Windows Management Instrumentation (WMI)


 
Windows Management Instrumentation (WMI) is the infrastructure for management data and operations on Windows-based operating systems. With WMI you can get information on all hardware in a system, including:
  • HDD Serial Number(s)
  • HDD Sizes
  • HDD Free Space
  • CPU Serial Number(s)
  • CPU Clock Speed
  • CPU Socket Type
  • Network Adapter MAC Address
  • Network Adapter Default Gateway


And much more. In this tutorial we will be looking at some of the information that can be retrieved using WMI, along with Windows Query Language, or WQL. though this tutorial isn't an all inclusive tutorial on the topic, we will look at enough to at least give you a good foundation for using WMI in your applications.

In this tutorial we will see how to retrieve HDD information, CPU information, and Network Adapter information. For this tutorial there are 3 classes we will be using to retrieve this information for our applications:



Of course there are many more WMI Classes that are available, and if I were to try and cover all of them this would be a 20 page tutorial. All the items we will be using require a reference to the System.Management Namsepace provided in the .Net framework

Win32_LogicalDiskClass

The Win32_LogicalDisk WMI class represents a data source that resolves to an actual local storage device on a computer system running Windows. In this section we will do a few tasks such as:

  • Retrieve selected HDD serial number
  • Retrieve selected HDD free space
  • Retrieve HDD initial size

The first task, getting the serial number of a selected HDD (as with all the tasks in this section) we will be passing a drive letter to our method, with that drive letter we will query the system using the DeviceIDProperty of the Win32_LogicalDisk class. Once we have done that we have access to many properties, which we will use in this section. First, to receive the serial number:


01 /// <summary>
02 /// method to retrieve the selected HDD's serial number
03 /// </summary>
04 /// <param name="strDriveLetter">Drive letter to retrieve serial number for</param>
05 /// <returns>the HDD's serial number</returns>
06 public string GetHDDSerialNumber(string drive)
07 {
08     //check to see if the user provided a drive letter
09     //if not default it to "C"
10     if (drive == "" || drive == null)
11     {
12         drive = "C";
13     }
14     //create our ManagementObject, passing it the drive letter to the
15     //DevideID using WQL
16     ManagementObject disk = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + drive +":\"");
17     //bind our management object
18     disk.Get();
19     //return the serial number
20     return disk["VolumeSerialNumber"].ToString();
21 }


As you can see, we check the DevideID to ensure we are looking at the proper HDD, then we use the Get Method of the ManagementObject Class to bind our management object, allowing us to retrieve the attributes we are looking for.

The nice thing about the Win32_LogicalDisk Class is once you learn to retrieve one attribute or property, the rest are easily retrieved, such as retrieving the free space of a HDD:


01 /// <summary>
02 /// method to retrieve the HDD's freespace
03 /// </summary>
04 /// <param name="drive">Drive letter to get free space from (optional)</param>
05 /// <returns>The free space of the selected HDD</returns>
06 public double GetHDDFreeSpace(string drive)
07 {
08     //check to see if the user provided a drive letter
09     //if not default it to "C"
10     if (drive == "" || drive == null)
11     {
12         drive = "C";
13     }
14     //create our ManagementObject, passing it the drive letter to the
15     //DevideID using WQL
16     ManagementObject disk = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + drive +":\"");
17     //bind our management object
18     disk.Get();
19     //return the free space amount
20     return Convert.ToDouble(disk["FreeSpace"]);
21 }
And retrieving the initial size of a selected HDD, like so:

01 /// <summary>
02 /// method to retrieve the HDD's size
03 /// </summary>
04 /// <param name="drive">Drive letter to get free space from (optional)</param>
05 /// <returns>The free space of the selected HDD</returns>
06 public double getHDDSize(string drive)
07 {
08     //check to see if the user provided a drive letter
09     //if not default it to "C"
10     if (drive == "" || drive == null)
11     {
12         drive = "C";
13     }
14     //create our ManagementObject, passing it the drive letter to the
15     //DevideID using WQL
16     ManagementObject disk = new ManagementObject("Win32_LogicalDisk.DeviceID=\"" + drive +":\"");
17     //bind our management object
18     disk.Get();
19     //return the HDD's initial size
20     return Convert.ToDouble(disk["Size"]);
21 }



