Summary: Microsoft Scripting Guy, Ed Wilson, shares an excerpt about WMI and CIM from his book, Windows PowerShell Best Practices.

Microsoft Scripting Guy, Ed Wilson, is here. Today I have an excerpt from my new book, Windows PowerShell Best Practices, which is published by Microsoft Press.

Image of book

The CIM cmdlets in Windows PowerShell support multiple ways of exploring WMI. They work well when you are working in an interactive fashion. For example, Tab expansion expands the namespace when you use the CIM cmdlets; thereby permitting exploring namespaces that might not otherwise be very discoverable. You can even use this technique to drill down into namespaces. All CIM classes support Tab expansion of the Namespace parameter, but to explore WMI classes, you want to use the Get-CimClass cmdlet.

Note  The default WMI namespace on all Windows operating systems after Windows NT 4.0 is Root/Cimv2. Therefore, all of the CIM cmdlets default to Root/Cimv2. The only time you need to change the default WMI namespace (via the Namespace parameter) is when you need to use a WMI class from a non-default WMI namespace.

Using the Classname parameter

When you use the Get-CimClass cmdlet, you can use wildcard characters for the Classname parameter to enable you to quickly identify potential WMI classes for perusal. You can also use wildcard characters for the Qualifiername parameter. In the following example, the Get-CimClass cmdlet looks for WMI classes related to computers:

PS C:\> Get-CimClass -ClassName *computer*

   NameSpace: ROOT/CIMV2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
