powershellcpu-usageperformancecounterw3wp

Fine-tuning Get-Counter script for quicker execution


Below is my script to get process utilization of individual w3wp.exe app pools, the problem is each iteration takes about 2 seconds there are about 25 app pools. Can you please help me to fine tune the below script for faster execution.

    gwmi win32_process -filter 'name="w3wp.exe"' | % {
    $name=$_.name
    $cmd = $pattern.Match($_.commandline).Groups[1].Value
    $procid = $_.ProcessId
    $tmp = (Get-Counter "\Process(*)\ID Process").CounterSamples | Where-Object       {$_.CookedValue -eq $procid} | select -expand Path
    $calc = [regex]::match($tmp,'\(([^\)]+)\)').Groups[1].Value
    $cooked = (Get-Counter "\Process($calc)\% Processor Time").CounterSamples | Where-Object {$_.InstanceName -notlike '_total'} | select -expand CookedValue
    $cpuper = [Math]::Round( ($cooked/2), 0)
    echo $cpuper
    }

Solution

  • It looks like Get-Counter has a minimum sample time of 1 second. Resulting in a minimum execution time of 1 second per call. Your best bet would be to get all the counters up front and then look for the counters you are interested in.

    This does something like what you were doing. It prints the process ID and % processor time in a table.

    $proc = 'w3wp'
    $samples = get-counter '\Process($proc*)\ID Process', '\Process($proc*)\% Processor Time' | select -expand countersamples 
    $samples | group { Split-Path $_.Path } | ft @{ N='ID'; E={$_.Group[0].CookedValue} }, @{ N='% Processor'; E={[Math]::Round($_.Group[1].CookedValue/2, 0)} }