Summary: Microsoft Scripting Guy, Ed Wilson, talks about using the Windows PowerShell 3.0 CIM cmdlets to discover WMI class associations.
Microsoft Scripting Guy, Ed Wilson, is here. One of the cool things about the new Windows PowerShell 3.0 CIM cmdlets is the way they enhance WMI discoverability. Indeed, one of the primary questions I get relates back to WMI discoverability. With literally thousands of WMI classes in dozens of WMI namespaces, finding the specific WMI class to solve a particular problem is often a challenge.
Indeed, I used to spend hours searching for a particular WMI class to solve a specific problem. Once I found the WMI class, the actual scripting did not take very long—even in the VBScript days, it did not take me very long because I had written a number of very good templates. Still …. the big problem was finding the appropriate WMI class. Luckily, WMI discoverability using the new CIM cmdlets is a lot easier (for me they replace about a dozen very complex scripts I had written to accomplish the same sorts of things.) But, one script I had not written was one that showed me what WMI classes are related via specific WMI associations. For that purpose, I used the old-fashioned WMI Admin tools.
Finding WMI association classes
I have not been able to get the WMI Admin tools to work correctly on my Windows 8 laptop. This is probably good news, because the WMI Admin tools are like about 100 years old—they are rickety HTML applications that start up with a bunch of prompts, and once loaded, the right pane fails to work. Surprisingly enough, they did work on Windows 7. I say this is good news that they finally fail to work because now I get to move on to use new tools that are safer, faster, and more informative. Yes, I am talking about the new Windows PowerShell 3.0 CIM cmdlets.
Surprise! Association classes have an association qualifier
One of the most powerful tools exposed by the new CIM cmdlets is the Get-CimClass cmdlet. This cmdlet basically replaces the WMI Admin tools—at least the part I used to find WMI classes. The trick to finding WMI association classes is realizing two things. First, all association classes possess the association qualifier. Second, I want to find WMI classes that are dynamic, instead of classes that are abstract. This is because querying abstract WMI classes is not supported. To find all of the association classes, I use the Get-CimClass cmdlet and specify the association qualifier, as shown here.
Get-CimClass -QualifierName association
The output is a couple of hundred WMI association classes—both abstract and dynamic. I can easily filter out WMI classes that begin with Win32—and most dynamic WMI classes begin with Win32. This technique is shown here.
Get-CimClass -QualifierName association | ? cimclassname -match '^win32'
Cool, on my computer I now have the list down to 139 WMI classes. But some of these could be abstract, and I might also miss a dynamic WMI class that begins with CIM_. Unfortunately, the –QualifierName property does not accept an array; therefore, I need to do a couple of queries in the pipeline. I end up with the following command to return dynamic association WMI classes.
Get-CimClass -QualifierName association | % {get-cimclass $_.cimclassname -qualifiername dynamic}
I now have 128 dynamic association WMI class names. In addition, I found Cim_DirectoryContainsFile that is a dynamic association WMI class that begins with the letters CIM.
Finding out which classes make up the association
To find out what WMI classes make up the association, I use the Get-CimClass cmdlet. To illustrate this technique, I will use the Win32_SystemProcesses WMI association class. This class appears to relate processes to a system (at least the name gives that impression). The first thing to do is to use Get-CimClass to return the class. The command and associated results are shown here.
18:19 C:\> Get-CimClass win32_systemprocesses
NameSpace: ROOT/cimv2
CimClassName CimClassMethods CimClassProperties
------------ --------------- ------------------
Win32_SystemProcesses {} {GroupComponent, PartCom...
From previous work with association classes, I know that often a WMI association class returns two pieces of information: GroupComponent and PartComponent. The property names themselves are uninteresting, but what IS interesting is the WMI class contained within the GroupComponent or PartComponent property.
Note Not all WMI association classes return GroupComponent or PartComponent properties. In fact, the most common property names are the properties Antecedent/Dependent, followed by the properties Element/Setting, and then GroupComponent/PartComponent. I used the code shown here to determine the prevalence of Association Class property names (it is a one line command that I broke at the pipeline character).
Get-CimClass -QualifierName association |
% {get-cimclass $_.cimclassname -qualifiername dynamic} |
% { $_ | select -ExpandProperty cimclassproperties} |
Group name | sort count -Descending
To see what WMI classes return from the association, it is necessary to expand the CimClassProperties property. To do this, I use the Select-Object cmdlet (select is an alias) and I specify the –ExpandProperty parameter (-Expand is a shortened form of that parameter name). This technique is shown here.
18:34 C:\> Get-CimClass win32_systemprocesses | select -expand CimClassProperties
Name : GroupComponent
Value :
CimType : Reference
Flags : Property, Key, ReadOnly, NullValue
Qualifiers : {Aggregate, read, key, MappingStrings...}
ReferenceClassName : Win32_ComputerSystem
Name : PartComponent
Value :
CimType : Reference
Flags : Property, Key, ReadOnly, NullValue
Qualifiers : {read, key, MappingStrings, Override}
ReferenceClassName : Win32_Process
The ReferenceClassName property of each returned object contains the name of the WMI classes that make up one piece of the association. Therefore, the Win32_SystemProcesses WMI class associates the Win32_ComputerSystem and the Win32_Process WMI classes together. I can now use the Get-CimClass cmdlet to explore the properties and methods that may be contained in the two returned class instances.
That is all there is to exploring WMI association classes. I will continue this topic tomorrow when I will talk about using the new CIM cmdlets to query an association WMI class.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy