Monitor highest CPU usage processes on Windows

Hello together,
I would like to monitor on a single host, which processes use most of the CPU.
Sometimes the server hangs up and we have to forcefully reboot it, becaus we can’t access it anymore.
Also I would like to be able to display how it was started (cmd parameters?)
I have found some scripts and fiddled around, but sadly I can’t get it working.

Greetings
Max

Currently, checkmk does not offer an out-of-the-box solution for this. But you are not alone with this wish.

https://ideas.checkmk.com/suggestions/558059/improve-ps-check-add-top-x-process-by-cpu-by-memory-option

Until Checkmk picks up this idea, this could be done with a local or mrpe check that lists the top 10 processes.

1 Like

Here is an example of how you could get the top 10 by cpu,mem on linux:

echo 'by cpu'; 
ps aux --sort -%cpu | head -10; 
echo 'by mem'; 
ps aux --sort -%mem | head -10

And here in the same format as the Linux Agent produces the ps_lnx section.

echo '<<<ps_by_cpu>>>'
ps ax -ww -o user:32,vsz,rss,cputime,etime,pid,command  --sort=-%cpu| tr -s ' ' | head -10
echo '<<<ps_by_mem>>>'
ps ax -ww -o user:32,vsz,rss,cputime,etime,pid,command --sort=-%mem | tr -s ' ' | head -10

And here as a small example nagios style check (execute as a mrpe check):

#!/bin/bash

threshold=10
state=0
ps_out=$(ps aux --sort -%cpu --no-headers | head -10)

while IFS=' ' read -r -a ps_row; do
    # Critical if greater than the threshold
    (( $(bc <<< "${ps_row[2]} > ${threshold}") )) && state=2
done <<< "$ps_out"
echo "$ps_out"
exit $state

1 Like

Thank you very much!
Sorry, my question was unclear.

I looked for a solution on Windows

and here as simple Powershell script:

$threshold = 10
$exitCode = 0
$ps_out = Get-Process | Sort-Object CPU -Descending | Select-Object -First 10

# Iterate through each process
foreach ($ps_row in $ps_out) {
    # Calculate the CPU usage percentage
    $cpuUsage = ($ps_row.CPU / (Get-WmiObject -Class Win32_Processor | Select-Object -ExpandProperty NumberOfLogicalProcessors)) * 100

    # Display the process information
    Write-Host "Process: $($ps_row.ProcessName) (PID: $($ps_row.Id)) CPU Usage: $cpuUsage%"

    # Check if the CPU usage is greater than 10%
    if ($cpuUsage -gt 10) {
        # Set the exit code to 2
        $exitCode = 2
    }
}

# Exit the script with the saved exit code
exit $exitCode
2 Likes

On my local machine I had to change
$cpuUsage = ($ps_row.CPU / (Get-WmiObject -Class Win32_Processor | Select-Object -ExpandProperty NumberOfLogicalProcessors)) * 100
into
$cpuUsage = ($ps_row.CPU / (Get-WmiObject -Class Win32_Processor | Select-Object -ExpandProperty NumberOfLogicalProcessors)) / 10
to get correct percentages.

Other than that, cool, thanks for the script! (-:

Thanks for the feedback on this. I didn’t test the code because it was more of a demo than a practical exercise, but I hope it was helpful anyway.

While question of OP is about cpu, your demo script can possibly be a nice starting point to convert into top X processes using most memory.
Or maybe keep CPU usage and add memory.

I have a few endpoint clients that sometimes are crashing due to high memory usage when they don’t log off after office hours. I suspect some sites cause a memory leak in Chrome.

So yeah, it might be useful for that.

$ps_out = Get-Process | Sort-Object WS -Descending | Select-Object -First 10

# Iterate through each process
foreach ($ps_row in $ps_out) {
    # Calculate the memory usage percentage
    $memUsage = ($ps_row.WorkingSet / (Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty TotalPhysicalMemory)) * 100

I have not checked if the calculation is correct, but you can see where it is going to go :wink:

1 Like

Hi, how did you get the correct percentages for high CPU usage? When I run the script with your section the results just don’t add up to what I’m seeing in task manager, see example:

image
image

I find it tricky to compare directly to taskmanager or process explorer since they show more processes, group them and / or have a refresh rate going on so the top processes jump all over the place from one moment to the next. So the moment in time for ps is never the same as the gui tools. But in general they feel to be similar.

Reading back what I wrote back then, and looking at current script, looks I goofed up on Sep 12: / 10 should have been / 100, so:
$cpuUsage = ($ps_row.CPU / (Get-WmiObject -Class Win32_Processor | Select-Object -ExpandProperty NumberOfLogicalProcessors)) / 100