Understanding WMI -- Managing Windows networks using scripts, part 3

Learn how Windows Management Instrumentation (WMI) works and how it can be scripted using VBScript in this tip, originally published on WindowsNetworking.com.

    Requires Free Membership to View

This article originally appeared on WindowsNetworking.com.

In the first two articles of this series we saw how to change the IP address of a network adapter on a Windows computer using VBScript. Along the way we learned many of the basic concepts of Windows scripting such as classes, objects, properties, methods, and different types of variables including string variables, integer variables, arrays and collections. We also learned some of the basics of writing a good script such as defining variables, implementing error handling, accepting user input, displaying confirmation output, and documenting your script by adding comments.

Read other 'Managing Windows networks using scripts' tips
Part 1: The basics

Part 2: Cleaning up

Part 3: Understanding WMI

Part 4: Using Win32_NetworkAdapterConfiguration

Part 5: Getting over the hump

Part 6: Remote scripting first steps

Part 7: Troubleshooting the mystery error

Part 8: Troubleshooting remote scripting with Network Monitor 3.0

Part 9: Understand remote scripting

Part 10: Two tricks using WMI scripts

Part 11: More remote scripting tips

Part 12: Properties of WMI class

Part 13: A return-all-values script

Part 14: WMI scripting resources

Our final script worked as expected, but there may be some aspects of it you still find mysterious. For example, take a look at this particular line:

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

In my first article, I made the following comment concerning this particular line: "This connects you to the root\cimv2 namespace on the local computer by defining an object named objWMIService and setting it equal to the handle returned by the GetObject method."

What on earth does that mean? What's WMI and how does it work? And why is it important to learn about if you want to learn how to write scripts to administer Windows computers?

Understanding WMI

WMI has been around since the days of Windows 98 and earlier, only back then it was called something different: Web-Based Enterprise Management (WBEM). WBEM was a technology developed jointly by Microsoft, Cisco, Intel, Compaq and BMC Software to make it easier to manage desktop and server systems in enterprise environments. WMI provides a model for how to represent, store and query configuration and status information and other operational aspects of Windows computers. Developers can use WMI to write scripts or managed code to view and modify configuration settings on Windows computers, to view the status of Windows applications and services, and do a whole lot of other things useful to administrators who deploy, maintain and troubleshoot Windows-based networks.

In other words, WMI stands for:

  • Windows - works on and for computers running Microsoft Windows
  • Management - can be used to manage these computers
  • Instrumentation - provides instruments for viewing and modifying what goes on under the hood with these computers

A good analogy is to think of a Windows computer as a car and WMI as the electronics (instrumentation) that enables your dashboard to display your speed, engine temperature, RPMs, and so on. These dashboard controls aren't themselves WMI -- you still have to figure out a way to get the info out of the electronics and present it in a readable form. Writing VBScripts that use WMI is therefore like creating dashboard display elements that can hook into the instrumentation under your car's hood and tell you what you want to know and control what your engine is doing. In other words, Windows ships with all this instrumentation built into it via WMI--you just need to figure out how to get at it so you can do something useful with it like change your IP address, view your time zone, reboot a remote machine, display a list of installed hotfixes -- whatever.

WMI namespaces

Just about anything -- well, not quite. Actually, finding out whether WMI can do something in particular takes a bit of patience and understanding. Let's start by considering WMI namespaces. In WMI terminology, a namespace is a kind of logical database of classes and their instances. Here's a simple script called ShowNamespaces.vbs that enumerates all WMI namespaces under the root namespace:

Set objWMIService = GetObject("winmgmts:\\.\root")
Set colNamespaces = objWMIService.InstancesOf("__NAMESPACE")

For Each objNamespace In colNamespaces
     WScript.Echo objNamespace.Name

Here's the result of running this script on a Windows XP machine:

C:\scripts>cscript ShowNamespaces.vbs

Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.


Each of these namespaces is a possible source which you can query for information concerning the status or configuration of some aspect of a Windows computer (and often modify that configuration as well). These namespaces are organized hierarchically like the folders on a hard drive. For example, we can display all the namespaces under the root\CIMV2 namespace by modifying the first line of our script as follows:

Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")

When you run this modified script, the output looks like this:

C:\scripts>cscript ShowNamespaces.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.


In fact, root\CIMV2 is the default WMI namespace on Windows machines. What this means is that if you don't specify a namespace to connect to in the first line of this script, WMI will automatically connect to the root\CIMV2 namespace by default. So if we change the first line to this: Set objWMIService = GetObject("winmgmts:\\") ...We get the same results as above. Note that we've also left out the period in winmgmts:\\.\root\CIMV2. If you remember from our first article, this period represented the local computer and by default WMI assumes you want to work with the local computer which means you can leave out the period if you want to. Best practices for scripting however is to use variables (and define them) so here's a more generalized script we can use for displaying WMI namespaces:

Option Explicit
On Error Resume Next
Dim strComputer
Dim strWMINamespace
Dim objWMIService
Dim colNamespaces
Dim objNamespace

strComputer = "."
strWMINamespace = "\root\CIMV2"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Set colNamespaces = objWMIService.InstancesOf("__NAMESPACE")

For Each objNamespace In colNamespaces
     WScript.Echo objNamespace.Name

Why go to all this trouble? The main reason is flexibility! For example, if we need to run the script against a remote computer we can change the value of strComputer to the IP address of the remote machine. Or if we need to display a different portion of the namespace, we could add a few lines to our script to accept user input for the strWMINamespace variable.

WMI providers

Finding the right namespace is just the first challenge (though much of the time connecting to the default namespace will suffice). You also have to access the right provider in order to retrieve or update data on the system you are targeting. Here's a script called ShowProviders.vbs that displays all the WMI providers for the root\CIMV2 namespace:

Option Explicit
On Error Resume Next
Dim strComputer
Dim strWMINamespace
Dim objWMIService
Dim colWin32Providers
Dim objWin32Provider

strComputer = "."
strWMINamespace = "\root\CIMV2"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Set colWin32Providers = objWMIService.InstancesOf("__Win32Provider")

For Each objWin32Provider In colWin32Providers
     WScript.Echo objWin32Provider.Name

And here's the output from running this script on a Windows XP machine:

C:\scripts>cscript ShowProviders.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

SCM Event Provider
Microsoft WMI Forwarding Event Provider
Standard Non-COM Event Provider
WMI Kernel Trace Event Provider
WMI Self-Instrumentation Event Provider

Looks a bit overwhelming, doesn't it? Using this list of providers however, you can easily search MSDN for more information concerning a particular provider and find what methods it supports, that is, what you can do with the provider using WMI.

WMI classes

Besides namespaces and providers, you also need to understand WMI classes if you want to leverage the power of WMI to script Windows administration tasks. A class is a kind of template for a type of object you can manage using WMI. For example, the class named Win32_LogicalDisk is a template for logical disks on Windows machines, and WMI uses this class to generate one instance of Win32_LogicalDisk for each installed disk.

Here's a script called ShowClasses.vbs that displays all the classes (potentially manageable objects) for the root\CIMV2 namespace:

Option Explicit
On Error Resume Next
Dim strComputer
Dim strWMINamespace
Dim objWMIService
Dim colClasses
Dim objClass

strComputer = "."
strWMINamespace = "\root\CIMV2"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Set colClasses = objWMIService.SubclassesOf()

For Each objClass In colClasses
    WScript.Echo objClass.Path_.Path

And here's just some of the output (there's lots!) from running this script on Windows XP:

C:\scripts>cscript ShowClasses.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.


Again, this all looks a bit overwhelming, but using this list of classes you can search MSDN for more information concerning a particular WMI class to find what properties and methods are associated with.

Using WMI

Let's make some use of what we've learned above. One of the classes that the script above displays is Win32_TimeZone, and let's use this to display the time zone that's configured on the computer. First we need to find out more about this class, and searching for "Win32_TimeZone class" brings up this page on MSDN. On this page we can find information about the properties and methods that this class supports (though actually this particular class only has properties and no methods) and using this information we should be able to write the script we want.

A little experimenting shows that it's the Caption property that we want to display as this is the most "human-readable" form of time zone information stored on the machine. Here's the script named DisplayTimeZone.vbs that we'll use to query WMI for this information and display it:

Option Explicit
On Error Resume Next
Dim strComputer
Dim strWMINamespace
Dim strWMIQuery
Dim objWMIService
Dim colItems
Dim objItem

strComputer = "."
strWMINamespace = "\root\CIMV2"
strWMIQuery = "SELECT * FROM Win32_TimeZone"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Set colItems = objWMIService.ExecQuery(strWMIQuery)

For Each objItem In colItems
    WScript.Echo objItem.Caption

And here's the result of running this script:

C:\scripts>cscript DisplayTimeZone.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

(GMT-06:00) Central Time (US & Canada)

Let's see how this script works. First, you can see a lot of it is based on our previous scripts above. In other words, we begin by connecting WMI using the following statement:

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

The next statement however is new:

Set colItems = objWMIService.ExecQuery(strWMIQuery)

What we're doing here is executing a query against WMI to gather some information from it. The query was defined earlier using the following statement:

strWMIQuery = "SELECT * FROM Win32_TimeZone"

This SQL-type SELECT statement basically returns everything (the asterisk) that the Win32_TimeZone provider has to offer us and stores the results in a collection named colItems. Then we loop through each item in this collection (there's only one item returned by the query) and display the Caption property of this item, which is the following text string:

(GMT-06:00) Central Time (US & Canada)

Try this exercise

We'll dig deeper into WMI scripting in future articles of this series, but for now let's try a little exercise. Copy the contents of the DisplayTimeZone.vbs script above into Notepad (make sure Word Wrap is turned off) and save it as PageFile.vbs. Now change one line in the script (actually only a small portion of a line) so that when the script is run it displays the path and name of your system's pagefile instead of its time zone. Here's a hint: search MSDN for info about the Win32_PageFile class. I'll give you the answer to this exercise in the next article in this series.

About the author:
Mitch Tulloch is a writer, trainer and consultant specializing in Windows server operating systems, IIS administration, network troubleshooting, and security. He is the author of 15 books including the Microsoft Encyclopedia of Networking (Microsoft Press), the Microsoft Encyclopedia of Security (Microsoft Press), Windows Server Hacks (O'Reilly), Windows Server 2003 in a Nutshell (O'Reilly), Windows 2000 Administration in a Nutshell (O'Reilly), and IIS 6 Administration (Osborne/McGraw-Hill). Mitch is based in Winnipeg, Canada, and you can find more information about his books at his website: www.mtit.com.

WindowsNetworking.com contains a wealth of networking information for administrators: Featuring information on how to setup and troubleshoot various networks of any size. Also includes a comprehensive archive of hundreds of reviewed networking software and hardware solutions. Frequently updated with articles and tips by a team of leading authors, it remains a favorite within the networking community.

This was first published in September 2007

There are Comments. Add yours.

TIP: Want to include a code block in your comment? Use <pre> or <code> tags around the desired text. Ex: <code>insert code</code>

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
Sort by: OldestNewest

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

Disclaimer: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.