Hey, Scripting Guy! Question

Hey, Scripting Guy! I really like using the Microsoft Performance Monitor (PerfMon) tool to examine the various things in Windows Server, but I would like to have more control over the data that it retrieves. I am never sure what it is actually telling me, or how it makes its calculations. Does this make sense?

- SK

SpacerHey, Scripting Guy! Answer

Hi SK,

There are lots of performance monitoring WMI classes. These are all derived from the performance counters that you see when you open the PerfMon tool. The exact performance classes you will have installed on your computer depend on the software installed and the version of the operating system you are working with. To list the performance monitoring classes on your computer, you can use the following line of Windows PowerShell code:

Get-WmiObject -List | Where-Object { $_.name -match 'perf' }

The resulting list of WMI classes is impressive and is seen in the image following this paragraph. If you squint closely, you can see that some of the WMI class names include the word "PerfRawData” in the name of the class. You may also be able to see that some of the classes include the word "PerfFormattedData" in the name. You may want to refer to this article for some VBScript examples of using the performance classes.

Image of WMI performance classes on a Windows Vista computer

 

There are actually two kinds of WMI performance classes: raw counter classes and cooked counter classes. I am not making this up. Interestingly enough, when I was writing the Microsoft Press WMI book, Microsoft Windows Scripting with WMI: Self-Paced Learning Guide, one of my editors actually struck out the term "cooked counter" because she thought I was being cute. I mean me? Being cute? Luckily, my technical reviewer countered back that it was in fact a technical term and saved me the trouble of coming up with a cute response.

So what are the differences between raw counters and cooked counters? Well, the raw counters are simply that: raw numbers. No post processing or anything-raw instantaneous access to performance counters. The cooked counters, which are available on Windows XP and later, are supplied by the Formatted Performance Data Provider, which supplies calculated counter data. Often these counters will incorporate the concept of time into their values, and report things such as percentage of disk utilization-a value that is meaningless without the concept of time built into it.

In general, I prefer my performance counters cooked. We can modify our Windows PowerShell query to return only the cooked counters:

Get-WmiObject -List | Where-Object { $_.name -match 'perf' -AND $_.name -notmatch 'raw'}

You can see the cooked counters here:

Image of cooked counters

 

The WMI performance monitor classes can be directly related to the counters that are available in the PerfMon tool. As seen in the next image, a number of performance counters are available for the processor object. One thing you should keep in mind is that the name of the WMI class will generally bear some relationship to the category seen in the left side of the following image. The properties correspond to the counters you see added on the right side of the picture. The instance of the WMI class corresponds to the "Instances of Selected Object" shown in the bottom left side of the figure.

Image of performance counters available for the processor object

 

With hundreds of WMI performance classes available to you, how can you find the class you need? One way is to use a modified WMI query such as the one we used to list the performance classes in the first place. To find our processor classes, we could use the following query:

Get-WmiObject -List | 
Where-Object { $_.name -match 'perf' -AND $_.name -notmatch 'raw' -AND $_.name -match 'processor'}

This is one logical line of code. The pipeline character is an easy place to break the code for readability purposes. When Windows PowerShell sees the pipeline character at the end of the line, it recognizes that it is an incomplete command and will automatically look to the next line.

You will notice that all we did was add another -AND operator and say the name needs to match the string “processor”. When we run this, we are treated with the only WMI performance class that is a cooked counter dealing with processors:

Win32_PerfFormattedData_PerfOS_Processor

We can use the WMI class directly by feeding it to the -class property of the Get-WmiObject cmdlet. This is seen here:

Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_Processor

This is quick and easy. You will always have at least two instances returned for this query: one instance for the processor and one instance that is called _Total. If you only have a single-core, single-processor machine, _Total is exactly the same as processor 0. If you have multiple cores and multiple processors, you will have multiple instances to work with and will always have one more instance than the number of cores and processors. You can choose a particular instance to monitor (which is an excellent idea if you have set processor affinity for a particular process or application); you can monitor each instance individually; or you can monitor the _Total processor utilization. For in-depth troubleshooting, it is better to examine each instance of the processor object. However, from a general monitoring standpoint, looking at _Total is probably sufficient.

