Windows
banshee/windows-collection/windows/ssh/
processes
The processes of a Windows: their number, and the instances, memory and processor time of each process followed, by SSH and PowerShell
by banshee1 installation2 versions
// The processes of a Windows, by SSH: their total number, and for each process name followed
// ("lsass.exe", "sqlservr.exe") the number of its instances, their memory and their processor time.
// Runs one PowerShell command that only reads Win32_Process: Name, ProcessId, WorkingSetSize (in bytes),
// KernelModeTime and UserModeTime (in hundreds of nanoseconds since the process started). A process that
// ends during the reading is simply missing from the answer.
need('protocol:ssh');
per('process', 'Processes', array('only' => array('lsass.exe', 'services.exe')));
output('processes', 'number', array('label' => 'Number of processes'));
output('instances', 'number', array('label' => 'Number of instances', 'per' => 'process'));
output('memory', 'number', array('label' => 'Memory', 'unit' => 'MiB', 'per' => 'process'));
output('cpu', 'number', array('label' => 'Processor time, as a share of one processor', 'unit' => '%', 'per' => 'process'));
watch.missing('missing', 'Process missing', 'instances', array('critical' => array('lsass.exe', 'services.exe')));
watch.above('too-many', 'Too many processes', 'processes', array('enabled' => false));
watch.above('memory-high', 'Memory of a process', 'memory', array('enabled' => false));
watch.above('cpu-high', 'Processor of a process', 'cpu', array('warning' => 90, 'for' => '3 runs', 'enabled' => false));
// A process name may hold characters outside ASCII: the output is written in UTF-8, without the byte order
// mark that the default UTF-8 encoding of .NET would put first.
$read = ssh.run("powershell -NoProfile -NonInteractive -Command \""
. "[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding; "
. "ConvertTo-Json -Compress -InputObject @(Get-CimInstance Win32_Process"
. " | Select-Object Name, ProcessId, WorkingSetSize, KernelModeTime, UserModeTime)\"");
$answer = text.trim($read['output']);
if (list.count(text.match($answer, '^\[')) == 0) {
fail('misconfigured', 'PowerShell did not return the processes', $answer . $read['errors']);
}
// The instances of one name add up. Process 0, "System Idle Process", is not a process: its time is the
// idle time of the processors.
$processes = 0;
$count = array();
$memory = array();
$cpu = array();
foreach (json.read($answer) as $process) {
if ($process['ProcessId'] == 0) {
continue;
}
$name = $process['Name'];
$processes = $processes + 1;
$count[$name] = list.get($count, $name, 0) + 1;
$memory[$name] = list.get($memory, $name, 0) + $process['WorkingSetSize'];
$cpu[$name] = list.get($cpu, $name, 0) + $process['KernelModeTime'] + $process['UserModeTime'];
}
if ($processes == 0) {
fail('misconfigured', 'No process found in Win32_Process', $answer);
}
value('processes', $processes);
foreach ($count as $name => $instances) {
value('instances', $instances, $name);
value('memory', number.round($memory[$name] / 1048576, 1), $name);
// Ten million hundreds of nanoseconds a second are one processor: a hundred thousand are one percent.
// Nothing at the first run, nor when an instance has ended and the sum went back.
$rate = counter.rate('cpu', $cpu[$name], $name);
if ($rate != '') {
value('cpu', number.round($rate / 100000, 1), $name);
}
}