Get CPU Usage Using PowerShell

So I’m writing a script to do a process dump of IIS CPU utilization goes to 100% and an IIS Worker Process of an app pool is to blame. I’ve done all kinds of searches and it seems many have bits and pieces of the solution, but not the entire thing and in a clean little package.

What we really want is to be able to get all the data that Task Manager produces on on the Process tab, but do it in PowerShell so we can parse the results and act on it.

Here’s the PowerShell script to continuously display the overall percent usage of CPU with a break out of the processes that are actually consuming CPU. I wanted a clean list, so I filtered out all the 0% processes.

Usage:

-Loop switch to continuously loop

-ComputerName to sample remote machine. No parameter assumes localhost.

Param(
    [Parameter(Mandatory=$false)][String]$ComputerName = "localhost",
    [Parameter(Mandatory=$false)][Switch]$Loop
)
function GetTotalCPU {
   $cpu = Get-Counter -ComputerName $ComputerName -Counter "\processor(_total)\% processor time"
   $cpu = [math]::Round($cpu.CounterSamples.CookedValue) 
   return $cpu
}
function GetRawProcessData {
    $Procs = (Get-Counter -ComputerName $ComputerName -Counter "\process(*)\% processor time" -ErrorAction SilentlyContinue).CounterSamples | Where-Object { $_.CookedValue -ne 0}
    $idle = ($Procs | Where-Object {$_.InstanceName -eq "idle"}).CookedValue
    $total = ($Procs | Where-Object {$_.InstanceName -eq "_total"}).CookedValue
    $Procs | ForEach-Object {
        $_.CookedValue = [math]::Round($_.CookedValue/$total*100,1)
        $_.InstanceName = $_.Path.Substring($_.Path.indexof("(")+1)
        $_.InstanceName = $_.InstanceName.Substring(0,$_.InstanceName.indexof(")"))
    }
    return $Procs
}
function GetRefinedProcessData ($Procs) {
    $procsList = @()
    $idProcess = (Get-Counter -ComputerName $ComputerName -Counter "\process(*)\ID Process" -ErrorAction SilentlyContinue).CounterSamples
    foreach ($Proc in $Procs) {
        $procName = $Proc.InstanceName
        $procPID = $idProcess | ? {$_.Path -match $procName } | Select-Object CookedValue
        $procPID = $procPID.CookedValue
        $procCPU = $Proc.CookedValue
        if ($procName -ne "_total") {
            $procsList += New-Object PSObject -Property @{Name = $procName; PID = $procPID; CPU = $procCPU}
        }
    }
    return $procsList
}
do {
    $cpu = GetTotalCPU
    $Procs = GetRawProcessData
    $ProcsList = GetRefinedProcessData $Procs
    clear
    "{0} CPU: {1}%" -f $ComputerName, $cpu
    $ProcsList | Sort-Object CPU -Descending | FT Name, PID, @{Label="CPU"; Expression={"{0}%" -f $_.CPU}}
}
while ($Loop)