Working with System Processes in WSH

In this article, we’re going to explore the different ways of working with system processes in WSH. Behind every running program in Windows is a process. Those processes control every end-user function that the computer performs.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 4
January 15, 2008
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Understanding and controlling these processes allows you to do some pretty advanced scripting.  Pretty advanced scripting, in turn, requires pretty advanced techniques and for that we turn to WMI.

The Windows Management Interface provides scriptable access to core system components and hardware.  It exposes dozens of properties and methods with classes that span nearly every corner of the operating system.

So why might someone want a script to have the ability to control processes?

Well, to be quite simple, if you control the processes, you control the entire operating system.  As you can imagine, this can be both extremely useful and potentially dangerous.

On the surface, processes are just programs.  Notepad, Calculator, and Microsoft Word are applications that rely on underlying processes.  You anti-virus program relies on an underlying process in order to monitor your system's health.

Some processes are more sophisticated and less visible, controlling such things as the Windows desktop, network connectivity, and Windows Update.  In fact, many processes run hidden, meaning that they don't display a user interface and they don't appear in the task bar.

The most common scripting tasks are to monitor what tasks are running or to start and stop them.  We'll go into detail on each of these as well as other functions such as raising or lowering a processes' priority level.

Taking a look under the hood

Our first task is will be to list all currently running processes.  This is useful when making a system snapshot or just for curiosity's sake.  For this example we'll list each process by Name and Process ID.

strComputer = "."

Set objWMIService = GetObject("winmgmts: " _

   "{impersonationLevel=impersonate}!" & strComputer _

      & "rootcimv2")

Set colProcess = objWMIService.ExecQuery _

   ("Select * from Win32_Process")

 

For Each objProcess In colProcess

   WScript.Echo objProcess.Name & ", PID: " & objProcess.ProcessId

Next

Here we're connecting to WMI and querying all objects belonging to the Win32_Process class.  This returns a collection of objects representing each of the currently running processes.  We are using the Name and ProcessID properties to return the Name and Process ID of each process respectively.

strComputer = "."

Set objWMIService = GetObject("winmgmts: " _

   "{impersonationLevel=impersonate}!" & strComputer _

      & "rootcimv2")

Set colProcess = objWMIService.ExecQuery _

   ("Select * from Win32_Process Where Name='explorer.exe'")

 

For Each objProcess In colProcess

   WScript.Echo objProcess.Name & ", PID: " & objProcess.ProcessId

Next

A slight modification to our query allows this code to list specific processes instead.  In this above example, I've used a Where clause to limit the objects returned to only those with the name Explorer.exe.

Again, this is useful if you are monitoring a specific process, however, we are kind of assuming that the process exists.  Another slight rewrite makes this code a little more effective.

strProcess = "Explorer.exe"

strComputer = "."

Set objWMIService = GetObject("winmgmts: " _

   "{impersonationLevel=impersonate}!" & strComputer _

      & "rootcimv2")

Set colProcess = objWMIService.ExecQuery _

   ("Select * from Win32_Process Where Name = '" & strProcess & "'")

 

If colProcess.Count < 0 Then

   WScript.Echo "Process is running."

Else

   WScript.Echo "Process is not running."

End If

Instead of actually working with the objects, we're simply checking to see if the collection returned any objects.  This would be useful if you simply wanted to return a True or False value indicating whether a particular process was active in memory.

A complete list of the properties and methods available through the Win32_Process can be found here.

Now that we've seen how to check whether a process is running, it could be useful to see how to start and stop them accordingly.  Again, WMI provides a way for us to do this with very small modifications to our existing code sample.

strProcess = "Explorer.exe"

strComputer = "."

Set objWMIService = GetObject("winmgmts: " _

   "{impersonationLevel=impersonate}!" & strComputer _

      & "rootcimv2")

Set colProcess = objWMIService.ExecQuery _

   ("Select * from Win32_Process Where Name = '" & strProcess & "'")

 

For Each objProcess In colProcess

   objProcess.Terminate

