Windows Management Instrumentation (WMI) is a scalable, extensible management infrastructure included as part of Windows 2000 and later. It’s an implementation of Web-Based Enterprise Management (WBEM) and is based on the Common Information Model (CIM).

WMI includes a rich set of powerful classes that can be used for, among other things, performance monitoring of any Windows application that supports WMI.

To list the performance monitoring classes, the following command of Windows PowerShell code can be used:

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

NOTE: above script was processed on WinXP SP3.

Please note that some of the WMI class names include the word “PerfRawData” but others include the word “PerfFormattedData”. The reason is that these classes are derived from Win32_PerfRawData and from Win32_PerfFormattedData abstract classes (available only on Windows XP and later).

The difference between these two classes is that, for the most part, the raw data classes provide pure counters/values while the formatted data classes provide pre-calculated data, and therefore data based on the dynamic behavior of monitored objects over a sampling period.

The formatted data counters can be of various counter types depending on the calculation method and the nature of the value. Fortunately, they are based on a limited number of generic types. The most important generic types are the following:

● Average. These counters calculate the average of the last two measurements. For instance, the PERF_AVERAGE_TIMER counter type, which is derived from the generic Average, measures the average time it takes to complete a process or operation by using the formula ((N1 – N0) / F) / (D1 – D0), where the numerator (N) represents the number of ticks counted during the last sample interval, the variable F represents the number of ticks per second, and the denominator (D) represents the number of operations completed during the last sample interval. Thus, the formula calculates the average time it takes to process one operation (in seconds).

● Difference. These counters subtract the last measurement from the previous one and display the difference. A typical representative is PERF_COUNTER_COUNTER which calculates the average number of operations completed during each second of the sample interval by using the formula (N1- N0) / ( (D1-D0) / F), where the numerator (N) represents the number of operations performed during the last sample interval, the denominator (D) represents the number of ticks elapsed during the last sample interval, and F represents the number of ticks per second. Thus, the formula calculates how many operations, on average, were processed in one second.

● Percentage. These counters display calculated values as a percentage. A typical representative is PERF_COUNTER_TIMER which calculates the average time that a component was active as a percentage of the total sampling time by using the formula (N1 – N0) / (D1 – D0) * 100, where the denominator (D) represents the total elapsed time of the sample interval, and the numerator (N) represents the portion of the sample interval during which the monitored components were active.

● Rate. Similar to an average counter, these counters sample an increasing count of events over time. The count is divided by the change in time to display a rate of activity.

● Instantaneous. These counters display the most recent measurement. As an example, the PERF_COUNTER_RAWCOUNT shows the last observed value only.

There are hundreds of WMI performance classes available and it is naturally difficult to find just the one that is needed. Sure, you can use PowerShell code to find the desired class – for example, to find processor formatted classes, the following code could be used:

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

NOTE: above script was processed on WinXP SP3.

We already explained how the formatted data classes calculate values. The other common question concerns the correct way to get data from formatted classes.

Here is example VBScript code, using the Win32_PerfFormattedData_PerfProc_Process class, to obtain performance data for the System processes:

Set objWMIService = GetObject("WINMGMTS:\\.\ROOT\cimv2") Set PerfProcess = objWMIService.Get("Win32_PerfFormattedData_PerfProc_Process.Name='System'") While (True) PerfProcess.Refresh_ Wscript.Echo PerfProcess.PercentProcessorTime Wscript.Sleep 5000 ‘5 seconds sampling interval Wend

As explained before, formatted data counters, in general, work over a sampling interval.

The Refresh method grabs the current values of the Win32_PerfFormattedData_PerfProc_Process class at the beginning of the sampling interval. When we loop around the next time (after the sleep – which defines the sampling interval and allows Win32_PerfFormattedData_PerfProc_Process class time to perform necessary calculations according to the counter type), the Refresh method will again grab the current values and provide the calculation. In other words, it’s essentially issuing a new query each time, and therefore constantly grabbing the latest values.

Using formatted counters requires some amount of time for data collection and calculation. Besides this, they are only available starting from Windows XP and Windows Server 2003. In addition, sometimes, it is undesirable to have any latency, especially in cases where we have a lot of metrics that need to be monitored. So, taking into account that monitors in most cases periodically grab the current values, they can help matters by storing the current values and using them for calculation in the next cycle of probing. Note that in this case you don’t need to use formatted counters at all because the raw counter’s values are more than enough. If you have the measuring cycle duration and two values – previous and current – you can do any calculation simply, e.g. percentage, by the formula (Nc – Np) / D * 100, where Nc is the current value, Np – previous value and D – cycle duration.

Finally, don’t think that raw counters are “stupid” – they also provide some simple calculations, e.g. the Win32_PerfFormattedData_PerfProc_Process class contains IODataOperationsPerSec, PageFaultsPerSec, PercentProcessorTime, and other properties that are already pre-calculated.

Based on the foregoing, example code can look as follows:

Set oWMI = GetObject("WINMGMTS:\\.\ROOT\cimv2") While (True) Set Instance = oWMI.Get("Win32_PerfRawData_PerfProc_Process.Name=""System""") Wscript.Echo Instance.PercentProcessorTime ‘% System Time Wscript.Sleep 60000 'Wait for 1 min to get next value Wend

In this example, we get the raw value that is already given as a percentage, so no calculation is needed (the sleep for 1 minute defines the duration of monitor probing).

In case you want to use another dummy counter (e.g. ThreadCount, which is the number of threads currently active in this process) we use the approach described above to get a dynamic picture:

Set oWMI = GetObject("WINMGMTS:\\.\ROOT\cimv2") Set duration = 60 ‘cycle duration in seconds Set preValue = 0 Set curValue = 0 While (True) Set Instance = oWMI.Get("Win32_PerfRawData_PerfProc_Process.Name=""System""") Set curValue = Instance.ThreadCount Set dynValue = ( curValue - preValue) / duration Wscript.Echo dynValue Set preValue = curValue Wscript.Sleep duration*1000 'Wait for 1 min to get next value Wend

The Monitis WMI monitor implements the approach depicted above, using only the raw data classes, because the technique is simple, does not require sampling intervals and works on any version of Windows.