Executive Summary:

As a command shell and scripting environment, Windows PowerShell is quickly proving to be one of the most valuable tools available to system administrators. PowerShell particularly shines in its support for Windows Management Instrumentation (WMI), a management technology built into Windows OSs. WMI provides a comprehensive structure for accessing information on local and remote Windows computers and managing those computers. (You can find more information about WMI at http://www.microsoft.com/whdc/system/pnppwr/wmi.)

With PowerShell, you can take advantage of the full range of WMI capabilities. And the best part is that in many cases, you need to enter only a single line of code to access WMI. These “one-liners” can return a wealth of information and can simplify many of your administrative tasks. In addition, the procedures for working with WMI in PowerShell are consistent across the WMI spectrum, making it easier to adapt what you learn to other areas.

Your Basic Command: Get-WmiObject
The key to WMI access in PowerShell is the get-wmiobject cmdlet, which lets you access any WMI class in any WMI namespace on a system. Each class provides access to a complete set of related information about a particular system. For example, the Win32_OperatingSystem class gives information such as the OS name, build number, service pack version, system directory, and many other details.

A good place to start is to learn how to retrieve the online help available for the get-wmiobject cmdlet. The following PowerShell command calls the basic help file:

help get-wmiobject

In this command, the help keyword is actually a built-in alias for the get-help cmdlet. You can retrieve the same results by entering the following command:

get-help get-wmiobject

Figure 1 shows the results returned by either of these statements. In addition to providing basic information about the cmdlet, the help file also provides commands that point you to additional resources. One of these commands, shown in the following statement, lets you retrieve more detailed information about the get-wmiobject cmdlet:

help get-wmiobject -detailed

Finding and Accessing Classes
One bit of information you might have gleaned from the detailed help file, particularly in the examples it gives, is that you must specify a WMI class if you want to access specific system information. If you’ve worked with WMI or created scripts that access WMI, you’re probably already familiar with the various classes available to particular namespaces. However, a namespace can include many classes, so unless you know the name of the class you want to access, you need a way to identify those classes.

In PowerShell, the easiest way to retrieve a list of classes is to use the following command:

get-wmiobject -list

The command uses the -list parameter to retrieve a list of the classes. By default, the command retrieves the list from the root\cimv2 namespace on the local computer. Figure 2 shows a sample of results returned by the command.

Many of the WMI classes that you’ll want to access are within the root\cimv2 namespace. However, you can specify any namespace when you run the get-wmiobject cmdlet. The following statement retrieves a list of classes in the root\microsoft\sqlserver\computermanagement namespace:

get-wmiobject -list -namespace `
 root\microsoft\sqlserver\computermanagement

Note that the backtick (`) at the end of the first line indicates that the command continues on the next line. You can also put the entire command (without the backtick) on one line.

In addition to specifying a namespace, you can also specify the computer on which to target your PowerShell command. You can use the following statement to retrieve a list of classes from the server05 computer:

get-wmiobject -list `
-computer server05 -namespace `
root\microsoft\sqlserver\computermanagement

Filtering Your Results
In PowerShell, whenever you call the get-wmiobject cmdlet, you can specify a namespace, a computer, or both. You can also send the results of a get-wmiobject command down the PowerShell pipeline to another command. This ability is especially useful if you want to limit the results returned by your statement. For example, suppose you want to see a list of classes that contain the word “service.” You can create a statement such as the following:

get-wmiobject -list | where `
\{$_.name -like "*service*"\}

In this example, the list of classes is sent down the pipeline to a where-object command (represented by the where alias). The cmdlet filters the list so that only classes whose name contains service are returned by the statement. Figure 3 shows a sample of results returned from running this statement. Notice that each class listed contains the word service.

From this filtered list, you can more easily identify a particular class that might be useful to you. For example, you might want to use the Win32_Service class to retrieve information about the services running on a system. After you’ve identified a class, you simply call the get-wmiobject cmdlet along with the -class parameter and the class name as a value for that parameter, as shown in the following example:

get-wmiobject -class win32_service

As Figure 4 shows, the statement returns a list of services running on your system. Notice that each service listing includes details about the service, such as the service name, state, and status.

When you specify the -class parameter in a get-wmiobject command, you don't need to include the name of the parameter, only the class name. Therefore, the following command returns the same results as the preceding example:

get-wmiobject win32_service

Regardless of whether you include the parameter name in the command, you can pipe the result of the command to other commands, as you saw earlier. For example, suppose you want to see only a list of service names, without all the other details. You can pipe the command results to a select-object command, as shown in the following example:

get-wmiobject win32_service `
 | select name

