WMI programming using C#.NET

Hello, Anil Chintala here. I am a senior developer on the Information Security Tools team. I work in operations engineering cell which is focused on building scanning tools, data protection tools and number of other security tools to support InfoSec operations team within Microsoft.

As part of the Windows 7 and Bitlocker Drive Encryption deployments within Microsoft, I had an opportunity to work on a tool that checks Bitlocker capability of a machine and enforce Bitlocker Drive Encryption on it. We’ve used Windows Management Instrumentation (WMI) and .NET Framework 3.5 to do some cool stuff to access and interact with windows management objects.

Before going any further with the blog post, here is a quick intro on WMI.
WMI is the Microsoft implementation of WBEM (Web-Based Enterprise Management) and CIM (Common Information Model); industry standards of DMTF (Distributed Management Task Force). Go to MSDN if you want to know more on WMI.

For this blog post, I’ll show key code snippets for you to get started with WMI programming.

First things first, add System.Management using statement. Also make sure you add System.Management.dll reference to your project.

 // Add using statement to access WMI
using System.Management;

To display system information, a management class object is created using Win32_ComputerSystem WMI class which represents a computer system running Windows Operating System. It contains numerous properties and what I’ve shown in the below example is just a few properties. Refer to the .NET documentation for help on other properties.

Following code is used to list the general system information like Manufacturer, Model, System Type, Host Name and Logon User Name.

 // create management class object
ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
//collection to store all management objects

ManagementObjectCollection moc = mc.GetInstances();
if(moc.Count != 0)
{
    foreach (ManagementObject mo in mc.GetInstances())
    {
        // display general system information
        Console.WriteLine("\nMachine Make: {0}\nMachine Model: {1}\nSystem Type: {2}\nHost Name: {3}\nLogon User Name: {4}\n",
                          mo["Manufacturer"].ToString(),
                          mo["Model"].ToString(),
                          mo["SystemType"].ToString(),
                          mo["DNSHostName"].ToString(),
                          mo["UserName"].ToString());
    }
}
//wait for user action

Console.ReadLine();

Now that we’ve looked at how to access general system information using WMI classes. Let’s look at how to interact with the Trusted Platform Module (TPM) and BitLocker Drive Encryption (BDE) using WMI. Security WMI providers allow interaction with TPM and BDE through Win32_Tpm class and Win32_EncryptableVolume class respectively.

Following code shows how to interact with TPM using Win32_Tpm class. We check if TPM is present on the machine by creating a object of Win32_Tpm management class and if TPM is present we make a WMI call and invoke “IsActivated” method to check TPM module is activated on the machine or not.

Below code snippet also shows how to make WMI method calls and report the results back.

             //
            // Accessing TPM-related information
            //
            bool isTpmPresent;
            UInt32 status = 0;
            object[] wmiParams = null;
            // create management class object
            ManagementClass mc = new ManagementClass("/root/CIMv2/Security/MicrosoftTpm:Win32_Tpm");
            //collection to store all management objects
            ManagementObjectCollection moc = mc.GetInstances();
            // Retrieve single instance of WMI management object
            ManagementObjectCollection.ManagementObjectEnumerator moe = moc.GetEnumerator();
            moe.MoveNext();
            ManagementObject mo = (ManagementObject)moe.Current;
            if (null == mo)
            {
                isTpmPresent = false;
                Console.WriteLine("\nTPM Present: {0}\n", isTpmPresent.ToString());
            }
            else
            {
                isTpmPresent = true;
                Console.WriteLine("\nTPM Present: {0}\n", isTpmPresent.ToString());
            }
            if (isTpmPresent) // Query if TPM is in activated state
            {
                wmiParams = new object[1];
                wmiParams[0] = false;
                status = (UInt32)mo.InvokeMethod("IsActivated", wmiParams);
                if (0 != status)
                {
                    Console.WriteLine("The WMI method call {0} returned error status {1}", "IsActivated", status);
                }
                else
                {
                    Console.WriteLine("TPM Status: {0}", status);
                }
            }

 

We’ve looked at how WMI can help you retrieve basic system information and also how to interact with more advanced windows management objects like TPM in a familiar .NET programming language.

That's it for now, Feel free to leave any comments or questions you may have on the blog post. Thank you!