Windows Management Instrumentation in C#

Windows Management Instrumentation (WMI) helps to ease administrative enterprise system management tasks such as starting and stopping remote services and rebooting a remote machine. With WMI you can create management applications to control and modify operating system elements contained in systems, applications, networks, and devices such as CPUs, disks, memory, services, and network status. But you are required to have authorization to perform the relevant tasks. All of the .NET WMI classes live in the System.Management namespace. 

Although WMI is a great feature, it may prove to be a security risk because intruders may use WMI objects accidentally or maliciously to their advantage without your control. If you have no intention of using the features of WMI on your network, you may want to disable it on certain computers. Note that all of the WMI operations are controlled by the Windows Management Instrumentation Windows service on computers on which Windows NT, 2000, or XP is installed. 

WMI is an interface designed to interact with parts of the Windows operating system. Without it we would have to address administrative tasks individually rather than remotely and automatically. WMI works with the Common Information Model Object Manager (CIMOM). CIMOM is a database of objects representing different operating system elements such as applications and services. CIMOM provides a common interface to these operating system elements. 

WMI is the Microsoft implementation of Web-Based Enterprise Management (WBEM). WBEM is an industry initiative to develop a standardized technology for accessing management information such as details about the state of system memory, inventories of currently installed client applications, and other information about client status in an enterprise environment. WMI enables the Common Information Model (CIM) designed by the Distributed Management Task Force (DMTF) to represent systems, applications, networks, and other managed components. CIM can model every component in the managed environment, regardless of the data source location. As well as data modeling, WMI provides a powerful set of basic services that include query-based information retrieval and event notification. 

CIM is a model for describing overall management information in a network or enterprise environment. It comprises both a specification and a schema. The specification defines the details for integration with other management models, while the schema provides the actual model descriptions. 

More details about WBEM, CIM, and other DMTF standards are available at http://www.dmtf.org/standards/. 

WMI can help you accomplish a horde of tasks:

  • Control remote workstations and severs in bulk from your own workstation
  • Audit or configure Windows 2000 systems automatically and remotely
  • Centrally archive Windows NT event logs
  • Block server render down with WMI event notification
  • Integrate WMI with Active Directory
  • Manipulate remote processes and files
  • Identify, list, and adjust all the services on a server
  • Identify, list, and adjust all the NT file system partitions on a server that have less than 10 percent free space
  • Execute a backup on a Microsoft Exchange Server machine and then dump the transaction log
  • Use any existing WMI method to launch a program on a server remotely
  • Set up an event consumer that subscribes to a system that watches for a specific event in the system log and sends an SMS (System Management Service) or e-mail message when that event occurs
  • Reconfigure an event consumer to request a system event whenever a server's CPU use exceeds 85 percent

WMI has a query language named WQL (Windows Management Instrumentation Query Language). WQL is a subset of the American National Standards Institute Structured Query Language (ANSI SQL) with small semantic changes to support WMI. For example, you can perform a WQL query such as "SELECT * FROM Win32_Processor" on the root\CIMV2 namespace path. 

The code samples in Listings 21.39 through 21.46 demonstrate various ways to employ WMI in the .NET Framework. 

Listing 21.39: Retrieving Local WMI Objects 

ManagementObject mo = new ManagementObject("Win32_Share.Name=\"X$\"");
mo.Get();
Console.WriteLine("Win32_Share.Name=\"X$\" path is {0}", mo["Path"]);

Listing 21.40: Retrieving Remote WMI Objects

ManagementPath path = new ManagementPath();
path.Path = "Win32_Share.Name=\"X$\"";
path.Server = "MCBcomputer";
path.NamespacePath = @"root\CIMV2";
ManagementObject mo = new ManagementObject(path);
Console.WriteLine("Win32_Share.Name=\"X$\" path is {0}", mo["Path"]);

Listing 21.41: Enumerating WMI Objects

ManagementClass mc = new ManagementClass("Win32_Share");
ManagementObjectCollection mcCollection = mc.GetInstances();

foreach (ManagementObject mo in mcCollection)
{
    Console.WriteLine("'{0}' path is '{1}'", mo["__RELPATH"], mo["Path"]);
}

Listing 21.42: Performing Queries on WMI Objects

ManagementObjectSearcher query =
new ManagementObjectSearcher(
"SELECT * FROM Win32_Service WHERE Started=true");
ManagementObjectCollection queryCollection = query.Get();