One easy way to obtain a specific instance of the processor object is to pipeline the results of the WMI query to the Where-Object, as shown here:

Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_Processor | where-object { $_.name -eq '_Total'}

When the above line of code is run, here are the results:

__GENUS               : 2
__CLASS               : Win32_PerfFormattedData_PerfOS_Processor
__SUPERCLASS          : Win32_PerfFormattedData
__DYNASTY             : CIM_StatisticalInformation
__RELPATH             : Win32_PerfFormattedData_PerfOS_Processor.Name="_Total"
__PROPERTY_COUNT      : 24
__DERIVATION          : {Win32_PerfFormattedData, Win32_Perf, CIM_StatisticalInformation}
__SERVER              : OFFICE
__NAMESPACE           : root\cimv2
__PATH                : \\OFFICE\root\cimv2:Win32_PerfFormattedData_PerfOS_Processor.Name="_Total"
C1TransitionsPersec   : 0
C2TransitionsPersec   : 0
C3TransitionsPersec   : 0
Caption               :
Description           :
DPCRate               : 1
DPCsQueuedPersec      : 209
Frequency_Object      :
Frequency_PerfTime    :
Frequency_Sys100NS    :
InterruptsPersec      : 1279
Name                  : _Total
PercentC1Time         : 0
PercentC2Time         : 0
PercentC3Time         : 0
PercentDPCTime        : 0
PercentIdleTime       : 0
PercentInterruptTime  : 0
PercentPrivilegedTime : 4
PercentProcessorTime  : 4
PercentUserTime       : 0
Timestamp_Object      :
Timestamp_PerfTime    :
Timestamp_Sys100NS    :

One great thing about Windows PowerShell is that the properties of the object are automatically displayed without the need for a bunch of write-host (similar to wscript.echo in VBScript) statements for each property you wish to see. You will also notice there are a bunch of properties that begin with “__. These are all system properties from the WMI class, and while interesting, often are not needed in your display. An easy way to filter out this information is to use a range operator as shown here:

Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_Processor | 
where-object { $_.name -eq '_Total'} | 
Format-List -Property [a-z]*

The resulting display now is a bit cleaner, as shown here:

C1TransitionsPersec   : 0
C2TransitionsPersec   : 0
C3TransitionsPersec   : 0
Caption               :
Description           :
DPCRate               : 2
DPCsQueuedPersec      : 253
Frequency_Object      :
Frequency_PerfTime    :
Frequency_Sys100NS    :
InterruptsPersec      : 1317
Name                  : _Total
PercentC1Time         : 0
PercentC2Time         : 0
PercentC3Time         : 0
PercentDPCTime        : 0
PercentIdleTime       : 0
PercentInterruptTime  : 1
PercentPrivilegedTime : 6
PercentProcessorTime  : 6
PercentUserTime       : 0
Timestamp_Object      :
Timestamp_PerfTime    :
Timestamp_Sys100NS    :

The above list is good, but suppose you are not interested in all that information. Maybe, you are only interested in the Percent times, but not the PercentC1Time or those related values, or the PercentDPCTime value. Also you would like to get the InterruptsPerSecond but not anything else. You do not need to type all the property names for the Format-List cmdlet. You can instead use the range operator trick and the “*” wild card to reduce the amount of typing required. Ttake a look at this command:

Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_Processor | 
where-object { $_.name -eq '_Total'} | 
Format-List -Property percent[i-z]*, int*

Here is the output from the above command:

PercentIdleTime       : 0
PercentInterruptTime  : 1
PercentPrivilegedTime : 4
PercentProcessorTime  : 4
PercentUserTime       : 0
InterruptsPersec      : 1281

Perfect! This is exactly the information we were looking for. Tomorrow, we will go further into using the performance WMI classes. See you then.

Ed Wilson and Craig Liebendorfer, Scripting Guys