Ready to Start Your Career?

WMI and C# - Part One

beller0ph0n 's profile image

By: beller0ph0n

November 27, 2017

WMI and C# - Part One

In the series of articles titled "WMI and C#" we will learn how to harness the power of C# and WMI. In this first article, we will learn what is WMI and how to connect to it remotely using C#.

WMI – what is that?

WMI stands for Windows Management Instrumentation and it is a technology which has been a part of Microsoft Windows operating systems since Windows NT 4.01 and Windows 95. Regardless of its “age”, not many people know much about it. The main purpose of WMI is to provide a system administrator with an easier way to do administrative management tasks such as starting or stopping remote services and rebooting or shutting down a remote device, just to name a few. Basically, WMI is an interface designed to interact with certain parts of Microsoft Windows operating system. It works in conjunction with Common Information Model Object Manager – CIMOM, which is basically a database of objects representing operating system elements such as applications or services. Using WMI system administrator could also create management applications which have the ability to control and modify certain operating system elements. However, in order to be able to perform relevant tasks via WMI system administrator needs to provide valid credentials.Even though WMI is an excellent technology (which can most certainly be of great help to the system administrator) in recent years we are witnesses of its misuse by the people with malicious intents (not using the term hackers intentionally). Because of the fact that malicious user may use WMI objects to obtain sensitive information about end device (more or less without the end users control) it may prove to be a security risk. Due to that fact, Microsoft suggests disabling WMI on critical assets for added protection. All of the WMI operations are controlled by the Windows Management Instrumentation service and starting from Microsoft Windows Vista WMI uses Event Tracing for Windows – ETW instead of WMI log files.So you may ask yourself how do I use it? Well, that is where all the fun begins.

WMI and .NET

In order to make use of WMI, we will be using .Net framework and C#, but before we start seeing some code examples we need to learn how to communicate with WMI via .Net.Previous versions of WMI used System.Management namespace which contained all of the .Net WMI classes. These days, all .Net WMI classes are contained within Microsoft.Management.Infrastructure namespace including those used to establish remote connections to WMI. If you take a look at MSDN you will see that Management Infrastructure API contains interfaces, enumerations, structures, and unions used to develop native WMI providers and clients. So the first thing we will need in order to communicate with WMI using C# is to use a valid namespace which is done via using keyword.Code:using Microsoft.Management.Infrastructure;When we connect to WMI remotely, using classes inside Microsoft.Management.Infrastructure namespace we are basically using DCOM as the underlying remote mechanism. It is necessary that WMI remote connections comply with DCOM security requirements for impersonation and authentication. By default, a scope is bound to the local device and the RootCIMv2 system namespace. Does that mean that we can only connect to WMI using current logged users credentials? The answer to that question is a definitive NO. The scope can be changed meaning system administrator can specify computer, domain, and WMI namespace that he wants to access. Among these, system administrators could also set authority, impersonation and credentials options just to name the few.When using C# this can be achieved by initializing a new instance of ConnectionOptions class, defined within System.Management namespace. Here we can see three different constructors we could use for ConnectionOptions class with the first one being the default constructor:Code:public ConnectionOptions();public ConnectionOptions(string locale, string username, string password, string authority, ImpersonationLevel impersonation, AuthenticationLevel authentication, bool enablePrivileges, ManagementNamedValueCollection context, TimeSpan timeout);public ConnectionOptions(string locale, string username, SecureString password, string authority, ImpersonationLevel impersonation, AuthenticationLevel authentication, bool enablePrivileges, ManagementNamedValueCollection context, TimeSpan timeout); If we, for example, want to connect to WMI remotely using alternate credentials (meaning we won't be using current logged users credentials) we could do the following: Code:var options = new ConnectionOptions();options.Username = “beller0ph0n”;options.Password = “mypa$$w0rd”;options.Authority = = $"NTLMDOMAIN:MYDOMAIN"; var remoteDevice = “computerA”; By doing this we are saying that we want to use domain username beller0ph0n with the password being mypa$$w0rd and the domain name MYDOMAIN for remote connection to WMI on computerA.What we need to do next is specify to which device we want to connect and with what credentials which can be achieved by initializing a new ManagementScope class. Code:var myScope = new ManagementScope($@"\{remoteDevice}rootCIMV2", options); Next, we need to create a new WQL (which is, in fact, SQL for WMI) query stating what information we want to retrieve from a remote device. Lastly, we will need to initialize a new ManagementObjectSearcher class by providing its constructor with our scope and our query. Code:var query = new ObjectQuery("SELECT Caption,Description,LastBootUpTime,Version,ProductType FROM Win32_OperatingSystem");var searcher = new ManagementObjectSearcher(myScope, query); From this moment on we can use try catch block and loop through results using for each loop. Code:try{foreach (ManagementObject obj in searcher.Get())      {            // process each object      }}catch (Exception as error){      // process errors} In the articles to come, we will explore WMI even further so stay tuned and don't hesitate to ask questions in the comments section. Best wishes, until the next time!
Schedule Demo