PowerShell Problem Solver: Process CPU Utilization

The last few PowerShell Problem Solver articles have involved getting processor load or utilization information with WMI and PowerShell. If you’re just jumping in with us, you should get caught up because I am going to build on what’s been outlined in previous articles in this series. The original question consisted of two different parts, where the first part was to get average processor load values. The second part looks to find the top five processes that are consuming the most processor time. Let’s look at this task. Each method I’ll demonstrate expresses processor time in a slightly different manner and they may not indicate which processes are consuming the most CPU time at the time you are querying.
Processor Load Article Series: 

Using PowerShell’s Get-Process Cmdlet

The Get-Process cmdlet is easy enough to use and the results include a CPU property. You can use common cmdlets to sort and select the top five processes.

Getting top five processes by CPU locally (Image Credit: Jeff Hicks)
Getting top five processes by CPU locally (Image Credit: Jeff Hicks)
I ran this command locally. The CPU property is actually a calculated property that PowerShell brings to the party. If you research the System.Diagnostics.Process class, you won't see CPU listed. The CPU property is defined as the TotalSeconds property of the TotalProcessTime property.
Viewing the CPU definition (Image Credit: Jeff Hicks)
Viewing the CPU definition (Image Credit: Jeff Hicks)
If you prefer, you can select this property directly.
Selecting by TotalProcessorTime (Image Credit: Jeff Hicks)
Selecting by TotalProcessorTime (Image Credit: Jeff Hicks)
Some processes are protected, which is why you'll see an error. I should also point out that this value indicates a historical figure and is not representative of what might be using the CPU right now. But let's carry on and query some remote computers.
Querying a remote computer (Image Credit: Jeff Hicks)
Querying a remote computer (Image Credit: Jeff Hicks)
There is no value for CPU which means TotalProcessorTime probably is empty as well. It turns out that you cannot get this value through a remote query. You have to run Get-Process locally. This means we need to use PowerShell remoting.
Querying processes via a remoting connection (Image Credit: Jeff Hicks)
Querying processes via a remoting connection (Image Credit: Jeff Hicks)
This actually works to our advantage when we want to query multiple computers.
Get top processes remotely for a group of servers (Image Credit: Jeff Hicks)
Get top processes remotely for a group of servers (Image Credit: Jeff Hicks)
But what if that isn't the CPU value you were hoping for?

Using WMI

Another option is to use WMI. Although there is a Win32_Process class, it doesn't contain any processor related properties. There are WMI performance classes, specifically Win32_PerfFormattedData_PerfProc_Process and Win32_PerfRawData_PerfProc_Process. These classes have a property called PercentProcessorTime, which is the percentage of time that all process threads took to complete. This is similar to what we saw with Get-Process. The raw data is in 100 nano second intervals. In my testing, the cooked values which you can see with the PerfFormattedData version always returns 0, so I'll use the raw data.
Get-WmiObject Win32_PerfRawData_PerfProc_Process -filter "Name  '_Total' and Name 'Idle'" -computername chi-dc04 |
Sort PercentProcessorTime -descending |
Select -first 5 Name,PercentProcessorTime,IDProcess,PSComputername | format-table –auto

Getting raw formatted performance data (Image Credit: Jeff Hicks)
Getting raw formatted performance data (Image Credit: Jeff Hicks)

Note that I am filtering with WMI and not using Where-Object. If you need to filter in PowerShell, filter as early in your expression as you can.
Again, for performance reasons, using remoting is helpful when querying multiple computers.

Querying raw performance data remotely (Image Credit: Jeff Hicks)
Querying raw performance data remotely (Image Credit: Jeff Hicks)
If you prefer to format the percent value yourself you can try something like this:
​

As you have probably realized if you have made it this far, this is not beginner stuff. I still want to show you how to use performance counters to get process information but that is going to be equally complex, so I will save that for the next article.