Win32_ComputerSystemEvent           {}                   {SECURITY_DESCRIPTOR, TIME_CR...
Win32_ComputerShutdownEvent         {}                   {SECURITY_DESCRIPTOR, TIME_CR...
CIM_ComputerSystem                  {}                   {Caption, Description, Instal...
CIM_UnitaryComputerSystem           {SetPowerState}      {Caption, Description, Instal...
Win32_ComputerSystem                {SetPowerState, R... {Caption, Description, Instal...
CIM_ComputerSystemResource          {}                   {GroupComponent, PartComponent}
CIM_ComputerSystemMappedIO          {}                   {GroupComponent, PartComponent}
CIM_ComputerSystemDMA               {}                   {GroupComponent, PartComponent}
CIM_ComputerSystemIRQ               {}                   {GroupComponent, PartComponent}
Win32_ComputerSystemProcessor       {}                   {GroupComponent, PartComponent}
CIM_ComputerSystemPackage           {}                   {Antecedent, Dependent}
Win32_ComputerSystemProduct         {}                   {Caption, Description, Identi...
Win32_NTLogEventComputer            {}                   {Computer, Record}

Note  If you try to use a wildcard character for the Classname parameter of the Get-CimInstance cmdlet, an error message returns because the parameter design does not permit wildcard characters.

Finding WMI class methods

If you want to find WMI classes related to processes that contain a method that begins with the letters term*, you use a command similar to the following:

PS C:\> Get-CimClass -ClassName *process* -MethodName term*

   NameSpace: ROOT/cimv2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
Win32_Process                       {Create, Terminat... {Caption, Description, Instal...

To find all WMI classes related to processes that expose any methods, you would use the following command:

PS C:\> Get-CimClass -ClassName *process* -MethodName *

   NameSpace: ROOT/cimv2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
Win32_Process                       {Create, Terminat... {Caption, Description, Instal...
CIM_Processor                       {SetPowerState, R... {Caption, Description, Instal...
Win32_Processor                     {SetPowerState, R... {Caption, Description, Instal...

To find any WMI class in the root/cimv2 WMI namespace that expose a method called Create, use the following command:

PS C:\> Get-CimClass -ClassName * -MethodName create

   NameSpace: ROOT/cimv2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
Win32_Process                       {Create, Terminat... {Caption, Description, Instal...
Win32_ScheduledJob                  {Create, Delete}     {Caption, Description, Instal...
Win32_DfsNode                       {Create}             {Caption, Description, Instal...
Win32_BaseService                   {StartService, St... {Caption, Description, Instal...
Win32_SystemDriver                  {StartService, St... {Caption, Description, Instal...
Win32_Service                       {StartService, St... {Caption, Description, Instal...
Win32_TerminalService               {StartService, St... {Caption, Description, Instal...
Win32_Share                         {Create, SetShare... {Caption, Description, Instal...
Win32_ClusterShare                  {Create, SetShare... {Caption, Description, Instal...
Win32_ShadowCopy                    {Create, Revert}     {Caption, Description, Instal...
Win32_ShadowStorage                 {Create}             {AllocatedSpace, DiffVolume, ...

Filtering classes by qualifier

To find WMI classes that possess a particular qualifier, use the Qualifier parameter. For example, the following command finds WMI classes that relate to computers and have the SupportsUpdate WMI qualifier:

PS C:\> Get-CimClass -ClassName *computer* -QualifierName *update

   NameSpace: ROOT/cimv2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
Win32_ComputerSystem                {SetPowerState, R... {Caption, Description, Instal...

The parameters can be combined to produce powerful searches that without using the CIM cmdlets would require rather complicated scripting. For example, the following command finds all WMI classes in the root/Cimv2 namespace that have the Singleton qualifier and also expose a method:

PS C:\> Get-CimClass -ClassName * -QualifierName singleton -MethodName *

   NameSpace: ROOT/cimv2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
__SystemSecurity                    {GetSD, GetSecuri... {}
Win32_OperatingSystem               {Reboot, Shutdown... {Caption, Description, Instal...
Win32_OfflineFilesCache             {Enable, RenameIt... {Active, Enabled, Location}

One qualifier that is important to review is the Deprecated qualifier. Deprecated WMI classes are not recommended for use because they are being phased out. By using the Get-CimClass cmdlet, it is easy to spot these WMI classes. This technique is shown here:

PS C:\> Get-CimClass * -QualifierName deprecated

   NameSpace: ROOT/cimv2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
Win32_PageFile                      {TakeOwnerShip, C... {Caption, Description, Instal...
Win32_DisplayConfiguration          {}                   {Caption, Description, Settin...
Win32_DisplayControllerConfigura... {}                   {Caption, Description, Settin...
Win32_VideoConfiguration            {}                   {Caption, Description, Settin...
Win32_AllocatedResource             {}                   {Antecedent, Dependent}

By using this technique, it is easy to find association classes. The following command finds all of the WMI classes in the root/cimv2 WMI namespace that relate to sessions. In addition, it looks for the Association qualifier. Luckily, you can use wildcard characters for the qualifier names; and therefore, the following command uses assoc* instead of typing out association.

PS C:\> Get-CimClass -ClassName *session* -QualifierName assoc*

   NameSpace: ROOT/cimv2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
Win32_SubSession                    {}                   {Antecedent, Dependent}
Win32_SessionConnection             {}                   {Antecedent, Dependent}
Win32_LogonSessionMappedDisk        {}                   {Antecedent, Dependent}
Win32_SessionResource               {}                   {Antecedent, Dependent}
Win32_SessionProcess                {}                   {Antecedent, Dependent}

One qualifier you should definitely look for is the Dynamic qualifier. This is because it is unsupported to query Abstract WMI classes. Therefore, when looking for WMI classes, you will want to ensure that at some point you run your list through the Dynamic filter. In the following command, three WMI classes return that are related to time:

PS C:\> Get-CimClass -ClassName *time

   NameSpace: ROOT/cimv2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
Win32_CurrentTime                   {}                   {Day, DayOfWeek, Hour, Millis...
Win32_LocalTime                     {}                   {Day, DayOfWeek, Hour, Millis...
Win32_UTCTime                       {}                   {Day, DayOfWeek, Hour, Millis...

By adding the query for the qualifier, the appropriate WMI classes are identified. One class is abstract, and the other two are dynamic classes that could prove to be useful. In the following script, first the Dynamic qualifier is used, and then the Abstract qualifier appears:

PS C:\> Get-CimClass -ClassName *time -QualifierName dynamic

   NameSpace: ROOT/cimv2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
Win32_LocalTime                     {}                   {Day, DayOfWeek, Hour, Millis...
Win32_UTCTime                       {}                   {Day, DayOfWeek, Hour, Millis...

PS C:\> Get-CimClass -ClassName *time -QualifierName abstract

   NameSpace: ROOT/cimv2

CimClassName                        CimClassMethods      CimClassProperties
------------                        ---------------      ------------------
Win32_CurrentTime                   {}                   {Day, DayOfWeek, Hour, Millis...

Join me tomorrow when I will talk about more cool Windows PowerShell stuff.

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