Export (0) Print
Expand All

Returning All Properties of Selected Instances of a Class

Microsoft® Windows® 2000 Scripting Guide

The two WQL query types demonstrated so far return information for each instance of the specified class. However, you will often want to work with only a subset of instances. For example, you might want information only about services that are stopped, or only about hard disks (and not floppy disk drives or CD-ROM drives). In a situation like this, it can be inconvenient to return all the instances of a class. If you returned a list of all the services, you would need to individually check each one to see whether it was stopped before you echoed information about the service. Although this kind of checking can be included within a script, you never want to write more code than absolutely required. More code means more chances for making a mistake.

At other times, returning all instances of a class rather than selected instances of a class can make a significant difference. For example, consider a Windows 2000based test computer with approximately 48,000 events recorded in its three event logs (Application, System, and Security). A script designed to return only the 4,000 events recorded in the System event log completed its task in 18 seconds.

And how long did it take to return all the events from all the event logs? No one knows. After 14 minutes, and after returning 41,592 events, the script exhausted available memory and crashed.

Note

  • It is bad enough that the script could not complete its task. Even worse, however, is the fact that, although the script stops, WMI continues running the query. In this case, that brought the entire system to a near-standstill. The only way to stop a "runaway" query such as this is to stop and then restart the WMI service.

In this case, returning only the events in the System event log made a dramatic difference. Likewise, a script that returned only those instances in the System event log that had EventCode 532 completed in just a few seconds.

To return a selected set of instances, you need to append a WHERE clause to the SELECT query. The generic representation of such a query looks like this:

"SELECT * FROM ClassName WHERE PropertyName = PropertyValue

Note

  • This generic representation is not entirely accurate. You are not restricted to using only the equals sign (=). You can also use other operators, such as less than (<), greater than (>), and not equal to (<>).

For example, this query returns only events recorded in the System event log:

"SELECT * FROM Win32_NTLogEvent WHERE Logfile = 'System'"

In the preceding query:

  • Win32_NTLogEvent is the WMI class being queried.

  • Logfile is the class property.

  • System is the value of the Logfile property. Only events that have a Logfile property equal to System are returned by the query.

When writing queries that use WHERE clauses, you must correctly format the property value. The formatting you use will vary depending on whether the value is a string, a number, a Boolean value, or a variable.

Using Strings in WHERE Clauses

You might have noticed that, in the preceding query, the value (System) was enclosed within single quote marks. This is required anytime the value of the WHERE clause is a string. For example, the following script returns the names of all of the services on a computer that are stopped. In this query:

  • Win32_Service is the WMI class being queried.

  • State is the class property.

  • Stopped is the value of the State property. Because Stopped is a string value, it is enclosed in single quote marks.



strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colServices = objSWbemServices.ExecQuery _
    ("SELECT * FROM Win32_Service WHERE State = 'Stopped'")
For Each objService In colServices
    Wscript.Echo objService.Name
Next

Using Numbers and Boolean Values in WHERE Clauses

When you use numbers or Boolean values (such as True or False) in a WHERE clause, these values should not be enclosed in single quote marks. For example, the following script returns the names of all of the services on a computer that are capable of being paused. In this query:

  • Win32_Service is the WMI class being queried.

  • AcceptPause is the class property.

  • True is the value of the AcceptPause property. Because True is a Boolean value, it is not enclosed in quotation marks.



strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colServices = objSWbemServices.ExecQuery _
    ("SELECT * FROM Win32_Service WHERE AcceptPause = True")
For Each objService In colServices
    Wscript.Echo objService.Name
Next

Using Variables in WHERE Clauses

One approach to writing scripts is to hard-code values as needed. For example, if you want to return a list of all the services that are stopped, you can hard-code the query into the script:



Set colServices = objSWbemServices.ExecQuery _
    ("SELECT * FROM Win32_Service WHERE State = 'Stopped'")

But what if you there are times when want to see a list of all the services that are running or a list of all the services that are paused? One way to handle this problem is to create separate scripts to return each data set. If services can be running, stopped, paused, or resuming, you need four scripts, one for each state.

Alternatively, you can create a single script that returns information about services based on service state. When the user runs the script, he or she simply supplies the desired state, perhaps as a command-line argument, and the script does the rest.

The most efficient way to do this is to store the supplied value in a variable and then reference the variable within the WQL query. Essentially, you need the query to do this:



Select all the properties from the Win32_Service class where the State is equal to the value stored in this variable.

This is easy enough to write in pseudo code. But how do you translate the pseudo code into an actual WQL query?

Here is how:

  1. Write the query in the usual fashion, stopping where the variable must be inserted. For example, suppose you are modifying the following query:

    "SELECT * FROM Win32_Service WHERE State = 'Stopped'".

    You write the first part of the query up to the word Stopped, including the single quotation mark. (Why write the query up to the word Stopped? Because, in this example, you want to replace the hard-coded value with the variable name.) Your query will look like this:

    "SELECT * FROM Win32_Service WHERE State = '

  2. Insert a set of quotation marks to indicate that the string is being cut off at this point, and then insert a space and an ampersand (&). The ampersand indicates that you are appending something to the string. Your query will now look like this:

    "SELECT * FROM Win32_Service WHERE State =' &

  3. Insert the name of the variable (in this example, strState), and then add an ampersand, a space, and a second set of quotation marks. This indicates that there is additional text to be appended after the variable name. Your query should look like this:

    "SELECT * FROM Win32_Service WHERE State = '" & strState &

  4. Add the rest of the query string. If you recall, the original query string was:

    "SELECT * FROM Win32_Service WHERE State = 'Stopped'"

    You have now replaced the word Stopped with the variable name and have only the last single quotation mark and the last quotation mark remaining. Add these to the end of the string, making the final query look like this:

    "SELECT * FROM Win32_Service WHERE State ='" & strState & "

This is what the query looks like within a script that lets you specify a service state as a command-line argument. Assuming that you named the script ServiceState.vbs and you wanted a list of running services, you start the script using this command:

cscript servicestate.vbs running



strState = Wscript.Arguments.Item(0)
strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colServices = objSWbemServices.ExecQuery _
    ("SELECT * FROM Win32_Service WHERE State = '" & strState & "'")
For Each objService In colServices
    Wscript.Echo objService.Name
Next

Admittedly, this can be a little confusing. You will likely find it easier if you follow the same approach each time: Start by creating a query with a hard-coded value, and then replace the hard-coded value with the variable name and the appropriate quotation marks and ampersands.

You can use the following pattern (with a space following each element):

Quotation marks Ampersand Variable name Ampersand Quotation marks

Or:

" & strVariableName & "

Was this page helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft