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();
28             }
29         }
30         //dispose of our object
31         obj.Dispose();
32     }
33     //replace the ":" with an empty space, this could also
34     //be removed if you wish
35     gateway = gateway.Replace(":", "");
36     //return the mac address
37     return gateway;
38 }



Win32_Processor

This class allows us to retrieve properties of the processor running on a Windows based computer. On a system with multiple processors, one instance of the Win32_Processor class exists for each processor. Using this class allows us to retrieve information about the processor such as:

  • CPU ID
  • CPU Manufacturer
  • CPU Status
  • CPU Current Clock Speed


As with the other class examples, we will only be getting information from the first processor we find, they too can be modified to return information for all processors in a system. In these examples we will also be using theGetInstances Method, as each processor will have it's own instance. First, getting the CPU ID:


01 /// <summary>
02 /// Return processorId from first CPU in machine
03 /// </summary>
04 /// <returns>[string] ProcessorId</returns>
05 public string GetCPUId()
06 {
07     string cpuInfo =  String.Empty;        
08     //create an instance of the Managemnet class with the
09     //Win32_Processor class
10     ManagementClass mgmt = new ManagementClass("Win32_Processor");
11     //create a ManagementObjectCollection to loop through
12     ManagementObjectCollection objCol = mgmt.GetInstances();
13     //start our loop for all processors found
14     foreach(ManagementObject obj in objCol)
15     {
16         if(cpuInfo == String.Empty)
17         {
18             // only return cpuInfo from first CPU
19             cpuInfo = obj.Properties["ProcessorId"].Value.ToString();
20         }           
21     }
22     return cpuInfo;    
23 }



To get the manufacturer, we will return the Manufacturer property of the first instance we find:


01 /// <summary>
02 /// method for retrieving the CPU Manufacturer
03 /// using the WMI class
04 /// </summary>
05 /// <returns>CPU Manufacturer</returns>
06 public string GetCPUManufacturer()
07 {
08     string cpuMan = String.Empty;
09     //create an instance of the Managemnet class with the
10     //Win32_Processor class
11     ManagementClass mgmt = new ManagementClass("Win32_Processor");
12     //create a ManagementObjectCollection to loop through
13     ManagementObjectCollection objCol = mgmt.GetInstances();
14     //start our loop for all processors found
15     foreach (ManagementObject obj in objCol)
16     {
17         if (cpuMan == String.Empty)
18         {
19             // only return manufacturer from first CPU
20             cpuMan = obj.Properties["Manufacturer"].Value.ToString();
21         }
22     }
23     return cpuMan;     
24 }



Processors today are vastly different than they were 20 years ago, today people are over clocking their processors to get more power out of them. That being the case, some systems might be running at a higher clock speed than what is listed on the system information, so we will use the CurrentClockSpeed Property to retrieve the current clock speed of the first instance we find:


01 /// <summary>
02 /// method to retrieve the CPU's current
03 /// clock speed using the WMI class
04 /// </summary>
05 /// <returns>Clock speed</returns>
06 public int GetCPUCurrentClockSpeed()
07 {
08     int cpuClockSpeed = 0;
09     //create an instance of the Managemnet class with the
10     //Win32_Processor class
11     ManagementClass mgmt = new ManagementClass("Win32_Processor");
12     //create a ManagementObjectCollection to loop through
13     ManagementObjectCollection objCol = mgmt.GetInstances();
14     //start our loop for all processors found
15     foreach (ManagementObject obj in objCol)
16     {
17         if (cpuClockSpeed == 0)
18         {
19             // only return cpuStatus from first CPU
20             cpuClockSpeed = Convert.ToInt32(obj.Properties["CurrentClockSpeed"].Value.ToString());
21         }
22     }
23     //return the status
24     return cpuClockSpeed;  
25 }



As stated before this isnt an all exhaustive list of classes and ways to use the WMI class, there are hundreds (maybe more) items that can be retrieved about a system using this class. The items in this tutorial, and the attached class file, will give you a good jump start on using the WMI class in your applications.
 

© 2019 Saini Technologies. All rights reserved | Design by SainiTechnologies.com