Note that the select keyword is a built-in alias for the select-object cmdlet. Because the cmdlet specifies the name property, only those values (the names of the services) are returned when you run the statement. Figure 5 shows the much simpler list the statement now returns.

By taking advantage of the PowerShell pipeline, you can retrieve very specific information, making it easier to locate the data you require. You can then use the information you retrieve from one command to set up another command. For example, suppose you want to retrieve information about the Browser service. You can use the following statement to retrieve information:

get-wmiobject win32_service `
-filter "name='browser'"

As you can see, the get-wmiobject command again specifies the Win32_Service class. But this time, the command also includes the -filter parameter, which specifies that the results should contain only the service named Browser. As Figure 6 demonstrates, the statement returns the values of the ExitCode, Name, ProcessId, StartMode, State, and Status properties.

Methods and Properties
Although the information Figure 6 displays is useful, it's only part of the results that are available when you call a WMI object. In fact, each WMI object you retrieve contains a set of properties and methods that you can access whenever you call that object. To see the properties and methods that an object supports, you can use the following statement:

get-wmiobject win32_service `
-filter "name='browser'" | gm

This statement uses the gm alias to call the get-member cmdlet. Member refers to the object’s collection of methods and properties. As the cmdlet's name suggests, it returns a list of members for that specific object, as Figure 7 shows. You’ll no doubt use this cmdlet regularly in PowerShell to learn what properties and methods you can call. For example, one of the properties returned by the preceding statement is DisplayName. This property stores the service name that is displayed in the Services administration tool. You can use a get-wmiobject command to call the DisplayName property, as shown in the following statement:

(get-wmiobject win32_service -filter `
 "name='browser'").displayName

As you saw in earlier examples, the get-wmiobject command retrieves a WMI object for the Browser service on the local computer. The command is then enclosed in parentheses so that it's treated as a single unit. (You can also put the results in a variable, then call the variable.) After the closing parenthesis, you simply add a period and then the property name (.displayName). Figure 8 shows results similar to what you'll receive when you run the statement. In this case, the value of the DisplayName property is “Computer Browser.”

You might want to see a list of an object’s methods without having to view all the members of that object. The easiest way to do this is to modify your PowerShell statement:

get-wmiobject win32_service `
-filter "name='browser'" | `
gm -member method

In the statement, you simply add the -member parameter—a shortened version of the -memberType parameter—to the get-member command and specify “method” as the parameter value. Because no other parameters begin with member, you can use the shortened version and PowerShell will know which parameter to use. As Figure 9 shows, your statement results now include only methods.

Notice that the list includes the StopService method, which is used for stopping the service. You can call this method just like you called a property:

(get-wmiobject win32_service -filter `
"name='browser'").stopService()

When you run this statement, PowerShell calls the method on the WMI object, which in turns stops the service. You can verify whether the service has stopped by running the following command:

get-wmiobject win32_service `
-filter "name='browser'"

The State property indicates whether the service is running, as Figure 10 shows. If you want to restart the service, simply call the StartService method, as shown in the following statement:

(get-wmiobject win32_service `
-filter "name='browser'").startService()

Building from the Basics
Of course, the example one-liners shown in this article represent only a tip of the iceberg with regard to how you can use PowerShell to interact with WMI. At the same time, the examples demonstrate the basic concepts that apply to most of your WMI-related tasks. As you’ve seen, the key is to call the get-wmiobject cmdlet along with the appropriate class and parameters. In other words, just plug in the right values, and PowerShell does the rest.