At my company, we occasionally see a rash of slowdowns on our network. In some cases, the slowdowns occur after a patch or a new software package has been deployed. In other cases, there's no apparent reason for the slowdowns. When there's a rash of slowdowns, we run CpuLoadPercentage.vbs to find servers that are running "hot," as we call it. This script helps us find the CPU-hogging servers in a fraction of the time it would take to manually check all of them.

The script returns the value of the CPULoadPercentage property from Windows Management Instrumentation's (WMI's) Win32_Processor class. The CPULoadPercentage property value is an averaged percentage of the load on a particular CPU over a one-second time period. For each server, the script writes the CPULoadPercentage property value to a Microsoft Excel spreadsheet. To make sure a balanced sample is being obtained, the script checks the CPULoadPercentage property value three times in succession. Although the script is hard-coded to obtain three CPU load readings per server, you can easily modify it to obtain as few or as many readings as you'd like.

Figure 1 shows a simple example of three CPU load percentage readings. If you had multiple servers with multiple CPUs, you'd see a row for each server's CPU.

Figure 1: Sample results from CpuLoadPercentage.vbs

To get the three CPU load percentage readings, the script uses WMI's SWbemRefresher object, which you can use to obtain and refresh WMI data. Using the SWbemRefresher object's Refresh method is faster and less prone to errors than using the SWbemServices object's ExecQuery method. (For more information, see the Microsoft article "Don’t Panic: You Can Use Scripts to Monitor Performance".)

Creating a SWbemRefresher object is really quite simple. First, you begin by creating an instance of this object, after which you connect to the WMI namespace on the target computer, as callout A in Listing 1 shows.

Listing 1: Code That Demonstrates How to Use the SWbemRefresher Object

Then, you use the SWbemRefresher object's AddEnum method. To call this method, you need to specify the target computer (in this case, a remote server) and the target class (in this case, Win32_Processor). The ObjectSet property at the end tells the AddEnum method to return a collection of WMI objects.

Next, you call the SWbemRefresher object's Refresh method, which callout B shows. Note that, for some unknown reason, the very first time the Refresh method is called, it won't return any items to the collection. This first instance of the refresh call is referred to as priming.

Finally, the code at callout C steps through the collection and reports the CPU load percentage readings. In this code, DeviceID refers to specific CPUs on the server. If you have four CPUs, for instance, you'll see readings for CPU0 through CPU3.

Note that you won't find Listing 1's code in CpuLoadPercentage.vbs. Listing 1 is meant only to show you how use the SWbemRefresher object. To obtain the actual script, you can click the Download the Code Here button at the top of the page.

CpuLoadPercentage.vbs works on Windows Server 2008, Windows Server 2003, Windows Vista, and Windows XP machines. Before you use CpuLoadPercentage.vbs, though, you need to specify the computers for which you want to collect CPU load percentage readings. In the code

compArray = array("pc1","Server1", "Server2","trex-pc")

replace the dummy names (i.e., pc1, Server1, Server2, and trex-pc) with your computers' names. You can specify any number of machines. Alternatively, you could modify the code to use an organizational unit (OU) or a file to provide the list of computers.

If you want to change the number of CPU load percentage readings taken, simply change the value of 3 to the desired number in the line

NumberOfSamples = 3

I hope you find this script useful. It helps us spot those servers that need attention a lot faster than checking them all manually.