Next

This code returns all instances of a specified process and then makes use of the Terminate method to end each instance.  Starting a process is done slightly differently.

strProcess = "Explorer.exe"

strComputer = "."

Set objWMIService = GetObject("winmgmts: " _

   "{impersonationLevel=impersonate}!" & strComputer _

      & "rootcimv2")

Set objProcess = objWMIService.Get("Win32_Process")

Set objProgram = objProcess.Methods_("Create") _

   .InParameters.SpawnInstance_

objProgram.CommandLine = strProcess

 

Set objProcess = objWMIService.ExecMethod _

   ("Win32_Process", "Create", objProgram)

Here we resort to the Create method.  This method is native to the Win32_Process class and is not provided by its objects as before.  This method creates a process instance in memory with the command line provided.  This command line should be a full path if this process is not located in the system path.

More fun with processes

To this point, everything we've done has been in a snapshot state.  By this I mean that we have only been able to work with the processes that are running at the moment our script is executed.

What if we want a script to monitor processes and notify us whenever one starts or stops?  To do this, we can use the Win32_Process class with a bit of event-based programming.

strProcess = "iexplore.exe"

strComputer = "."

Set objWMIService = GetObject("winmgmts: " _

   "{impersonationLevel=impersonate}!" & strComputer _

      & "rootcimv2")

Set objEventSrc = objWMIService.ExecNotificationQuery( _

   "SELECT * FROM __InstanceCreationEvent " & _

       "WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'" _

         & "And TargetInstance.Name = '" & strProcess & "'")

  

Do While True

   Set objEvent = objEventSrc.NextEvent()

   WScript.Echo strProcess & " has been started."

   Exit Do

Loop

Event scripting is slightly beyond the scope of this article.  Understand that WMI is able to monitor certain events.  In this example we are monitoring the __InstanceCreationEvent which tells WMI whenever a new object is created in memory.  We then use a notification query to check whether that particular event was our process starting.

Notice how we've used an infinite loop to ensure that our script doesn't stop running.  Thus it will continue to monitor each new event until Internet Explorer is started.

strProcess = "iexplore.exe"

strComputer = "."

Set objWMIService = GetObject("winmgmts: " _

   "{impersonationLevel=impersonate}!" & strComputer _

      & "rootcimv2")

Set objEventSrc = objWMIService.ExecNotificationQuery( _

   "SELECT * FROM __InstanceDeletionEvent " & _

       "WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'" _

          & "And TargetInstance.Name = '" & strProcess & "'")

  

Do While True

   Set objEvent = objEventSrc.NextEvent

   WScript.Echo strProcess & " has been stopped."

   Exit Do

Loop

Waiting for a process to end is exactly the same except that we will be watching the __InstanceDeletionEvent to know when a process is unloaded from memory instead.

Again, the nature of how this code works is a bit beyond the scope of this article.  Just understand that this is the basic query structure you will need to use.  You can modify this query slightly to achieve other effects as well so don't be afraid to play with it.  For more information, you can check out my articles on event scripting with WMI.

Event Scripting with WMI

More Event Scripting with WMI

Modifying processes

The final set of code samples I have for you is designed for special needs when working with processes that you just may develop a need to script.  We'll begin by modifying a specific process and then we'll look at some cool things we can do with our own.

Const IDLE = 64

Const BELOW_NORMAL = 16384

Const NORMAL = 32

Const ABOVE_NORMAL = 32768

Const HIGH_PRIORITY = 128

Const REAL_TIME = 256

 

strProcess = "iexplore.exe"

strComputer = "."

Set objWMIService = GetObject("winmgmts: " _

   "{impersonationLevel=impersonate}!" & strComputer _

      & "rootcimv2")

Set colProcesses = objWMIService.ExecQuery _

   ("Select * from Win32_Process Where Name = '" & strProcess & "'")

 

For Each objProcess In colProcesses

   result = objProcess.SetPriority(ABOVE_NORMAL)

Next

