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
v2Latest
Published on October 28, 2026. One naming convention across collections; documentation completed.
// 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);
}
}