foreach (ManagementObject mo in queryCollection)
{
    Console.WriteLine("Service: '{0}'", mo["DisplayName"]);
}

Listing 21.43: Calling a WMI Object Method to Create TEMP Share to C:\TEMP

ManagementClass mc = new ManagementClass("Win32_Share");

// Get the methods in parameters
ManagementBaseObject inParams =
mc.GetMethodParameters("Create");

// Setup method parameters
inParams["Name"] = "TEMP";
inParams["Path"] = @"C:\TEMP";
inParams["Type"] = 0;
ManagementBaseObject outParams =
mc.InvokeMethod("Create", inParams, null);

// inspect out parameters for return value
uint retVal = (uint)outParams["ReturnValue"];

Listing 21.44: Managing Remote WMI Connections

ConnectionOptions options = new ConnectionOptions();
options.Authentication = AuthenticationLevel.Call;
options.Impersonation = ImpersonationLevel.Impersonate;
options.EnablePrivileges = true;
options.Locale = "MS_409";
options.Username = @"MCBDOMAIN\mcb";
options.Password = "password";
ManagementScope ms =
new ManagementScope(@"\\MCBcomputer\root\CIMV2", options);

// Explicit connection to WMI namespace
ms.Connect();
ManagementObject mo = new ManagementObject("Win32_Share.Name=\"X$\"");

// Reuse existing connection for this
// ManagementObject retrieval
mo.Scope = ms;

// Connection scope used when object is retrieved here!
mo.Get();
Console.WriteLine("Win32_Share.Name=\"X$\" path is {0}", mo["Path"]);

Listing 21.45: Rebooting a Remote Computer with WMI (reboot1.cs)

using System;
using System.Management;

class RemoteWMI
{
    static void Main(string[] args)
    {
        //Connect to the remote computer
        ConnectionOptions co = new ConnectionOptions();
        co.Username = "mcb";
        co.Password = "password";
        ManagementScope ms = new ManagementScope(@"\\MCBcomputer\root\cimv2", co);

        //Query remote computer across the connection
        ObjectQuery oq = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
        ManagementObjectSearcher query1 = new ManagementObjectSearcher(ms, oq);
        ManagementObjectCollection queryCollection1 = query1.Get();

        foreach (ManagementObject mo in queryCollection1)
        {
            string[] ss = { "" };
            mo.InvokeMethod("Reboot", ss);
            Console.WriteLine(mo.ToString());
        }
    }
}

Listing 21.46: Clearing the Application Logs

using System;
using System.Management;

namespace ClearEventLog
{
    class ClearEventLog
    {
        [STAThread]

        static void Main(string[] args)
        {
            try
            {
                // create conncetion options
                ConnectionOptions options = new
                ConnectionOptions();
                options.Authentication = AuthenticationLevel.Call;
                options.Impersonation = ImpersonationLevel.Impersonate;
                options.EnablePrivileges = true;
                options.Locale = @"MS_409"; // LocaleID
                options.Username = @"mcb"; // username for connection
                options.Password = @"mindcracker"; // password for the
                // create management scope for CIM/WMI
                ManagementScope ms = new 
                ManagementScope(@"\\MCBComputer\root\CIMV2",
                options);

                // query Application event log
                ManagementObjectSearcher query1 =
                new ManagementObjectSearcher(@"select * from Win32_NTEventLogFile where LogfileName='Application'");

                // get the query collection
                ManagementObjectCollection queryCollection1 =
                query1.Get();

                // clear the Application event log

                foreach (ManagementObject mo in queryCollection1)
                {
                    mo.Get();
                    ManagementBaseObject inParams =
                    mo.GetMethodParameters("ClearEventLog");
                    ManagementBaseObject outParams =
                    mo.InvokeMethod("ClearEventLog", inParams, null);
                    mo.Dispose();
                    Console.WriteLine();

                    if (0 == (int)(uint)
                    (outParams.
                    Properties["ReturnValue"].Value)
                    )
                        Console.WriteLine("cleared!");
                    else
                        Console.WriteLine("not cleared!!!");
                }
            }

            catch (Exception e)
            {
                Console.WriteLine("Error: {0}", e.ToString());
            }
        }
    }
}

Conclusion

Hope this article would have helped you in understanding Windows Management Instrumentation in C#. See other articles on the website on .NET and C#.


Similar Articles