Previous Section Table of Contents Next Section

Associating WMI Instances

Hopefully, my previous two examples make it easier for you to understand WMI associations. However, they're bad examples for truly working with associated classes. Why? Because you aren't ever going to begin knowing which instance of the associator class you want; you're going to begin with one of the associated classes instead. Using the preceding technique, suppose you want to find the shares for a particular printer. You'd have to

  • Get the correct Win32_Printer class first to get its DeviceID.

  • Query Win32_PrinterShares for all instances where the Antecedent property references the DeviceID you're looking for.

  • Take the results of that query and retrieve all referenced instances of Win32_Share.

ASSOCIATORS OF

The aforementioned technique is an awkward way to get the information, and that's why WQL offers the ASSOCIATORS OF command. Suppose you have a printer with a device ID of "LaserJet 5." You've created three or four shares of the printer, each with different permissions or whatever. You want to use WMI to retrieve the name of each share, and list the maximum concurrent number of users allowed to use each share. You could write a WQL query like this: ASSOCIATORS OF {Win32_Printer.DeviceID = "LaserJet 5"}. Note that ASSOCIATORS OF replaces the SELECT, property list, FROM, and class name elements of a more traditional WQL query. Also note that the class must be listed in curly braces {} not parentheses. That messes me up every time. Figure 19.3 shows the results of this query in Wbemtest (assuming you have a printer named LaserJet 5, that is; for this example, I used a different printer name).

Figure 19.3. Results of the ASSOCIATORS OF query

graphics/19fig03.gif

It turns out there are several associated classes:

  • Win32_PrinterDriver

  • Win32_PrinterConfiguration

  • Win32_ComputerSystem

  • CIM_DataFile

  • Win32_Share

You can restrict the list just to the Win32_Share class by modifying the query a bit.


ASSOCIATORS OF {Win32_Printer.DeviceID = "LaserJet 5"}

 WHERE AssocClass = Win32_PrinterShare

This modified query just returns an instance of Win32_Share for each share that exists for the printer. Note that the query does not return Win32_PrinterShare instances; WMI is smart enough to know that although Win32_PrinterShare is the associator class, you're really after the other side of the relationship, which is Win32_Share.

The following script displays each share name for the specified printer, and the number of connections each accepts.


Dim oWMI, oPShares, oPShare

Dim oShare



'connect to WMI

Set oWMI = GetObject("winmgmts:\\.\root\cimv2")



'retrieve all settings

Set oPShares = oWMI.ExecQuery("ASSOCIATORS OF {Win32_Printer.DeviceID='LaserJet 5'} WHERE AssocClass = Win32_PrinterShare")



For Each oShare in oPShares



 'display share info

 If oShare.AllowMaximum = False Then

  WScript.Echo "Share " & oShare.Name & _

   " allows " & oShare.MaximumAllowed & _

   " concurrent connections."

 Else

  WScript.Echo "Share " & oShare.Name & _

   " allows max connections."

 End If



Next

REFERENCES OF

The WQL REFERENCES OF query works similarly to ASSOCIATORS OF. It's designed to return all association instances that refer to a specified source instance. However, whereas ASSOCIATORS OF attempts to retrieve the endpoint instances (such as mapping Win32_Printer all the way through to Win32_Share), REFERENCES OF only attempts to find the associator classes (such as Win32_PrinterShare).

For example, use Wbetmtest to execute the following query.


REFERENCES OF

 {Win32_Printer.DeviceID = 'printername'}

Of course, replace printername with a valid printer on your computer.

NOTE

Remember, to execute a query in Wbemtest, first connect to the \default\cimv2 namespace. Then, click the Query button and type the query into the text box.


The query returns several classes:

  • Win32_DriverForDevice

  • Win32_PrinterSetting

  • Win32_SystemDevices

  • Win32_PrinterShare (if the printer is shared)

  • Win32_PrinterDriverDll

These are all of the associator classes that refer to the specified Win32_Printer instance. If you want to get the endpoint of the association-in other words, the actual driver, printer setting, device, share, or driver DLL-you'd use ASSOCIATORS OF instead. I don't find much need for REFERENCES OF in my administrative scripts, because I'm usually looking for the other end of the association, not the middle point.

Using WHERE with ASSOCIATIONS OF and REFERENCES OF

Both the ASSOCIATIONS OF and REFERENCES OF queries support a WHERE clause; I showed you an example using the AssocClass keyword earlier. REFERENCES OF accepts the following keywords in its optional WHERE clause.

  • ClassDefsOnly. This causes the query to return the class definition, rather than instances of the class being queried.

  • RequiredQualifier. This allows you to specify a qualifier that all returned classes must meet. For example, RequiredQualifier = Dependent restricts query results to those association classes that have a property named Dependent.

  • ResultClass. This allows you to restrict the query results to a particular class, such as ResultClass = Win32_PrinterShare. This cannot be used in conjunction with ClassDefsOnly.

ASSOCIATORS OF supports different WHERE options.

  • AssocClass. This allows you to specify the associator class that will be used. Use this, as I did in my earlier example, to restrict your results to those from a particular class. For example, AssocClass = Win32_PrinterShare.

  • ClassDefsOnly. This forces the query to return the definition for the result classes, rather than the actual instances of the class. This cannot be used with ResultClass.

  • RequiredAssocQualifier. This tells the query to only return instances that are related by means of an associator class that includes the specified qualifier. Sound complex? Here's an example: RequiredAssocQualifier = Dependent. With this specified, the query only returns endpoint instances whose relationship to the queried class is through an associator class that has a property named Dependent.

  • RequiredQualifier. This specifies a property that must be present in the endpoint classes returned by the query. For example, RequiredQualifier = AllowMaximum restricts the associated classes returned by the query to those with an AllowMaximum property.

  • ResultClass. This specifies that the query only return specified classes. For example, ResultClass = Win32_Share ensures that only instances of Win32_Share are returned.

All of these WHERE clause keywords can be combined (except as I've noted here), and do not require commas or any other separation. For example:


ASSOCIATORS OF {Win32_Printer.DeviceID = 'LaserJet5'}

 WHERE

 ResultClass = Win32_Share

 RequiredQualifier = AllowMaximum

Don't be tempted to include an AND keyword like you would in a traditional WHERE clause, because WMI will return an error.

    Previous Section Table of Contents Next Section