Tag Archives: CPU

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)

Throttle PowerShell scripts to not kill CPU or RAM

Having fun deploying gobs of parallel processes when suddenly things start to slow as CPU and RAM are getting clobbered.  I came up with a way to help scripts be a little more polite to clear up the logjam.  Look for the top of loops or iterative processes to inject checking utilization before proceeding.  If thresholds are exceeded, then the script can pause a bit and check back to see if thresholds came down.  Essentially, it’s a call to a function to check utilization and a small loop to hang out in until utilization comes down.   I have CPU and RAM threshold dialed in at 80%.  One can change to suit.

The function:

function highCpuRam {
 $highCpuRam = $false
 $cpuUsed = [int](gwmi win32_processor).LoadPercentage
 $memUsed = [int]((((gwmi win32_OperatingSystem).FreePhysicalMemory) / ((gwmi win32_OperatingSystem).TotalVisibleMemorySize)) * 100)
 if ($cpuUsed -gt 80) {$highCpuRam = $true}
 if ($memUsed -gt 80) {$highCpuRam = $true}
 return $highCpuRam
}

The check:

 do {
 $busy = highCpuRam
 if ($busy) {"Throttling down. CPU/RAM busy."
 Start-Sleep -m 500}
 }
 while ($busy)