Monitoring Performance Data

Using WMI, you can access system counter data programmatically from objects in the performance libraries. This is the same performance data that appears in the System Monitor in the Perfmon utility. Use the preinstalled performance counter classes to obtain performance data in scripts or C++ applications.

The following sections are discussed in this topic:

WMI Performance Classes

As an example, the "NetworkInterface" object, in System Monitor, is represented in WMI by the Win32_PerfRawData_Tcpip_NetworkInterface class for raw data and the Win32_PerfFormattedData_Tcpip_NetworkInterface class for precalculated, or formatted data. Classes derived from Win32_PerfRawData and from Win32_PerfFormattedData must be used with a refresher object. On raw data classes, your C++ application or script must perform calculations to obtain the same output as Perfmon.exe. Formatted data classes supply precalculated data. For more information about obtaining data in C++ applications, see Accessing Performance Data in C++. For scripting, see Accessing Performance Data in Script and Refreshing WMI Data in Scripts.

The following VBScript code example uses Win32_PerfFormattedData_PerfProc_Process to obtain performance data for the Idle process. The script displays the same data that appears in Perfmon for the % Processor Time counter of the Process object. The call to SWbemObjectEx.Refresh_ performs the refresh operation. Be aware that the data must be refreshed, at least once, to obtain a baseline.

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" _
    & strComputer & "\root\cimv2")
set PerfProcess = objWMIService.Get(_
    "Win32_PerfFormattedData_PerfProc_Process.Name='Idle'")

While (True)
    PerfProcess.Refresh_     
    Wscript.Echo PerfProcess.PercentProcessorTime
    Wscript.Sleep 1000
Wend

Performance counter classes can also provide statistical data. For more information, see Obtaining Statistical Performance Data.

Performance Data Providers

WMI has preinstalled providers that monitor system performance on both the local system and remotely. The WmiPerfClass provider creates the classes derived from Win32_PerfRawData and from Win32_PerfFormattedData. The WmiPerfInst provider supplies data dynamically to both raw and formatted classes.

Using Formatted Performance Data Classes

The following VBScript code example obtains performance data about memory, disk partitions, and server work queues. The script then determines if the values are within an acceptable range.

The script uses the following WMI provider objects and scripting objects:

Set objCimv2 = GetObject("winmgmts:root\cimv2")
Set objRefresher = CreateObject("WbemScripting.SWbemRefresher")

' Add items to the SWbemRefresher
' Without the SWbemRefreshableItem.ObjectSet call,
' the script will fail
Set objMemory = objRefresher.AddEnum _
    (objCimv2, _ 
    "Win32_PerfFormattedData_PerfOS_Memory").ObjectSet
Set objDiskQueue = objRefresher.AddEnum _
    (objCimv2, _
    "Win32_PerfFormattedData_PerfDisk_LogicalDisk").ObjectSet
Set objQueueLength = objRefresher.AddEnum _
    (objCimv2, _
    "Win32_PerfFormattedData_PerfNet_ServerWorkQueues").ObjectSet

' Initial refresh needed to get baseline values
objRefresher.Refresh
intTotalHealth = 0
' Do three refreshes to get data
For i = 1 to 3
    WScript.Echo "Refresh " & i
    For each intAvailableBytes in objMemory
        WScript.Echo "Available megabytes of memory: " _
            & intAvailableBytes.AvailableMBytes
        If intAvailableBytes.AvailableMBytes < 4 Then
            intTotalHealth = intTotalHealth + 1
        End If
    Next
    For each intDiskQueue in objDiskQueue
        WScript.Echo "Current disk queue length " & "Name: " _
            & intDiskQueue.Name & ":" _
            & intDiskQueue.CurrentDiskQueueLength
        If intDiskQueue.CurrentDiskQueueLength > 2 Then
            intTotalHealth = intTotalHealth + 1
        End If
    Next
    For each intServerQueueLength in objQueueLength
        WScript.Echo "Server work queue length: " _
            & intServerQueueLength.QueueLength
        If intServerQueueLength.QueueLength > 4 Then
            intTotalHealth = intTotalHealth + 1                       
        End If
    Wscript.Echo "  "
    Next
    If intTotalHealth > 0 Then
        Wscript.Echo "Unhealthy."
    Else
        Wscript.Echo "Healthy."
    End If
    intTotalHealth = 0
    Wscript.Sleep 5000
' Refresh data for all objects in the collection
    objRefresher.Refresh
Next

Using Raw Performance Data Classes

The following VBScript code example obtains raw, current percent processor time on the local computer and converts it to a percentage. The example shows you how to obtain raw performance data from the PercentProcessorTime property of the Win32_PerfRawData_PerfOS_Processor class.

To calculate the percent processor time value, you must locate the formula. Look up the value in the CounterType qualifier for the PercentProcessorTime property in the CounterType Qualifier table to get the constant name. Locate the constant name in Counter Types to obtain the formula.

Set objService = GetObject( _
    "Winmgmts:{impersonationlevel=impersonate}!\Root\Cimv2")

For i = 1 to 8
    Set objInstance1 = objService.Get( _
        "Win32_PerfRawData_PerfOS_Processor.Name='_Total'")
    N1 = objInstance1.PercentProcessorTime
    D1 = objInstance1.TimeStamp_Sys100NS

'Sleep for two seconds = 2000 ms
    WScript.Sleep(2000)

    Set perf_instance2 = objService.Get( _
        "Win32_PerfRawData_PerfOS_Processor.Name='_Total'")
    N2 = perf_instance2.PercentProcessorTime
    D2 = perf_instance2.TimeStamp_Sys100NS
' Look up the CounterType qualifier for the PercentProcessorTime 
' and obtain the formula to calculate the meaningful data. 
' CounterType - PERF_100NSEC_TIMER_INV
' Formula - (1- ((N2 - N1) / (D2 - D1))) x 100

    PercentProcessorTime = (1 - ((N2 - N1)/(D2-D1)))*100
    WScript.Echo "% Processor Time=" , Round(PercentProcessorTime,2)
Next

Using WMI