SWbemServices

Microsoft® Windows® 2000 Scripting Guide

SWbemServices serves two primary roles. First, the SWbemServices object represents an authenticated connection to a WMI namespace on a target computer. Second, SWbemServices is the Automation object you use to retrieve WMI-managed resources. You can obtain a reference to an SWbemServices object in either of two ways:

  • As demonstrated in most of the WMI scripts presented thus far, you can use the VBScript GetObject function in combination with the WMI moniker "winmgmts:". The following example is the simplest form of a WMI connection. The example connects to the default namespace (typically root\cimv2) on the local computer:

    Set objSWbemServices = GetObject("winmgmts:")
    
  • You can also use the SWbemLocator object ConnectServer method to obtain a reference to an SWbemServices object. For more information, see "SWbemLocator" earlier in this section.

After you obtain a reference to an SWbemServices object, you use the object reference to call 1 of 18 methods available using SWbemServices. SWbemServices can return one of three different WMI scripting library objects (SWbemObjectSet, SWbemObject, or SWbemEventSource), depending on the method you call. Knowing the type of object each method returns will help you determine the next step your script must take. For example, if you get back an SWbemObjectSet, you must enumerate the collection to access each SWbemObject in the collection. If you get back an SWbemObject, you can immediately access the object methods and properties without enumerating the collection first.

SWbemServices methods and their return types are described in Table 6.5.

Table 6.5 SWbemServices Methods

Method Name

Default Mode

Return Type

Description

AssociatorsOf

Semisynchronous

SWbemObjectSet

Retrieves the instances of managed resources that are associated with a specified resource through one or more association classes. You provide the object path for the originating endpoint, and AssociatorsOf returns the managed resources at the opposite endpoint. The AssociatorsOf method performs the same function that the ASSOCIATORS OF WQL query performs.

Delete

Synchronous (cannot be changed)

None

Deletes an instance of a managed resource (or a class definition from the CIM repository).

ExecMethod

Synchronous (cannot be changed)

SWbemObject

Provides an alternative way to execute a method defined by a managed resource class definition. Primarily used in situations in which the scripting language does not support out parameters. For example, JScript does not support out parameters.

ExecNotificationQuery

Semisynchronous

SWbemEventSource

Executes an event subscription query to receive events. An event subscription query is a query that defines a change to the managed environment that you want to monitor. When the change occurs, the WMI infrastructure delivers an event describing the change to the calling script.

ExecQuery

Semisynchronous

SWbemObjectSet

Executes a query to retrieve a collection of instances of WMI-managed resources (or class definitions). ExecQuery can be used to retrieve a filtered collection of instances that match criteria you define in the query passed to ExecQuery.

Get

Synchronous (cannot be changed)

SWbemObject

Retrieves a single instance of a managed resource (or class definition) based on an object path.

InstancesOf

Semisynchronous

SWbemObjectSet

Retrieves all the instances of a managed resource based on a class name. By default, InstancesOf performs a deep retrieval. That is, InstancesOf retrieves the instances of the resource identified by the class name passed to the method and also retrieves all the instances of all the resources that are subclasses (defined beneath) of the target class.

ReferencesTo

Semisynchronous

SWbemObjectSet

Returns all of the associations that reference a specified resource. The best way to understand ReferencesTo is to compare it with the AssociatorsOf method. AssociatorsOf returns the dynamic resources that are at the opposite end of an association. ReferencesTo returns the association itself. The ReferencesTo method performs the same function that the REFERENCES OF WQL query performs.

SubclassesOf

Semisynchronous

SWbemObjectSet

Retrieves all the subclasses of a specified class from the CIM repository.

Table 6.5 lists only 9 of the 18 methods of SWbemServices; the remaining 9 methods are the asynchronous counterparts. The asynchronous methods have similar names; however, each asynchronous method name is appended with the suffix Async. For example, the asynchronous version of ExecNotificationQuery is named ExecNotificationQueryAsync.

SWbemServices modes of operation

SWbemServices supports three modes of operation: synchronous, asynchronous, and semisynchronous.

Synchronous. In synchronous mode, your script blocks (pauses) until the SWbemServices method completes. Not only does your script wait, but in cases in which WMI retrieves instances of managed resources, WMI builds the entire SWbemObjectSet in memory before the first byte of data is returned to the calling script. This can have an adverse effect on the script performance and on the computer running the script. For example, synchronously retrieving thousands of events from the Windows 2000 Event Logs can take a long time and use a lot of memory. For these reasons, synchronous operations are not recommended except for the three methods (Delete, ExecMethod, and Get) that are synchronous by default. These methods do not return large data sets, so semisynchronous operation is not required.

Note

  • Changing the run-time behavior of a semisynchronous method to synchronous is possible but not recommended. Doing so can result in WMI scripts that appear to hang when retrieving large data sets such as all the instances of CIM_DataFile or Win32_NTLogEvent.

Asynchronous. In asynchronous mode, your script calls one of the nine asynchronous methods and returns immediately. That is, as soon as the asynchronous method is called, your script resumes running the next line of code. To use an asynchronous method, your script must first create an SWbemSink object and a special subroutine called an event handler. WMI performs the asynchronous operation and notifies the script by calling the event handler subroutine when the operation is complete.

Semisynchronous. Semisynchronous mode is a compromise between synchronous and asynchronous. Semisynchronous operations offer better performance than synchronous operations, yet they do not require the extra knowledge and scripting steps necessary to handle asynchronous operations. This is the default operation type for most WMI queries.

