PowerShell Genie

Rank processes by total CPU time

Script 2 min read Windows PowerShell 5.1 and PowerShell 7

Documentation: Microsoft Learn

Get-Process emits one process object per running executable, Sort-Object orders them by the CPU property in descending order, and -First 15 trims the tail.

The script

1PS> Get-Process | Sort-Object CPU -Descending | Select-Object -First 15 Name,Id,CPU

Script reader

Inspect before you run

Inspection only

Inspect the script below. It does not run in this browser.

Inspection only — no command has run.

    Show reference output
    1 Name Id CPU
    2 ------- ----- ------
    3 MsMpEng 2600 950
    4 chrome 9184 842.31
    5 pwsh 11268 18.27
    6 spoolsv 4400 1.4
    7 notepad 3200 0.4
    See the objects move

    Inspect this authored example with fictional data in the bounded browser model. The numbered stages show how its objects change.

    Get-Process | Sort-Object CPU -Descending | Select-Object -First 15 Name,Id,CPU
    1. Stage 1Get-ProcessPositional values or no named parameters
    2. Stage 2Sort-Object-Descending
    3. Stage 3Select-Object-First

      How it works

      Get-Process emits one process object per running executable, Sort-Object orders them by the CPU property in descending order, and -First 15 trims the tail. Worth knowing what CPU means here: it is cumulative processor seconds consumed since the process started, so the column is a lifetime total rather than an instantaneous percentage.

      Adapting it

      For a rate instead of a total, capture CPU twice a few seconds apart and subtract the two samples. The alternative is Get-Counter against the Process object's % Processor Time counter, which reports the interval directly.

      If the result is unexpected

      The top entries are long-running system processes that are visibly idle, while the process actually burning the CPU sits far down the list or shows a blank value.

      The CPU property is total processor time in seconds since the process started, so uptime dominates the ranking. Something launched minutes ago cannot accumulate enough to compete with a process that has been up for weeks. Processes owned by other accounts return no CPU figure to an unelevated session, leaving them sorted as nulls.

      1. Reopen the console elevated, rerun, and check whether previously blank CPU values are now populated.
      2. Take two samples a few seconds apart and compare the figure per PID to get a rate rather than a total.
      3. Cross-check the suspect with Get-Counter on its % Processor Time counter.
      4. Divide CPU by the process lifetime derived from StartTime to normalize for uptime.
      5. Look up ParentProcessId through Win32_Process for anything unfamiliar near the top.

      Validate the result

      Two samples taken seconds apart show the suspect gaining CPU seconds while the idle system processes stay flat.

      Keep the check reliable

      Build the sampling difference into the script rather than sorting on the raw lifetime total, so the output answers what is busy right now.

      Primary documentation

      Select-Object reference · Sort-Object reference · Get-Process reference

      Continue
      Genie guideRank processes by total CPU time

      Get-Process emits one process object per running executable, Sort-Object orders them by the CPU property in descending order, and -First 15 trims the tail.