Systems administration is only a line of code away
Imagine writing a single line of code to create a systems administration tool. Using Windows Management Instrumentation (WMI) scripts, you can. For example, as callout A in Listing 1 shows, you can write a single line of code that will display the state of the Windows Alerter service. (Although callout A highlights two lines, VBScript interprets them as only one line of code because of the underscore at the end of the first line. Column widths in the printed publication force us to wrap code.) Callout B shows a one-line script you can use to stop or start the Alerter service.
One-line scripts use WMI monikers to connect, query, and administer systems. WMI monikers have one mandatory component and two optional components. The mandatory component is the prefix "winmgmts:" Note that the colon and quotes are part of the name. One optional component is the security settings, which can include the impersonation level, authentication level, authentication method, authenticating authority, and security privilege. The second optional component is the object path, which might be a path to a remote computer, WMI namespace, or Win32 class. (For additional information about WMI monikers, read the Scripting Solutions article "WMI Monikers," Windows IT Pro, May 2001, http://www.windowsitpro.com, InstantDoc ID 20401.)
Although the object path is an optional component in WMI monikers, it's a mandatory component in one-line scripts. As Figure 1 shows, one-line scripts require four parts. The first part displays the script's output on the screen. The second part is the object path to the WMI class that includes the third part—the unique instance identifier. The last part is the method or property of the class that the script calls. Let's take a closer look at each of the four parts.
Output. The output part of the one-line script writes output to the screen or redirects output to a command-shell window. You can use VBScript's MsgBox function or Windows Script Host's (WSH's) Echo method, Popup method, or StdOut.Write method. Which you use is simply a matter of choice.
WMI object path. Although the WMI object path is an optional component in WMI monikers, it's required for one-line scripts. This component defines the path to the class and the property being read.
Unique identifier. Every class has a property that's the unique identifier (aka key property). For example, the Win32_Service class's unique identifier is the Name property, whereas the Win32_Process class's unique identifier is the Handle property. For a one-line script to read a property of a class, you must include the appropriate unique identifier. For example, to read the State property for the Alerter service in the Win32_Service class, you must include Name as the unique identifier, as callout A in Listing 1 shows. If you're wondering how you're supposed to find out which property is the unique identifier for a class, don't worry. I'll show you how to identify it shortly.
Method or property. The final component of a one-line script is the property or method called by the script. I refer to this component as the action part of the script because it either executes a method or reads a property value.
Now that you know the parts of a one-line script, let's look at how to identify a class's unique identifier and how to write a one-line script that you run from the command line. We'll also look at how to generate one-line scripts programmatically.
Identifying a Unique Identifier
As I mentioned previously, one-line scripts depend on a class's unique identifier. Therefore, you must obtain the class's unique identifier before you can start building a one-line script for the command line.
You can learn some of the classes' unique identifiers from the WMI documentation on the Microsoft Developer Network (MSDN—http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmi_reference.asp). However, the documentation doesn't always list the unique identifier or might list the unique identifier under a slightly different name. For example, the documentation for the Win32_Process class lists Handle as the process identifier rather than the unique identifier.
An easier way to learn a class's unique identifier is to use the GetKeyProperty.wsf script, which Listing 2 shows. To run this script, you use the command
where ClassName is the name of the class for which you want to learn the unique identifier.
GetKeyProperty.wsf is a Windows Script (.wsf) file, which means it's a text document that conforms to XML standards. These types of files provide an easy way to handle script parameters compared with .vbs files in which you have to write your own code to handle command-line parameters. For example, as callout A in Listing 2 shows, the named element defines the /c parameter, which the script uses to get the class name from the command line. Setting the named element's required= attribute to true displays a message box that tells users that the /c parameter is a required when the WScript.Arguments.ShowUsage method is invoked. The WScript.Arguments.ShowUsage method is invoked when the sClassName parameter is empty, as callout B in Listing 2 shows.
After ensuring that the user entered a class name at the command line, GetKeyProperty.wsf uses the GetObject method to connect to the WMI service. With the connection made, the script retrieves an instance of the specified class by calling the Get method, as callout C in Listing 2 shows. The script then retrieves the specified class's collection of properties and stores this collection in the colProperties variable. The script identifies the class's unique identifier by calling the GetKeyProperty function. As callout D shows, this function iterates through each qualifier of each class property and compares the qualifier's name against the word key. When that word is found, the script uses the Exit For statement to exit the loop and assigns the unique identifier's name to the FoundKeyProperty variable.
After the FoundKeyProperty variable has a value, GetKeyProperty.wsf displays the class name and the unique identifier's name. Finally, the script ends by releasing the memory that it used.
Creating a One-Line Script for the Command Line
You can create a one-line script that you'll run from the command line in just three steps. For example, here's how you'd create a one-line script that obtains the service description for a specified service:
- Open an editor, such as Notepad.
- Enter the line of code that Listing 3 shows.
- Save the file as GetService_Description.vbs and close Notepad.
Let's say that you want to use GetService_Description.vbs to get information about the winmgmt service. To run the script, open a command-shell window by selecting Run under the Start menu, typing cmd.exe, then clicking OK. Type the command
cscript /nologo getservice_description.vbs "winmgmt"
and press Enter. (Although this command appears on several lines here, you would enter it on one line in the command-shell window. The same holds true for the other multiline commands in this article.) On execution, the script connects to the WMI service on the local system, queries the Win32_Service class to get information on the winmgmt service, and displays the description.
Generating One-Line Scripts Programmatically
You can use a script to generate one-line scripts so that you don't have to manually write them. GOLS.wsf (short for Generate One-Line Scripts) is an example of such a script. GOLS.wsf identifies the unique identifier for the class you specify, creates a one-line script for the property in which you're interested, writes that code to a text file, and saves that file as a .vbs script.
To use GOLS.wsf, you need to open a command-shell window and, if necessary, change the directory to the folder that contains the script. Then run the command
cscript /nologo GOLS.vbs /c:ClassName /p:PropertyName
where ClassName is the name of the class in which you're interested and PropertyName is the name of the property of interest in that class. Having the script set up this way removes the manual step of editing the script for each WMI class and property you want to generate scripts for.
Listing 4 shows an excerpt from GOLS.wsf. You can download the entire script as well as the other script in this article from the Windows Scripting Solutions Web site. Go to http://www.windowsitpro.com/windowsscripting, enter 47102 in the InstantDoc ID text box, then click the 47102.zip hotlink.
The first task GOLS.wsf performs is to check whether the user included the ClassName and PropertyName command-line parameters. When one or both of the parameters are missing, the script displays the script's usage syntax. When the ClassName and the PropertyName parameters are present, the script assigns them to the sClassName and sPropertyName variable, respectively. The script also creates a FileSystemObject object so that it can later create and save a text file.
The next few sections in GOLS.wsf are similar to those in GetKeyProperty.wsf. GOLS.wsf uses the GetObject method to connect to the WMI service and the Get method to retrieve an instance of the specified class. The script then retrieves the specified class's collection of properties and stores this collection in the colProperties variable. The script uses the GetKeyProperty function to identify the unique identifier.
As Listing 4 shows, after getting the unique identifier's name, GOLS.wsf creates a new text file, writes to that file the one-line script for the property that you specified on the command line, then closes the file. Finally, the script ends by releasing the memory that it used. You'll find the new .vbs file in the directory from which you ran GOLS.wsf.
Let's say you run GOLS.wsf against the Win32_Printer class and the Name property. GOLS.wsf will generate a script named getprinter_name.vbs, which you can test from the command line by passing in an appropriate parameter. For getprinter_name.vbs, you need to enter a printer device ID as the parameter. For example, to test the script against a printer named Brother HL-1240, you'd run the command
cscript /nologo getprinter_name.vbs "Brother HL-1240"
Gather Data the Easy Way
As I've demonstrated, you can manually create one-line scripts to connect to, query, and administer your Windows system. For more convenience, you can use a script like GOLS.wsf to automatically generate one-line scripts. And now that you know how this type of script works, you can even use the same methodology to adapt GOLS.wsf so that it automatically generates script for a specified method in a WMI class.