In semisynchronous mode, your script calls one of the six data retrieval methods and returns immediately. WMI retrieves the managed resources in the background as your script continues to run. As the resources are retrieved, they are immediately returned to your script by way of an SWbemObjectSet. You can begin to access the managed resources without waiting for the entire collection to be assembled.

There is a caveat to semisynchronous operations when you are working with managed resources that have many instances (many meaning greater than 1,000), such as CIM_DataFile and Win32_NTLogEvent. The caveat is a result of how WMI handles instances of managed resources. For each instance of a managed resource, WMI creates and caches an SWbemObject object. When a large number of instances exist for a managed resource, instance retrieval can monopolize available resources, reducing the performance of both the script and the computer.

To work around the problem, you can optimize semisynchronous method calls using the wbemFlagForwardOnly flag. The wbemFlagForwardOnly flag, combined with the wbemFlagReturnImmediately flag (the default semisynchronous flag), tells WMI to return a forward-only SWbemObjectSet, which eliminates the large data set performance problem. However, using the wbemFlagForwardOnly flag comes with a cost. A forward-only SWbemObjectSet can be enumerated only once. After each SWbemObject in a forward-only SWbemObjectSet is accessed, the memory allocated to the instance is released.

With the exception of the Delete, ExecMethod, Get, and nine asynchronous methods, semisynchronous is the default and recommended mode of operation.

Using SWbemServices methods

The methods most often used in system administration scripts are InstancesOf, ExecQuery, Get, and ExecNotificationQuery. Although often used, InstancesOf is not necessarily the recommended way to retrieve information (although it is arguably the easiest way). This will be discussed in more detail later in this chapter.

InstancesOf

You have already seen the InstancesOf method used numerous times throughout this chapter. At this time, it is important to clarify something said earlier. Earlier it was stated that you cannot retrieve instances of abstract classes, such as CIM_Service. And while that is true, the default behavior of InstancesOf might lead you to think otherwise.

By default, InstancesOf performs a deep retrieval. That is, InstancesOf retrieves all instances of the managed resource you identify and all instances of all the subclasses defined beneath the target class. For example, the following script retrieves all of the resources modeled by all of the dynamic classes defined beneath the CIM_Service abstract class.

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colSWbemObjectSet = objSWbemServices.InstancesOf("CIM_Service")
For Each objSWbemObject In colSWbemObjectSet
    Wscript.Echo "Object Path: " & objSWbemObject.Path_.Path
Next

If you run this script, you will get information back. However, this information will not be limited to the services installed on a computer. Instead, it will include information from all child classes of CIM_Service, including Win32_SystemDriver and Win32_ApplicationService.

ExecQuery

Like the InstancesOf method, the ExecQuery method always returns an SWbemObjectSet collection. Thus your WMI script must enumerate the collection ExecQuery returns in order to access each managed resource instance in the collection, as shown here:

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

Other SWbemServices methods that return an SWbemObjectSet include AssociatorsOf, ReferencesTo, and SubclassesOf.

Get

Unlike the ExecQuery and InstancesOf methods, the Get method always returns an SWbemObject representing a specific instance of a WMI-managed resource (or single class definition, as shown earlier). To obtain a specific instance of a WMI-managed resource using the Get method, you must tell Get the instance to retrieve by passing the method the object path, as shown in the following script.

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objSWbemObject = objSWbemServices.Get("Win32_Service.Name='Messenger'")
Wscript.Echo "Name:         " & objSWbemObject.Name        & vbCrLf & _
"Display Name: " & objSWbemObject.DisplayName & vbCrLf & _
"Start Mode:   " & objSWbemObject.StartMode   & vbCrLf & _
"State:        " & objSWbemObject.State

SWbemObjectSet

An SWbemObjectSet is a collection of zero or more SWbemObject objects. Each SWbemObject in a SWbemObjectSet can represent one of two things:

  • An instance of a WMI-managed resource.

  • An instance of a class definition.

For the most part, the only thing you will ever do with an SWbemObjectSet is enumerate all the objects contained within the collection itself. However, SWbemObjectSet does include a property Count that can be useful in system administration scripting. As the name implies, Count tells you the number of items in the collection. For example, this script retrieves a collection of all the services installed on a computer and then echoes the total number of services found:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_Service")
Wscript.Echo "Services installed on target computer: " & colSWbemObjectSet.Count

What makes Count useful is that it can tell you whether a specific instance is available on a computer. For example, this script retrieves a collection of all the services on a computer that have the Name W3SVC. If the Count is 0 (and it is valid for collections to have no instances), that means the W3SVC service is not installed on the computer.

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colSWbemObjectSet = objSWbemServices.ExecQuery _
    ("SELECT * FROM Win32_Service WHERE Name='w3svc'")
If colSWbemObjectSet.Count = 0 Then
    Wscript.Echo "W3SVC service is not installed on target computer."
Else
    For Each objSWbemObject In colSWbemObjectSet
        ' Perform task on World Wide Web Publishing service.
    Next
End If

One thing to be careful of when using Count is that WMI does not keep a running tally of the number of items in a collection. If you request Count for a collection, WMI cannot instantly respond with a number; instead, it must literally count the items, enumerating the entire collection. For a collection that has relatively few items, such as services, this enumeration likely takes less than a second. Counting the number of events in an event log collection, however, can take considerably longer.

And then suppose you want to display the property values for every event in the collection. If so, WMI will have to enumerate the entire collection a second time.