A couple of weeks ago, a colleague of mine asked me how I would determine a process’ CPU utilization as a percentage of total CPU time. I came up with this PowerShell code, but it’s not quite complete yet, because it doesn’t dynamically determine the number of cores that a system has.
During the investigation of this problem, I came across a few key learnings:
- The system’s last boot-up time must be converted from WMI DateTime format to a .NET System.DateTime struct so that one can be properly subtracted from the other using the System.DateTime’s subtraction operator overload
- Retrieving the number of cores from a system depends on the operating system. For XP/2003, you would use Win32_ComputerSystem.NumberOfProcessors, but on Vista / 7 / 2008 / 2008 R2 you would use the Win32_ComputerSystem.NumberOfLogicalProcessors property. This is important in calculating total [virtual] system uptime. It’s simply <RealTime> * <NumberOfCores> as best I can tell
- If a process is closed and restarted, you will not get an accurate percentage … perhaps you could use the CreationDate property of the Win32_Process WMI class to determine how long a process has been running, versus total system uptime
The PowerShell code below retrieves the percentage of CPU time that the System Idle Process has consumed on a dual-core (or single core, hyper-threaded) system.
Please note that modifications are required for other hardware configurations; I have not yet had a chance to revise the code appropriately, but I have addressed it above.
clear-host $proc = Get-WmiObject -Query "select * from Win32_Process where name = 'System Idle Process'" $proccputime = [TimeSpan]::FromSeconds(($proc.UserModeTime + $proc.KernelModeTime) / 10000000) #virtual CPU time, not real Write-Host "Process seconds: $($proccputime.TotalSeconds)" $virtuptime = [TimeSpan]([DateTime]::Now - [System.Management.ManagementDateTimeconverter]::ToDateTime((Get-WmiObject Win32_OperatingSystem).LastBootUpTime)) # This next line assumes a 2nd core by adding the TimeSpan to itself $virtuptime += $virtuptime Write-Host "Total system uptime (seconds): $($virtuptime.TotalSeconds)" $percentage = ($proccputime.TotalSeconds / $virtuptime.TotalSeconds) * 100 Write-Host "Process $($proc.Name) has used $percentage% of CPU time"