C# WMI Tutorial


Overview

I recently had a project where I was writing an agent that would collect data from various servers on the network. I needed information like the server name, IP address, OS drive, free and total space on the OS drive, Windows folder and so on. In addition to this I also needed to be able to collect information on specific files on each server as well as registry information from particular registry keys on each server. This would all be consolidated into a database and referred to at a future date.

In order to gather this information I turned to using WMI (See Background & Terminology below) within a C# application. The problem is that none of the research I performed turned up very good information on how to use WMI within C# and what was available to gather from within WMI.

This tutorial will provide a step-by-step process to follow in order to use WMI. It will provide information about the tools you need, how to use them and finally how to code to get information from WMI.

Background & Terminology

This article deals with coding for and consuming WMI (Windows Management Instrumentation). WMI is a set of extensions Microsoft created to provide instrumentation (measurement) information from within Windows. However, WMI is a Microsoft-specific set of extensions that are actually built upon the WBEM (Web-Based Enterprise Management) and CIM (Common Information Model) standards developed by the DMTF (Distributed Management Task Force).

The WMI set of instrumentation comes pre-installed in all Windows 2000 or newer operating systems from Microsoft and can be downloaded for older OS’s like Windows NT, 95 and 98. It’s powerful because it can be utilized by languages like VBScript, PowerShell and .NET to manage the operating system and gather a wide variety of information on it.

WBEM Test Tool

You’re going to need to become familiar with a tool called WBEMTest. This tool is pre-installed, along with WMI, on Windows 2000 and newer operating systems from Microsoft. To run it do the following.

  1. Open Run dialog (Win+R, Start->Run, etc.).
  2. Type ‘wbemtest’ and click OK.

The following dialog will appear.

WBEMTest

There are three things we need to know before using this tool. First you must connect to a WMI repository in order to pull anything from WMI. The default namespace you’ll be using is generally “root\cimv2”. Also, similar to .NET there are classes and instances of those classes. The class itself only defines what type of information might be provided in any particular instance of that class. The instances contain the information itself. To more fully understand this we’ll run through some examples.

Example 1: Obtain Drive Information

  1. Open WBEMTest as noted above.
  2. Click Connect.
  3. Ensure the Namespace is set to “root\cimv2” and click Connect.
  4. Click Open Class.
  5. Enter “Win32_LogicalDisk” and click OK.
  6. Info:
    1. The Properties (middle) list shows the information you can obtain from each instance.
  7. Click Instances.
  8. Info:
    1. The list will show all instances of Win32_LogicalDisk (drives) on your system (C, D, E, etc.).
    2. Notice the list shows the “DeviceID” property is what is set to the drive letter.
    3. We will gather information on the C drive (DeviceID=”C:”).
  9. Click Close and Close again to get back to the main window.
  10. Click Open Instance.
  11. Enter “Win32_LogicalDisk.DeviceID=’C:'” and click OK.
  12. Info:
    1. The Properties windows now contains information for each property in the class as it relates to the C drive.
    2. Later we will obtain information in C# on one of these properties.
    3. We’ll need to note the class (Win32_LogicalDisk), the DeviceID (C:) and the property name we want (“FreeSpace”).

Example 2: Obtain Windows Information

  1. Open WBEMTest as noted above.
  2. Click Connect.
  3. Ensure the Namespace is set to “root\cimv2” and click Connect.
  4. Click Open Class.
  5. Enter “Win32_OperatingSystem” and click OK.
  6. Info:
    1. The Properties (middle) list shows the information you can obtain from each instance.
  7. Click Instances.
  8. Info:
    1. The list will show all instances of Win32_OperatingSystem on your system.
    2. Notice the list doesn’t show anything behind Win32_OperatingSystem other than the “@” sign.
    3. We will gather information on this default OS instance (@).
  9. Click Close and Close again to get back to the main window.
  10. Click Open Instance.
  11. Enter “Win32_OperatingSystem=@” and click OK.
  12. Info:
    1. The Properties windows now contains information for each property in the class.
    2. Later we will obtain information in C# on one of these properties.
    3. We’ll need to note the class (Win32_OperatingSystem) and the property name we want.

Get WMI Information in C#

Now we will code the two examples above in order to obtain the information from the properties we saw in the examples. We will start with example 1. In this example “Win32_LogicalDisk” is the class we’ll be looking at.

  • Create a new C# Console Application in Visual Studio.
  • Add “System.Management” to the project references.
  • Add a “using System.Management;” statement to the top of the Program.cs file.
  • Perform the remaining steps inside the Main method (or wherever you want it).
  • Define your query (what you want to return from WMI).
    var dskQuery = new SelectQuery("Win32_LogicalDisk", "DriveType=3");
  • Define your scope (what system you want to connect to and WMI path).
    var mgmtScope = new ManagementScope("\\\\COMPUTERNAME\\root\\cimv2");
  • Connect to WMI.
    mgmtScope.Connect();
  • Define a searcher for the query.
    var mgmtSrchr = new ManagementObjectSearcher(mgmtScope, dskQuery);
  • Call searcher’s Get method and loop through results.
    foreach (var disk in mgmtSrchr.Get()) {
  • Get the DeviceID of the current loop item and compare to the drive we want info on.
    var devId = disk.GetPropertyValue("DeviceID").ToString();
    if (!string.IsNullOrEmpty(devId) && devId == "C:") {
  • Get the value of the property we want (FreeSpace) and validate.
    var freeWmi = disk.GetPropertyValue("FreeSpace").ToString();
    var freeInt = 0;
    if (!string.IsNullOrEmpty(freeWmi) && int.TryParse(freeWmi, out freeInt)) {
    Console.WriteLine("Free Space on " + devId + " Drive: " + freeInt.ToString());
    }}
  • Close out the for-each loop.
    }

The second example is coded as follows in order to get operating system information from the single default instance. In this example “Win32_OperatingSystem” is the class we’ll be looking at.

  • Create a new C# Console Application in Visual Studio.
  • Add “System.Management” to the project references.
  • Add a “using System.Management;” statement to the top of the Program.cs file.
  • Perform the remaining steps inside the Main method (or wherever you want it).
  • Define your query (what you want to return from WMI).
    var osQuery = new SelectQuery("Win32_OperatingSystem");
  • Define your scope (what system you want to connect to and WMI path).
    var mgmtScope = new ManagementScope("\\\\COMPUTERNAME\\root\\cimv2");
  • Connect to WMI.
    mgmtScope.Connect();
  • Define a searcher for the query.
    var mgmtSrchr = new ManagementObjectSearcher(mgmtScope, osQuery);
  • Call searcher’s Get method and loop through results.
    foreach (var os in mgmtSrchr.Get()) {
  • Get the value of the property we want (Version) and validate.
    var osVer = os.GetPropertyValue("Version").ToString();
    if (!string.IsNullOrEmpty(osVer))
    Console.WriteLine("OS Version: " + osVer);
  • Close out the for-each loop.
    }

Summary

The only remaining thing left to do is to determine what all of the Classes are that you can gather information on. This site contains WMI Class Information by the type of information you want. Keep in mind security considerations when trying to open remote WMI repositories. You can find more about maintaining WMI Security here.

I hope this help you get the entire picture of how to find and consume WMI information.

Advertisements

2 thoughts on “C# WMI Tutorial

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s