I\'m trying to write a PowerShell script to monitor % CPU utilization of a SQL Server process. I\'d like to record snapshots of this number every day so we can monitor it over t
Your hypothesis is almost correct. A single thread (and a process will always have at least one thread) can have at most 100% for PercentProcessorTime
but:
Hence here (Intel i7 CPU with hyperthreading on) I have 8 logical cores, and the top 20 threads (filtering out totals) shows (with a little tidying up to make it readable):
PS > gwmi Win32_PerfFormattedData_PerfProc_Thread | ?{$_.Name -notmatch '_Total'} | sort PercentProcessorTime -desc | select -first 20 | ft -auto Name,IDProcess,IDThread,PercentProcessorTime Name IDProcess IDThread PercentProcessorTime ---- --------- -------- -------------------- Idle/6 0 0 100 Idle/3 0 0 100 Idle/5 0 0 100 Idle/1 0 0 100 Idle/7 0 0 96 Idle/4 0 0 96 Idle/0 0 0 86 Idle/2 0 0 68 WmiPrvSE/7#1 7420 6548 43 dwm/4 2260 6776 7 mstsc/2#1 3444 2416 3 powershell/7#2 6352 6552 0 conhost/0#2 6360 6368 0 powershell/5#2 6352 6416 0 powershell/6#2 6352 6420 0 iexplore/7#1 4560 3300 0 Foxit Reader/1 736 5304 0 Foxit Reader/2 736 6252 0 conhost/1#2 6360 1508 0 Foxit Reader/0 736 6164 0
all of which should add up to something like 800 for the last column.
But note this is all rounded to integers. Compare with the CPU column of Process Explorer (which doesn't round when View | Show Fractional CPU is selected) over a few processes. Note, much like win32_PerfFormattedData_PerfProc_Process
the percentage value is normalised for the core count (and this is only part of the display):
A lot of processes are using a few hundreds of thousands of cycles, but not enough to round up to a single percent.
Everything I've learned about WMI and performance counters over the last couple of days.
WMI stands for Windows Management Instrumentation. WMI is a collection of classes registered with the WMI system and the Windows COM subsystem. These classes are known as providers and have any number of public properties that return dynamic data when queried.
Windows comes pre-installed with a large number of WMI providers that give you information about the Windows environment. For this question we are concerned with the Win32_PerfRawData* providers and the two wrappers that build off of it.
If you query any Win32_PerfRawData* provider directly you'll notice the numbers it returns are scary looking. That's because these providers give the raw data you can use to calculate whatever you want.
To make it easier to work with the Win32_PerfRawData* providers Microsoft has provided two wrappers that return nicer answers when queried, PerfMon and Win32_PerfFormattedData* providers.
Ok, so how do we get a process's % CPU utilization? We have three options:
We will see that there is a bug with option 1 so that it doesn't work in all cases even though this is the answer usually given on the internet.
If you want to get this value from Win32_PerfFormattedData_PerfProc_Process you can use the query mentioned in the question. This will give you the sum of the PercentProcessorTime value for all of this process's threads. The problem is that this sum can be >100 if there is more than 1 core but this property maxes out at 100. So, as long as the sum of all this process's threads is less than 100 you can get your answer by dividing the process's PercentProcessorTime property by the core count of the machine.
If you want to get this value from PerfMon in PowerShell you can use Get-Counter "\Process(SqlServr)\% Processor Time"
. This will return a number between 0 - (CoreCount * 100).
If you want to calculate this value for yourself the PercentProcessorTime property on the Win32_PerfRawData_PerfProc_Process provider returns the CPU time this process has used. So, you'll need to take two snapshots we'll call them s1 and s2. We'll then do (s2.PercentProcessorTime - s1.PercentProcessorTime) / (s2.TimeStamp_Sys100NS - s1.TimeStamp_Sys100NS).
And that is the final word. Hope it helps you.
Have you tryed Get-Counter
?
PS PS:\> Get-Counter "\Processus(iexplor*)\% temps processeur"
Timestamp CounterSamples
--------- --------------
17/07/2012 22:39:25 \\jpbhpp2\processus(iexplore#8)\% temps processeur :
1,5568026751287
\\jpbhpp2\processus(iexplore#7)\% temps processeur :
4,6704080253861
\\jpbhpp2\processus(iexplore#6)\% temps processeur :
0
\\jpbhpp2\processus(iexplore#5)\% temps processeur :
4,6704080253861
\\jpbhpp2\processus(iexplore#4)\% temps processeur :
0
\\jpbhpp2\processus(iexplore#3)\% temps processeur :
0
\\jpbhpp2\processus(iexplore#2)\% temps processeur :
0
\\jpbhpp2\processus(iexplore#1)\% temps processeur :
1,5568026751287
\\jpbhpp2\processus(iexplore)\% temps processeur :
0
Be careful it depend on you locale test :
PS PS:\> Get-Counter -ListSet * | where {$_.CounterSetName -contains "processus"}