BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

System Information
.NET 1.1+

Executing WMI Queries

Windows Management Instrumentation provides a number of services that allow gathering of information about the operating system, software and hardware of a machine. Using WQL, this information can be retrieved using familiar, text-based queries.

Windows Management Instrumentation

Windows Management Instrumentation (WMI) is a management technology that is built into Microsoft Windows operating systems. It allows information relating to the operating system, registry, hardware and software to be obtained from the local system or from remote computers over a network. It also allows some settings to be modified and some actions to be performed, again locally or remotely, such as shutting down or restarting a computer.

WMI is usually used in systems management software as it allows monitoring and control of remote computers. It is ideal for the software used by IT departments or support services. However, you can use WMI in any program that would benefit from access to the information it provides. When using the .NET framework, a set of classes is provided to simplify the process and allow querying of WMI information using WQL.

WQL

WMI Query Language (WQL) is a subset of the Structured Query Language (SQL) that is normally associated with querying databases. When used with WMI, it allows querying of WMI classes and instances, which provide a large amount of categorised system information. An example query is shown below. This retrieves all of the available information from the Win32_OperatingSystem class.

SELECT * FROM Win32_OperatingSystem

There are many classes available to query, each returning a specific category of information. The classes are too numerous to describe in this article. You should refer to the WMI Classes reference on MSDN for further details.

Executing WQL Queries Using C#

In the remaining sections of this article I will describe one method of retrieving information from WMI using WQL with C#. The examples provided are not exhaustive as there are other ways to access the system information and additional query clauses. To begin, create a new console application and add a reference to the System.Management assembly. This standard library contains the types that are required to access WMI. All of the classes that we require are in the System.Management namespace, so add the following using directive to the code:

using System.Management;

The first class that we will use from the namespace is ObjectQuery. Instances of this class are used to represent WQL queries. A query can be defined in a string and passed to a parameter of the type's constructor. For example, to define the query described earlier, add the following code:

ObjectQuery wql = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");

Next we need a ManagementObjectSearcher instance. This class is used to execute queries and return the results as a collection of management objects. A simple way to initialise the new instance is to pass the previously prepared query as the single constructor argument, as follows:

ManagementObjectSearcher searcher = new ManagementObjectSearcher(wql);

The ManagementObjectSearcher class includes the Get method, which executes the query and returns the results. Add the code below to execute the query.

ManagementObjectCollection results = searcher.Get();

Once you have the ManagementObjectCollection object that contains the results of the query, you can iterate through the results using a foreach loop. Each item in the collection is a ManagementObject object that contains a number of values that have been returned. To obtain the values you can provide the attribute name to the object's indexer. All attribute values are returned as objects but can be converted to strings or cast to other types in most cases.

To see some of the results of the query, add the foreach loop shown below. This cycles through all of the results, though in this case there will be only one item in the collection, and outputs three pieces of system information. In this case, the name and organisation with which Microsoft Windows was registered, and the name of the operating system are shown.

foreach (ManagementObject result in results)
{
    Console.WriteLine("User:\t{0}", result["RegisteredUser"]);
    Console.WriteLine("Org.:\t{0}", result["Organization"]);
    Console.WriteLine("O/S :\t{0}", result["Name"]);
}

Filtering Results

The WQL query language includes various elements of SQL. One of the key items is the ability to filter the information that is returned. We can specify which data to return in a similar manner to defining the column list in a SQL query. We can also apply filters with a WHERE clause. To demonstrate, first try running the following code. This returns all of the information about the currently installed local drives, including floppy disks, hard disks and optical media. Although all of the information is retrieved, only the drive letter and volume name are outputted.

ObjectQuery wql = new ObjectQuery("SELECT * FROM Win32_LogicalDisk");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wql);
ManagementObjectCollection results = searcher.Get();
foreach (ManagementObject result in results)
{
    Console.WriteLine(string.Format("{0}-{1}", result["Name"], result["VolumeName"]));
}

As we only need two elements of the available information, we can modify the query so that only those items are retrieved. The following query shows this. Try substituting this query in the previous code sample and running the program again. The results should be identical, as we have still obtained enough information to display.

SELECT Name, VolumeName FROM Win32_LogicalDisk

Adding the list of required items filtered the "columns" that were returned. To filter the "rows", we can add a WHERE clause. This defines a predicate and only returns the items from the WMI data where the predicate is true. We can demonstrate this with the following query, which adds a WHERE clause to specify that only drives with a DriveType of 3 should be retrieved. These are local hard disk drives.

SELECT Name, VolumeName FROM Win32_LogicalDisk WHERE DriveType=3
9 October 2010