WMI (Windows Management Instrumentation) is a component of the Microsoft operating system that allows you to monitor virtually every piece of the system (either locally or remotely) as well as control the windows operating system. This technology is particularly useful to professionals such as system administrators and database administrators who need to monitor and change client machines on a daily basis.
WMI consists of several pieces that allow it to manage systems. All parts of the operating system are managed through COM by a provider that talks to WMI. WMI also has a repository and a Windows Management service that manages reading and writing information between the provider and the repository. And WMI has this cool query language (WQL) that allows you to query the Windows Management service about different providers. WQL looks a heck of a lot like SQL so it is easy to learn.
.NET and WMI
If you look at the WMI API you probably will fall off your seat when you see how vast and complicated it seems. Also, it's not obvious from raw COM how to use it. Luckily, Microsoft decided to simplify the process by creating several namespaces and RAD solutions to ease the use of this Goliath (yet powerful) feature. One of the RAD facilities provided by the net is the server explorer WMI extensions. You'll need to download the server explorer extensions if they are not already installed). These extensions allow you to drag and drop WMI Classes into your .NET project and create wrappers to work with these objects directly. (Believe me, you don't want to create these wrappers yourself). Once the wrapper is created, using these classes is simple and painless.
Reading the Printer Driver through WMI
I thought I would step through a quick example of using the Server Explorer Extensions before showing you some of the cool System.Management namespace classes. Begin by opening the server explorer in Visual Studio.NET and expanding the Management Classes node. Then expand the Printers node and drag the printer into your form. This will generate the wrapper class you will need to query and control the printer.

Figure 1 - Viewing WMI classes in the Server Explorer
To use this class simply construct the wrapper class object and utilize its methods and properties. Below is the C# sample code that shows the printer's name and resolution:
Listing 1 - Querying the printer through WMI
- Printer p = new TestWMI.ROOT.CIMV2.Printer("Epson 880C");
- MessageBox.Show(p.Caption);
- MessageBox.Show(p.HorizontalResolution.ToString());
- MessageBox.Show(p.VerticalResolution.ToString());
.NET WMI Classes
.NET also provides some great classes for easing the pain in working with WMI. The System.Management namespace allows you to work with the WMI API while hiding all the complex architectural details. Below is a summary of some of the useful classes in this namespace:
| Class Name | Description |
| ManagementBaseObject | The base Windows Management Object containing the basic elements of a Windows Management Object |
| ManagementObject | Represents a Windows Management Object. Allows you to access properties and methods of a particular WMI Object. This inherits properties of ManagementBaseObject |
| ManagementClass | Represents a Windows Management Class and can be used to access the properties of a particular class. This inherits from ManagementObject. |
| ManagementObjectCollection | Contains a collection of ManagementBaseObjects (which can either be ManagementObjects or ManagementClasses) |
| ManagementQuery | Base class for queries |
| ObjectQuery | query object for querying instances and classes. Inherits Management Query. |
| EventQuery | Query object for querying events in WMI. Used with event watchers. |
| ManagementScope | Describes the scope of which management operations are performed. Generally, the scope is a WMI namespace such as root\cimv2 |
| ManagementEventWatcher | Used to monitor events coming through the WMI service. This object can be constructed using a certain ManagementScope and filtered on an EventQuery. |
| ManagementObjectSearcher | Used to retrieve a collection of ManagementObjects based on a particular query. |
Monitoring the Event Log
Using the WMI classes, we can now monitor the event log. The strategy we will take to monitor the event log will be to construct a ManagementEventWatcher and subscribe to an event that queries whenever a particular event log file changes. In order to monitor the event log remotely, we will specify the WMI scope on a remote machine on our network.
Listing 2 is the class we will use to monitor the event log. This class contains a ManagementEventWatcher to do the monitoring. The ManagementEventWatcher is constructed with a ManagementScope object to allow us to connect to the WMI repository on another machine. It also is constructed with an EventQuery object that specifies the Win32_NTLogEvent class in order to look for changes in the log file. The EventQuery is passed a WQL string that filters only events occurring in the "CaptureLog" file in our Event Log. The event watcher subscribes to the eventlog event and handles the event in an eventhandler delegate.
Listing 2 - Class to watch events on the remote event log
- namespace WMIRemoteEventLogDetection {
- /// <summary>
- /// Summary description for MyWMIWatcher.
- /// </summary>///
- [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name = "FullTrust")]
- [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name = "FullTrust")]
- public class WMIEventLogWatcher {
- EventLogHandler _handler = null;
- System.Management.ManagementEventWatcher _watcher = null;
- public MyWMIWatcher() {
- // Although connection information is not used in this example, I'll show you how to construct it here
- //Connection credentials to the remote computer - not needed if the logged in account has access
- ConnectionOptions oConn = new ConnectionOptions();
- oConn.Username = "sa";
- oConn.Password = "hockeypuck";
- // Connect to the remote machine's WMI repository
- System.Management.ManagementScope oMs = new System.Management.ManagementScope(@\\ RemoteMachine\ root\ cimv2);
- // connect it
- oMs.Connect();
- // construct the watcher object from the scope and the query
- _watcher = new ManagementEventWatcher(oMs, new EventQuery("SELECT * FROM __InstanceCreationEvent WHERE TargetInstance ISA 'Win32_NTLogEvent' and TargetInstance.LogFile = 'CaptureLog'"));
- // connect an event handler to the event returned when the event log changed
- _handler = new EventLogHandler();
- _watcher.EventArrived += new EventArrivedEventHandler(_handler.Arrived);
- }
- public void Start() {
- //Start watching for events
- _watcher.Start();
- Console.WriteLine("Started...");
- }
- public class EventLogHandler {
- public void Arrived(object sender, EventArrivedEventArgs e) {
- Console.WriteLine("Event Log Changed = ");
- // Get the Event object and display it
- PropertyData pd;
- if ((pd = e.NewEvent.Properties["TargetInstance"]) != null) {
- ManagementBaseObject mbo = pd.Value as ManagementBaseObject;
- if (mbo.Properties["Message"].Value != null) {
- Console.WriteLine(mbo.Properties["Message"].Value);
- }
- }
- }
- }
- }
- }
In order to run the class shown above used to monitor the event logger, simply construct the class and call Start. When the event log changes in the CaptureLog file, the event handler Arrived will be entered. You can access the ManagementBaseObject for the event logger on the remote machine through the event argument in the event handler. This object allows you to pull information out of the event log entry such as Message or EventCode. Below is the complete Log Event class that shows you all the properties you can access from the ManagementBaseObject.
Listing 3 - Log Event Class and its properties
- class Win32_NTLogEvent {
- uint16 Category;
- string CategoryString;
- string ComputerName;
- uint8 Data[];
- uint16 EventCode;
- uint32 EventIdentifier;
- uint8 EventType;
- string InsertionStrings[];
- string Logfile;
- string Message;
- uint32 RecordNumber;
- string SourceName;
- datetime TimeGenerated;
- datetime TimeWritten;
- string Type;
- string User;
- };
You can get documentation for all the classes and properties in WMI from MSDN. This is a useful reference, because otherwise, short of generating the classes from the server explorer extensions, it's difficult to know how to access information inside the Management Objects.
Security
In order to access WMI on a remote machine, you'll need to alter the WMI security on the remote computer and restart the WMI service. This can all be accomplished through the Computer Management Console in the control panel shown in Figure 2. Right-clicking on the WMI Control of the Services and Application section allows you to access the WMI Properties.