You will notice in the previous 3 methods the drive letter is actually optional. We check to see if a drive was provided, and if it wasnt then we default it to the users "C" drive, which is usually the OS drive on most computers.


Win32_NetworkAdapterConfiguration Class

The Win32_NetworkAdapterConfiguration WMI class represents the attributes and behaviors of a network adapter. This class includes extra properties and methods that support the management of the TCP/IP and IPX (Internetwork Packet Exchange) protocols.

With this class we can get information such as:

  • MAC Address
  • Default IP Gateway
  • IP Enabled Status


In the following examples we will be introduced to the ManagementObjectCollection Class. This class represents different collections of management objects that can be retrieved through WMI. We will then loop through all the items in our collection to retrieve information about the network adapter on that particular system.

First we will look at how to retrieve the systems MAC address. In these examples we will onl;y be retrieving information from the first network adapter we find, they can easily be modified to create a collection of network adapter information.


01 /// <summary>
02 /// Returns MAC Address from first Network Card in Computer
03 /// </summary>
04 /// <returns>MAC Address in string format</returns>
05 public string FindMACAddress()
06 {
07     //create out management class object using the
08     //Win32_NetworkAdapterConfiguration class to get the attributes
09     //of the network adapter
10     ManagementClass mgmt = new ManagementClass("Win32_NetworkAdapterConfiguration");
11     //create our ManagementObjectCollection to get the attributes with
12     ManagementObjectCollection objCol = mgmt.GetInstances();
13     string address = String.Empty;
14     //loop through all the objects we find
15     foreach (ManagementObject obj in objCol)
16     {
17         if (address == String.Empty)  // only return MAC Address from first card
18         {
19             //grab the value from the first network adapter we find
20             //you can change the string to an array and get all
21             //network adapters found as well
22             //check to see if the adapter's IPEnabled
23             //equals true
24             if ((bool)obj["IPEnabled"] == true)
25             {
26                 address = obj["MacAddress"].ToString();
27             }
28         }
29         //dispose of our object
30         obj.Dispose();
31     }
32     //replace the ":" with an empty space, this could also
33     //be removed if you wish
34     address = address.Replace(":", "");
35     //return the mac address
36     return address;
37 }



In the first example, along with the others in this section, we will be using the GetInstances Method of the ManagementObjectCollection Class to retrieve all instances of the specified class, in this case the Win32_NetworkAdapterConfiguration class. 

Now lets look at retrieving the default IP gateway of a network adapter. As with the first example, we will be using the first adapter we find, as long as its IPEnabled Property is true:


01 /// <summary>
02 /// method to retrieve the network adapters
03 /// default IP gateway using WMI
04 /// </summary>
05 /// <returns>adapters default IP gateway</returns>
06 public string GetDefaultIPGateway()
07 {
08     //create out management class object using the
09     //Win32_NetworkAdapterConfiguration class to get the attributes
10     //of the network adapter
11     ManagementClass mgmt = new ManagementClass("Win32_NetworkAdapterConfiguration");
12     //create our ManagementObjectCollection to get the attributes with
13     ManagementObjectCollection objCol = mgmt.GetInstances();
14     string gateway = String.Empty;
15     //loop through all the objects we find
16     foreach (ManagementObject obj in objCol)
17     {
18         if (gateway == String.Empty)  // only return MAC Address from first card
19         {
20             //grab the value from the first network adapter we find
21             //you can change the string to an array and get all
22             //network adapters found as well
23             //check to see if the adapter's IPEnabled
24             //equals true
25             if ((bool)obj["IPEnabled"] == true)
26             {
27                 gateway = obj["DefaultIPGateway"].ToString();