Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I monitor the activity of a process to see if anyone is using it?

-- AJ

SpacerHey, Scripting Guy! AnswerScript Center

Hey, AJ. You know, this is one time when writing the script is actually the easy part of the answer. Although there are a couple different ways to do this, we opted to periodically check the cumulative amount of processor time used by an application. If the amount of processor time never changes, that likely means that no one is using the application.

But if that’s the easy part of the answer then what’s the hard part? Well, in this case the hard part involves deciding what counts (or doesn’t count) as “not being used.” In our sample script, we’re going to measure the cumulative processor use 11 times, pausing 30 seconds between each measurement. When the script finishes we’ll have a set of measurements spanning 5 minutes; our assumption is that if the processor time hasn’t changed in the last 5 minutes then that means no one is using the application. That works fine for our sample script, but might not work as well in real life. After all, suppose your user is talking on the phone, taking a coffee break, or sitting in a meeting; in that case, it wouldn’t be too surprising that an application would sit for 5 minutes (or more) without being used and without using up additional processor time. You’ll need to decide for yourself what’s reasonable for your purposes.

We should also add that there’s no reason why we have to take measurements every 30 seconds; we did that primarily so you could view the cumulative processor time on screen, and so that you’d know for sure that the script was still working. We could just as easily take one measurement, wait five minutes, and then take a second measurement. Five minutes might not seem that long, but it’s practically an eternity when you’re waiting to see whether a script is actually doing anything or not. Again, you’ll need to decide what’s reasonable and what isn’t.

Yes, we know: that’s all well and good, Scripting Guys, but where is this script you keep talking about? Well, right here:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

For i = 1 to 11

    Set colProcesses = objWMIService.ExecQuery _
        ("Select * from Win32_Process Where Name = 'Notepad.exe'")

    For Each objProcess in colProcesses
        sngProcessTime = (CSng(objProcess.KernelModeTime) + _
                CSng(objProcess.UserModeTime)) / 10000000
        Wscript.Echo objProcess.Name, sngProcessTime
    Next

    Wscript.Sleep 30000
Next

Note. This particular script monitors the process Notepad.exe, and assumes that there’s only one instance of Notepad running on your computer; if there are (or could be) multiple instances of Notepad then you should monitor by process ID rather than process name.

The script begins by connecting to the WMI service on the local computer. We then set up a For Next loop to run 11 times, one for each measurement we plan to take. Inside the loop we use this line of code to return a collection of all the processes named Notepad.exe that are running on the computer:

Set colProcesses = objWMIService.ExecQuery _
    ("Select * from Win32_Process Where Name = 'Notepad.exe'")

Important. Make sure this line of code is included inside your For Next loop; that’s the only way to ensure that up-to-date process information is retrieved each time your run through the loop.

As it turns out, WMI tracks processor time using two different properties: KernelModeTime and UserModeTime. To track total processor time we need to add the values of these two properties. In addition, WMI tracks processor time in 100-nanosecond units. Because most of us don’t think in terms of 100-nanosecond units (hey, we did say most of us) we also divide the sum of these two properties by 10,000,000, something that will convert 100-nanosecond units to seconds. Sure, it sounds complicated, but it takes only one line of code:

sngProcessTime = (CSng(objProcess.KernelModeTime) + _
    CSng(objProcess.UserModeTime)) / 10000000

If you’d rather calculate processor time in minutes, then divide the sum by 600,000,000 instead (10000000 x 60 seconds per minute).

We echo the process name and total processor time, and then use the Sleep method to pause the script for 30 seconds (30,000 milliseconds). When 30 seconds are up, we loop around and repeat the whole process. After 11 such loops, the script terminates.

When we run the script we get back information similar to this:

notepad.exe 0.1602304
notepad.exe 0.801152
notepad.exe 0.801152
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664

As you can see, there was a very brief “flurry” of activity when we first began monitoring Notepad; for the last 8 measurements, however, Notepad hasn’t used any processor time at all. (And, overall, the application has still used less than a second of processor time.) Does that mean that no one is using Notepad? Well, like we said, that’s up to you to decide. After all, we work for Microsoft, and no Microsoft employee would ever presume to tell you what to do. (Well, pretty much.)