Hey, Scripting Guy! Part 1: How Can I Make Sure That a WMI Provider Exists Before Using It in a Script?


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

Comments (0)

Skip to main content