Figure 2- Computer Management Console in the System Administration Tools of the Control Panel
This will bring up the WMI Control Properties dialog shown in Figure 3. This dialog will allow you to change the security on the particular WMI node you are trying to access. In this case, we want to change the security on the CIMV2 node to enable remoting.

Figure 3- WMI Control Properties Dialog (Security Tab)
Clicking the security button opens a dialog that allows us to change security on the computer to enable remoting as shown in figure 4. We will give remoting access to everyone in this case.

Figure 4 - Allow Everyone Remoting Access to WMI
Now we simply restart the WMI service in the computer management console as shown in figure 5 and then we are ready to run our event log event trapper.

Figure 5 - Restarting the WMI Service
The event log trapper is initially started through a button in our form that simply calls start and sits and watches for events triggered by the query. If an event occurs, the event handler in the MyHandler class writes out the message to the console associated with the event written in the event log.
Listing 4 - Starting the EventLog Watcher with a button click
- MyWMIWatcher _watcher = new MyWMIWatcher();
- private void button1_Click(object sender, System.EventArgs e)
- {
- _watcher.Start();
- }
Conclusion
WMI is a powerful interface that can be used to monitor event logs, check disk space, or monitor peripherals. Through .NET, implementing WMI becomes a lot easier through Server Explorer Extensions and the System.Management and System.Management.Instrumentation interfaces. If you use WMI remotely, you may need to enable some security settings in the WMI properties window using the Computer Management Console. Have fun experimenting with WMI, another instrument at your disposal in .NET.

Eddie BritoPosted Feb 24, 2013, 11:37 AM
Hi, my name is Edi Brito Im from Mexico City, and I have some troubles with a printer log conection, I really want to know how I create it, and how to show log registers from printers, thanks and it's great that you share this pages like this one...greatfull
arsenium arseniumPosted May 22, 2010, 1:27 PM
Very bad code
aay jayPosted May 8, 2009, 11:52 AM
Hi Mike, I like your article, some how I'm getting error when I try to use Please send me zip file for above code thanks, aay
Nilesh kbPosted Feb 1, 2008, 2:47 AM
can we access taskmager of remote machine through wmi
Deepa DhulipallaeditedPosted Nov 16, 2007, 6:19 AMEdited Nov 16, 2007, 6:22 AM
Hi. I have granted the privileges to the users as you specified above in order to access the WMI on the remote machine ..But still couldn't able to connect to it as its throwing an error such as "Access is denied"... Please let me know does it require any other privileges to access the WMI... Code: System.Management.ManagementScope oMs = new System.Management.ManagementScope("\\\\MyServerName\root\cimv2); oMs.Connect(); Connection method failed -- throws an error.... ("Access is denied") Please do the needful at the earliest... Thanks in Advance, Deepa.
david_cool721Posted Oct 5, 2007, 4:07 AM
I cant seem remote my remote machine. why? please advise
saime aleyPosted Sep 6, 2007, 3:56 AM
Dear Mike, I am having problem with watcher, actually I am looking for solution witch which I can get current IP address, and it refreshes with system event. As it is time and CPU consuming to poll . Could you please give me example. I am using C# Regards, Saime
revati yeolekarPosted Feb 20, 2007, 4:24 AM
i m creating my own wmi provider..to monitor chat application.i m not getting how ti define function for my own wmi provider in visual c# .net..hoew to create wmi provider n its method..plz help me