Zabbix per process monitoring using Powershell


Hello folks,
Zabbix per process monitoring using PowershellIn this article I will show you how to use Windows Powershell to implement per process monitoring and calculate CPU % and memory usage of your Windows Servers. Data will be send to Zabbix monitoring System in Json format. Note that I’ve used Windows PowerShell Integrated Scripting Environment (ISE) which helps you a lot in developing Powershell scripts. I will just paste the code and explain each line so you can understand the logic behind my script. The script will contain two parts, one that populates Zabbix hosts with the desired items and the second one which will retrieve the values for these items:

# The keys parameter determines whether the script will populate items or retrieve values
param([Int32]$keys=0)

#Open Json statement
if ($keys -eq “1”)
{
write-host “{“
write-host ” `”data`”:[“
write-host
}

#Get the processes that run on the machine from a certain path
$colItems = Get-Process | Where-Object {$_.Path -like “D:\Servers\*” }

#$val hash table will be used to get the CPU counters at a single point in time
$val = @{}

# For each process contained in $colItems we will extract several parameters (process name, path and PID) which will be used to identify a particular service in the Zabbix monitoring system. We will replace a single ‘\’ character with ‘\\’ for process paths to be correctly displayed in Zabbix

foreach ($objItem in $colItems) {
  if ( $keys -eq “1”)
  {
 $line = ” { `”{#PROCESSNAME}`”:`”” + $objItem.ProcessName + “`” ,`”{#PROCESSPATH}`”:`”” + $objItem.Path + “`” ,`”{#PROCESSPID}`”:`”” + $objItem.Id + “`” },”
 $line = $line -replace ‘\\’,’\\’
 write-host $line
 }

  else
    {
#We will calculate a process CPU time in seconds at t0 by adding the user and kernel mode times. Values will be added in the $val hash table
     $procid = $objItem.Id
     $proc = gwmi win32_process | where-object {$_.handle -eq $procid}
     $proccputime0 = [TimeSpan]::FromSeconds(($proc.UserModeTime + $proc.KernelModeTime) / 10000000)
     $val.Add($objItem.Id,$proccputime0.TotalSeconds)
     }
}

#To be able to calculate CPU time in seconds at t1 we will have to pause the script for several seconds
 Start-sleep -s 3

#We will define the second hash table for storing values at t1
 $val1 = @{}
 $colItems1 = Get-Process | Where-Object {$_.Path -like “D:\Servers\*” }

 foreach ($objItem in $colItems1) 
 {
#We verify first if the process has not been closed since t0  and then calculate values at t1
   if ($val.ContainsKey($objItem.Id))
   {
     $procid = $objItem.Id
     $proc = gwmi win32_process | where-object {$_.handle -eq $procid}
     $proccputime3 = [TimeSpan]::FromSeconds(($proc.UserModeTime + $proc.KernelModeTime) / 10000000)
     $val1.Add($objItem.Id,$proccputime3.TotalSeconds)

#To be able to calculate the CPU% time we will need to get the number of logical processors on our
machine
$nrproc = (Get-WmiObject “Win32_ComputerSystem”).numberoflogicalprocessors

#Finally, we calculate the subtraction between each process t1 and t0 and we’ll divide it by the wait time and the number of logical processors to get the CPU% time
     $result = ($val1.get_item($objItem.Id) – $val.get_item($objItem.Id)) / 3 / $nrproc * 100
     $resultf = [System.Math]::Round($Result, 3)

#The CPU% values will then be sent to Zabbix
 $line = “- perprocess.CPU[`”” +$objItem.Path + “`”] ” + $resultf
     write-host $line
}

#The working set for each process is sent to Zabbix
 $ws = “- perprocess.WS[`”” +$objItem.Path + “`”] ” + $objItem.WorkingSet 
     write-host $ws

#Private memory for each process is sent to Zabbix
 $pm = “- perprocess.PM[`”” +$objItem.Path + “`”] ” + $objItem.PM
     write-host $pm
  }

# Close the JSON message
if ($keys -eq “1”)
{
write-host
write-host ” ]”
write-host “}”
write-host
}

On each machine, in the Zabbix client you will have to modify the zabbix_agentd config file and add the following lines. The first line will execute the script with $keys parameter set to 1 to add the items to Zabbix while the second one will send the items values:
UserParameter=perprocess.getkeys, powershell -NoProfile -ExecutionPolicy Bypass -file “C:\Program Files\Zabbix Agent\UserParameters\script\PerProcess.ps1” -keys 1
UserParameter=perprocess.getvalues, powershell -NoProfile -ExecutionPolicy Bypass -file “C:\Program Files\Zabbix Agent\UserParameters\script\PerProcess.ps1” -keys 0 | “C:\Program Files\Zabbix Agent\zabbix_sender.exe” -v -c “C:\Program Files\Zabbix Agent\zabbix_agentd.conf” -i –

Once you’ve configured the discovery rule in Zabbix and create the necessary items, you should have implemented per process monitoring successfully. That’s about it for this article folks, wish you all the best and have a great day!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s