Bookmark and Share

(Editor's note: This is part 1 of a two-part article originally intended for TechNet Magazine. Part 2 will be published tomorrow.) 


The sun had barely thought about coming up as I stepped aboard the catamaran that would take me from the Circular Quay across Sydney Harbor to Manly Beach. I staggered slightly as I navigated nearly 100 pounds of scuba gear across the narrow "cat walk" that led from the pier to the low-slung harbor cat. When aboard, I found a seat near a window and gazed expectantly out as the quick harbor cat rapidly came up to speed and rounded the jetty containing the Sydney Opera House. By now, the myriad sails were picking up the first hesitant strands of orange highlighting that signaled the dawn of a new day. It would be another great day of scuba diving—I was psyched.

Once aboard the dive boat, I quickly assembled my gear and chatted with my fellow explorers of the deep. Yesterday we had seen a Port Jackson shark, and a giant cuttlefish, but the leafy sea dragons had failed to make an appearance. Those gentle and terribly shy sea dragons move with a grace and ease that makes a hummingbird appear like a klutzy dodo bird. My dive buddy was from Munich, Germany, and we talked about his experiences diving in the Red Sea and the Philippines. Meanwhile, I regaled him with tales of diving in the clear warm waters of the Caribbean. Yes, it is going to be a fine day of diving.

As my voice was beginning to grow hoarse from talking above the twin diesel engines on the dive boat, I settled down and began to focus my attention on my camera rig. Strobe turned on and in standby. Sync cable attached and routed out of the way of the lens port. Counter weight attached. Lens cover attached. Check, check, check, and check. As the boat slowed and made the last turn, we approached a small outcropping of rocks pushing to the surface. I snapped a few pictures with my camera. On my digital camera’s display, the rocks and the cliffs off in the distance looked exotic. "Yes, this will be a stellar day of diving," I thought to myself.

As I stood, and duck-walked to the stern of the boat, I prepared to make my giant stride entry into the water. With all the gear, there is never any problem descending to depth. I placed my hand over my mask, grasped my regulator, and had one foot extendedjust then, my dive buddy grasped the yoke of my air tank and pulled me back. "You did not turn your air on, my friend." Whew! "That is why you check before you jump in the water," I thought.

 

Just as it is important to check that your air is turned on before you jump into the ocean with a bunch of lead weights and steel air tanks, it is also important to check that the WMI class you want to use in your script actually exists before you jump off the deep end and attempt to run the script against a large number of computers on your network. This is doubly important when the WMI class is one that may not be present on all of your computers. One way to detect if the WMI class exists is to do a WMI query and look for errors. This is similar to jumping off of the dive boat without checking to see if your air tank is turned on. Though it will probably work most of the time, the consequences for that rare exception could be serious.

A better approach for finding out if a WMI class is available is to check for the existence of the provider. In the case of the Win32_Product WMI class, it is supplied by the MSIPROV WMI provider. In this article we create a function, the Get-WmiProvider function, which can be used to detect the presence of any WMI provider that is installed on the system.

The Get-WmiProvider function contains two parameters. The first parameter is the name of the provider; the second is a switched parameter named verbose. When the Get-WmiProvider function is called with the verbose switched parameter, detailed status information is displayed on the console. The verbose information provides the user of the script information that could be useful from a troubleshooting perspective:

Function Get-WmiProvider([string]$providerName, [switch]$verbose)

After the function has been declared, the first thing that is done is to store the current value of the $VerbosePreference. This is because it could be set to one of four potential values. The possible enumeration values are SilentlyContinue, Stop, Continue, and Inquire. By default, the value of the $VerbosePreference automatic variable is set to SilentlyContinue.

When the function finishes running, you will want to set it back to its original value if it is changed during the script; therefore, the original value of the $VerbosePreference variable is stored in the $oldVerbosePreference variable.

It is time to determine if the function was called with the verbose switch. If it was, a variable named $verbose will be present on the variable drive. If the $verbose variable exists, the value of the $VerbosePreference automatic variable is set to continue:

{
 $oldVerbosePreference = $VerbosePreference
 if($verbose) { $VerbosePreference = "continue" }

Next you need to look for the WMI provider. To do this, the Get-WmiObject cmdlet is used to query for all instances of the __Provider WMI system class. All WMI classes that begin with a double underscore are system classes. In most cases they are not of much interest to IT pros; however, familiarity with them can often provide powerful tools to the scripter who takes the time to examine them. All WMI providers are derived from the __Provider WMI class. This is similar to the way that all WMI namespaces are derived from the __Namespace WMI class. The properties of the __Provider WMI class are seen in Table 1.

Table 1  Properties of the __Provider WMI Class

Property name

Property type

ClientLoadableCLSID

System.String

CLSID   

System.String

Concurrency                  

System.Int32

DefaultMachineName           

System.String

Enabled                      

System.Boolean

HostingModel                 

System.String

ImpersonationLevel           

System.Int32

InitializationReentrancy     

System.Int32

InitializationTimeoutInterval

System.String

InitializeAsAdminFirst       

System.Boolean

Name                         

System.String

OperationTimeoutInterval     

System.String

PerLocaleInitialization      

System.Boolean

PerUserInitialization        

System.Boolean

Pure                         

System.Boolean

SecurityDescriptor           

System.String

SupportsExplicitShutdown     

System.Boolean

SupportsExtendedStatus       

System.Boolean

SupportsQuotas               

System.Boolean

SupportsSendStatus           

System.Boolean

SupportsShutdown             

System.Boolean

SupportsThrottling           

System.Boolean

UnloadTimeout                

System.String

Version                      

System.UInt32

__CLASS                      

System.String

__DERIVATION                 

System.String[]

__DYNASTY                    

System.String

__GENUS                      

System.Int32

__NAMESPACE                  

System.String

__PATH                       

System.String

__PROPERTY_COUNT             

System.Int32

__RELPATH                    

System.String

__SERVER                     

System.String

__SUPERCLASS                 

System.String


The filter parameter of the Get-WmiObject cmdlet is used to return the provider that is specified in the $providerName variable. If you do not know the name of the appropriate WMI provider, you will need to search for it. You can use the Windows Management Instrumentation Tester (WbemTest), which is included as part of the WMI installation. If a computer has WMI installed on it, it has WbemTest. Because it resides in the system folders, you can launch it directly from within the Windows PowerShell console by typing the name of the executable. This is seen here:

PS C:\> wbemtest
PS C:\>

After WbemTest appears, the first thing you will need to do is to connect to the appropriate WMI namespace. To do this, click the Connect button. In most cases this will be the Root\Cimv2 namespace. On Windows Vista and later, the Root\Cimv2 is the default WMI namespace for WbemTest. On earlier versions of Windows, the default WbemTest namespace is Root\Default. Change or accept the namespace as appropriate, and click the Connect button. The display changes to a series of buttons, many of which appear to have cryptic names and functionality.

 

Join us tomorrow for part 2, the conclusion to this post about WMI providers. In the meantime, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you on Monday. Peace!

Ed Wilson and Craig Liebendorfer, Scripting Guys