The setPriority method allows you to control the priority of a running process.  It accepts predefined constant values to indicate the priority level and issues a return code from the table below.

Return Code

Description

0

Successful completion

2

Access denied

3

Insufficient Privilege

8

Unknown Failure

9

Path Not Found

21

Invalid Parameter

strProcess = "iexplore.exe"

strComputer = "."

Set objWMIService = GetObject("winmgmts: " _

   "{impersonationLevel=impersonate}!" & strComputer _

      & "rootcimv2")

Const ABOVE_NORMAL = 32768

 

Set objStartup = objWMIService.Get("Win32_ProcessStartup")

Set objConfig = objStartup.SpawnInstance_

objConfig.PriorityClass = ABOVE_NORMAL

  

Set objProcess = GetObject("winmgmts:rootcimv2:Win32_Process")

objProcess.Create strProcess, Null, objConfig

In the same way, it might also be useful to start a process at a specific priority level.  This code does just that for you.  It's a slightly modified combination of two examples you've already seen.  The PriorityClass property accepts the same values as the setPriority method that we just examined.

But settings a process' priority isn't all there is to do, is it?  It might also be nice to control how the process starts and runs.  After all, most processes run hidden, don't they?

strProcess = "iexplore.exe"

strComputer = "."

Set objWMIService = GetObject("winmgmts: " _

   "{impersonationLevel=impersonate}!" & strComputer _

      & "rootcimv2")

Const HIDDEN_WINDOW = 12

  

Set objStartup = objWMIService.Get("Win32_ProcessStartup")

Set objConfig = objStartup.SpawnInstance_

objConfig.ShowWindow = HIDDEN_WINDOW

  

Set objProcess = GetObject("winmgmts:rootcimv2:Win32_Process")

objProcess.Create strProcess, Null, objConfig

This time we rely on the ShowWindow property of the Win32_ProcessStartup class to set our process to run hidden.  This additional class allows us to control how processes start.  There are many properties and methods available with this class to control how a process starts and operates.  For more information, visit the link below.

MSDN: Win32_ProcessStartup Class

The final example I would like to provide for you is one that I sometimes find very useful.  It gives you the ability to prevent a process from running.  Essentially, it monitors for a process to start and then ends it.

strProcess = "iexplore.exe"

strComputer = "."

Set objWMIService = GetObject("winmgmts: " _

   "{impersonationLevel=impersonate}!" & strComputer _

      & "rootcimv2")

Set colProcess = objWMIService.ExecNotificationQuery _

   ("Select * from __InstanceCreationEvent" _

       & " WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'")

 

Do While True

   Set objLatestProcess = colProcess.NextEvent

   If objLatestProcess.TargetInstance.Name = strProcess Then

       objLatestProcess.TargetInstance.Terminate

   End If

Loop

This code basically combines our examples for monitoring a process start-up and ending a process.  Again, this code can be further modified to suit your needs.  This example demonstrates how you can combine the techniques you've seen to produce a usable script.

Take the time to explore the MSDN documentation for the Win32_Process and Win32_ProcessStartup classes.  They provide many other properties and methods that I was unable to include for lack of space.  By reading the documentation and getting to know these WMI classes, you can add a lot of power to your scripts and more weapons to your scripting arsenal.  Until next time, keep coding!

blog comments powered by Disqus
WINDOWS SCRIPTING ARTICLES

- More Windows Scripting Workarounds from Nilpo
- Overloading Methods and More in VBScript
- Improving MFC for Windows Vista
- Regular Expressions in VBScript
- Working with Dates in WMI
- Completing Calendars with VBScript Date Func...
- Building Calendars with VBScript Date Functi...
- Working With Dates and Times in VBScript
- Designing WCF DataContract Classes Using the...
- Understanding Dates and Times in VBScript
- Working With Arrays in VBScript
- Compressed Folders in WSH
- Using .NET Interops in VBScript
- Nilpo`s Scripting Secrets, Vol I
- Database operations using Silverlight 2.0 WC...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 2 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials