Windows Management Instrumentation (WMI) is Microsoft’s implementation of Web-Based Enterprise Management (WBEM), a standards-based system management interface. WMI debuted with Microsoft Windows 2000, but it can be installed on Windows NT 4 and Windows 9x machines as well. It’s a powerful tool that makes it easy to retrieve system information.

Why use WMI?
In many instances, the information you get from WMI you can also get in other ways from the Windows operating system. For example, if you want the name of the computer, you can look it up in the Registry. If you want the amount of free disk space on the C: drive, you can use an API call. But it’s often difficult to retrieve information in this way, particularly if you’re developing in Visual Basic. WMI allows you to retrieve system information using a well-documented object model, SQL-like queries, and usually with much less and easier-to-read code.

Using WMI: Three examples
Let’s look at the following three topics: querying WMI, retrieving WMI information, and calling WMI methods. The examples given here are written in Visual Basic. For more information on WMI, see the WMI documentation on MSDN.

Querying WMI
WMI is generally queried in two ways: by retrieving an entire WMI object or by using a SQL-like query. Also, since we’re accessing system information and can even query machines across a network, we need to provide security information when querying WMI. First, we need to add a reference to the WMI type library by opening Project – References in Visual Basic and selecting Microsoft WMI Scripting Library. Once we’ve created the reference to the WMI type library, we can work with WMI as demonstrated below.
Dim oWMI as SWBEMObjectSet
Set oWMI =

Let’s look at what this code shows us. First, we declared a variable as SWBEMObjectSet, which is the standard WMI collection class. Next, we instantiated oWMI with a very long statement. Notice first the reference to Winmgmts. This object provider is the standard reference to WMI. The next part, {impersonationLevel=impersonate}, defines with what security we are to query the system. As defined here, we’re going to use the credentials of the user running the program. Several security levels and authentication methods are defined in the WMI documentation. InstancesOf is a WMI method that retrieves all of the instances of the requested WMI object. Finally, we state the object we want to retrieve, Win32_LogicalDisk, which contains information on all of the drives on the computer. When this statement is executed, oWMI will have a collection of WMI objects with information about each drive. Later on, we’ll examine how to retrieve that information.

I mentioned that we can use SQL-like statements to query WMI with WMI Query Language (WQL). WQL is a retrieval-only form of SQL that supports a limited SQL vocabulary. If we want to use WQL to query WMI, we use the ExecQuery method instead of InstancesOf. To demonstrate how WQL works, let’s change our query above to only retrieve local (not network) drives:
Set oWMI = GetObject(“winmgmts: {impersonationLevel=impersonate}”).ExecQuery(“select * from Win32_LogicalDisk where DriveType=3”)

Now you can retrieve information
Once we have a WMI object collection, we can retrieve the information contained within it. Each WMI object has several properties containing system information. For a list of all of the standard WMI objects and their attributes, refer to the WMI documentation. The following example shows how to retrieve drive information from the Win32_LogicalDisk object we just accessed:
Dim wmiObject As SwbemObject
For Each wmiObject In oWMI
DriveName = wmiObject.Caption
FreeSpace = wmiObject.FreeSpace
TotalSize = wmiObject.Size

Retrieving information from WMI is straightforward, but sometimes, a little more work must be done. For example, some properties contain array data. In that case, simply loop through the array from the lower bound to the upper bound to read each individual property. Another data type that requires extra handling is date properties. A WMI date string looks like this: 20020402080418.000000-420, where the format follows Table A.
Table A

Characters Value
1-4 Year
5-6 Month
7-8 Day
9-10 Hour
11-12 Minute
13-14 Second
15-21 Millisecond
22-25 UTC offset

WMI formatting

WMI dates are usually stated in Coordinated Universal Time—thus the UTC offset to get the local time. However, I’ve come across a few attributes that are stated in local time, so be sure the times appear correct in your testing.

Calling WMI methods
WMI not only access a great deal of system information, but it has methods defined to modify the system. One of the first WMI methods I used allows you to enable DHCP for a NIC or, conversely, to set a static IP address for the NIC. Listing A shows how.

This example queries for a specific NIC named EL90Xbc0 3Com EtherLink PCI. If DHCP is enabled on the NIC, the adapter is changed to a static IP address using the EnableStatic method of the Win32_NetworkAdapterConfiguration object. If DHCP is not enabled, use the EnableDHCP method. Note how the IP address and the subnet mask passed to EnableStatic are defined as string arrays. Since EnableStatic requires string arrays as parameters, the variables must be initialized in this way.

WMI vs. traditional methods
Now, you may be thinking that you could have handled each of the examples perfectly well using the Windows API or accessing the registry. Well, let’s do a quick comparison between WMI and traditional Windows methods.

In this example, let’s gather a list of all of the services on the machine. You may need to query the system for this information in case your application depends on a particular service. First, let’s look at the code for doing this using the Windows API (Listing B). Now, let’s use WMI to get the same information (Listing C).

To perform the same query, the WMI code is much shorter and easier to read. If you were to compare the execution speed of these two examples, the WMI function will be slower. But speed aside, there are advantages to using WMI.

Only the beginning
We’ve only scratched the surface of WMI’s potential. WMI also lets you develop your own and other information providers beyond the Win32 objects, query remote computers, and access WMI with a high-performance API. Microsoft has demonstrated a commitment to expanding the capabilities of WMI in future versions of Windows with enhancements like a command-line WMI query tool in Windows XP. WMI is a powerful system tool that can add capabilities to your applications.