KrishnaR
KrishnaR

Reputation: 420

Top 5 Processes with CPU % and Process ID using Powershell

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%

Upvotes: 0

Views: 1087

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174445

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
  }

Upvotes: 1

Related Questions