Home > Software design >  Top 5 Processes with CPU % and Process ID using Powershell
Top 5 Processes with CPU % and Process ID using Powershell

Time:03-31

I tried this script

Get-Counter -ErrorAction SilentlyContinue '\Process(*)\% Processor Time' | 
    Select -ExpandProperty countersamples | 
    ?{$_.instanceName -notmatch "^(idle|_total|system)$"} | 
    Sort -Descending cookedvalue | 
    Select -First 5 @{
        L='ProcessName';
        E={[regex]::matches($_.Path,'.*process\((.*)\)\\% processor.*').groups[1].value}
     },
     @{
         L='CPU';
         E={($_.Cookedvalue/100/$env:NUMBER_OF_PROCESSORS).toString('P')}
     },
     @{
         L='ProcessId';
         E={((Get-Counter "\Process([regex]::matches($_.Path,'.*process\((.*)\)\\% processor.*').groups[1].value)\ID Process" -ErrorAction SilentlyContinue).CounterSamples).Cookedvalue}
     }

I am able to get ProcessName and CPU % columns but not ProcessID

ProcessName  CPU   ProcessId
-----------  ---   ---------
firefox#4    0.58%
svchost#11   0.19%
firefox#6    0.19%
dwm          0.10%
svchost#39   0.10%

CodePudding user response:

Make sure you request both the % Processor Time and ID Process counter from each counter instance, then use Group-Object to group them together.

Worth noting is that you don't need regex to correlate the two, simply group on the first part of the counter path (\Process(notepad#3)). Regex is also not needed for extracting the process name, since each sample already has an InstanceName property with the corresponding process name.

Once you've correlated name process ID sample value, you can start sorting, and then finally format the CPU percentage:

Get-Counter '\Process(*)\ID Process','\Process(*)\% Processor Time' -ErrorAction SilentlyContinue |
  ForEach-Object {
    $_.CounterSamples |
      Where-Object InstanceName -NotMatch '^(?:idle|_total|system)$' |
      Group-Object {Split-Path $_.Path} |
      ForEach-Object {
        [pscustomobject]@{
          ProcessName = $_.Group[0].InstanceName
          ProcessId = $_.Group |? Path -like '*\ID Process' |% RawValue
          CPUCooked = $_.Group |? Path -like '*\% Processor Time' |% CookedValue
        }
      } |Sort-Object CPUCooked -Descending |
         Select-Object -First 5 -Property *,@{Name='CPUPercentage';Expression={'{0:P}' -f ($_.CPUCooked / 100 / $env:NUMBER_OF_PROCESSORS)}} -ExcludeProperty CPUCooked
  }
  • Related