Summary: Microsoft Scripting Guy, Ed Wilson, illustrates how to explore WMI methods and writable properties from a Windows PowerShell script.

Weekend Scripter

Microsoft Scripting Guy, Ed Wilson, here. One of the things I like about Windows PowerShell is the ease in which I can modify things, experiment with things, play with things, and finally end up with a decent script. It is a rainy day in Charlotte, North Carolina, and it is beginning to actually look like spring outside. I am listening to Radiohead on my Zune HD, and sipping a cup of organic mint tea…it is just one of those sort of laid-back days.

I had an extremely busy week, with a presentation to the Charlotte IT Professionals Group thrown in for fun. I absolutely love speaking to user groups, either in person or via Live Meeting, and it is always the highlight of my week. I firmly believe and wish to support these groups because they are the embodiment of community. By the way, if you are looking for a Windows PowerShell user group in your area, check out the PowerShell Group site for listings. If you know of a group that is not listed in this directory, please add it. There is also help available if you want to start a user group.

One of the goals of a good scriptwriter should be to write reusable code. In Windows PowerShell, this generally means creating functions. When I created the Get-WmiClassesMethods.ps1 Windows PowerShell script and the Get-WmiClassProperties.ps1 script, I had code reuse in mind. For details about the essential logic of today’s script, refer to the following articles:

Use PowerShell to Find WMI Classes that Contain Methods

Use PowerShell to Find Writable WMI Properties

Therefore, I encapsulated the main logic into individual functions. Due to time constraints, the functions are not as reusable as I would like them to be, but I did have reuse in mind at the time. This also illustrates that there is often a tradeoff between code reuse and development time. It takes time to design a completely portable function, and sometimes it takes a long time to analyze how a function might be reused and to abstract everything.

On a rainy Saturday morning, I thought it would be a good idea to combine the two scripts into a single script that produces a consolidated listing of implemented methods and writable properties from all the WMI classes in a particular WMI namespace. I know I can use such a list, and I hope you find it useful as well.

To be sure, the script is a bit complicated, and it is most certainly long. That is why I uploaded the Get-WmiClassMethodsAndWritableWmiProperties.ps1 script to the Scripting Guys Script Repository. But the script is shorter and easier to understand that a corresponding script written in VBScript. In fact, I always wanted to write such a script in VBScript but I never got around to doing it—and I wrote the book on VBScript and WMI.

All right, I want to start with the Get-WmiClassMethods function. I will highlight the changes I made. The first change I made was to add a class parameter to the Param portion of the function. The reason for this is that I want to collect the WMI classes outside of the function, and pass the individual WMI class information to the function for processing. This will enable me to work on the same class and to retrieve methods and properties as appropriate. Because I am going to pass the class information to the functions, I do not need to collect the classes inside the function. Therefore, I comment out the lines in the function that perform the class collection duties. This revised portion of the code is shown here.

Function Get-WmiClassMethods

{

 Param(

   [string]$namespace = "root\cimv2",

   [string]$computer = ".",

   $class

)

 $abstract = $false

 $method = $null

 #$classes = Get-WmiObject -List -Namespace $namespace | Where-Object { $_.methods }

 #Foreach($class in $classes)

 #{

I changed the output to include the Word METHODS in addition to the WMI class name. To do this, I used the New-Underline function. One of the cool things about this function, and one reason I use it so often, is that it allows one to specify the character to use for underlining, in addition to the colors to use for the text and the underline string.

I also had to comment out the closing curly bracket (closing braces…squiggly things…whatever) of the foreach class loop. The comments that I included when I originally created the script make lining up the curly bracket easier. This portion of the script is shown here.

if($method)

        {

         New-Underline -strIN $class.name

         New-Underline "METHODS" -char "-"

        }

      $method

    } #end if not abstract

  $abstract = $false

  $method = $null

# } #end foreach class

Because the two functions (Get-WmiClassMethods and Get-WmiClassProperties) are written in a similar style, similar changes are required for inclusion here. I need to add a class parameter to the Param section, and I need to comment out the code that gathers the WMI classes and implements the foreach class loop. The revised code is shown here.

Function Get-WmiClassProperties

{

 Param(

   [string]$namespace = "root\cimv2",

   [string]$computer = ".",

   $class

)

 $abstract = $false

 $property = $null

 #$classes = Get-WmiObject -List -Namespace $namespace

 #Foreach($class in $classes)

 #{

I add the word PROPERTIES to the output portion of the script, and remove the closing curly bracket. This revision is shown here.

     if($property)

        {

         New-Underline -strIN $class.name

         New-Underline "PROPERTIES" -char "-"

        }

      $property

    } #end if not abstract

  $abstract = $false

  $property = $null

# } #end foreach class

} #end function Get-WmiClassProperties

I moved the collection of the WMI classes, and the foreach $class construction to the entry point of the script. In addition, I added the -class parameter when I call each function. This portion of the script is shown here.

# *** Entry Point to Script ***

 

$classes = Get-WmiObject -List -Namespace $namespace

Foreach($class in $classes)

 {

  Get-WmiClassMethods -class $class

  Get-WmiClassProperties -class $class

 }

When the script runs, the output that is shown in the following image appears in the Windows PowerShell ISE.

Image of command output

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