A Scriptomatic You Can Call Your Own

Dr. Scripto

Hi Everyone! In this issue of GUI Guy, we’re going to answer a challenge we put forth in the previous edition. As a result, you’ll get a good start on building your very own Scriptomatic; or, at least, you’ll better understand how our version works and how simple it was to construct. What, and you thought we toiled away for months over hot keyboards to bring you o-matics? If you have any feedback on this article or anything you’d like to see in the Scripting Eye for the GUI Guy, send email to scripter@microsoft.com (in English, if possible).

On This Page

Crafting Your Very Own Scriptomatic
Finding Our Way to an HTA
Dropping WMI Classes
Methods for Displaying Properties & Methods
Bonus – Auto-Generating Scripts

Crafting Your Very Own Scriptomatic

In the previous issue of GUI Guy, we looked at the wbemtest.exe utility. We learned how to use this utility to retrieve WMI class names and the properties and methods associated with a given WMI class. We then wrote scripts to retrieve this same information. The column ended with a challenge to the reader: combine the script that returns WMI class names with the script that returns properties and methods of WMI classes. There are various approaches you could take to packaging these scripts together in a useful way, but we tried to guide you towards using an HTML application, or HTA. You see, The Scripting Way isn’t completely devoid of GUI.

So, let’s go ahead and tackle the challenge. We’ll begin by recalling the first script we’re going to use. The following script returns the names of the WMI classes in the CIMV2 namespace:

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}root\cimv2")

Set colClasses = objWMIService.SubClassesOf

For Each objClass In colClasses
If Left(objClass.Path_.Class,6) = "Win32_" Then
   WScript.Echo objClass.Path_.Class
End If
Next

Note. We’ve chosen to use the version of the script that only returns WMI classes with a prefix of “Win32_”. This is a simple (some might say crude) way of filtering for classes that might be of interest to a Windows scripter.

Finding Our Way to an HTA

The script currently uses WScript.Echo to display the name of each WMI class. We’d like to, instead, capture those class names and display them in a drop-down list in an HTA. In keeping with Scripting Guys best practices, let’s begin by trying to leverage work already done by others. The following, skeletal, HTA file was pretty easy to find over at the HTA Developers’ Center: it’s the first bit of code listed in “Creating your Own HTA’s: Part 1.”

<head>
<title>HTA Test</title>
<HTA:APPLICATION 
     APPLICATIONNAME="HTA Test"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
     WINDOWSTATE="maximize"
>
</head>

<script language="VBScript">
    Sub TestSub
        Msgbox "Testing 1-2-3."
    End Sub
</script>

<body>
<input type="button" value="Run Script" name="run_button"  onClick="TestSub"><p> 

</body>

Fire up Notepad and copy the above code into it, then save the result as guiguy.hta. Remember where you put it, and be careful to avoid saving the file with a .hta.txt extension. You can ensure that you get the file extension you want by enclosing your file name in double quotes when you type it into Notepad’s File Name input box, like this: “guiguy.hta”.

Once you’ve saved your skeletal HTA, double-click on it. You should see something like the following:

screenshot

The HTA takes up your whole screen and, if you click on the Run Script button, it presents you with a message box. The first change we’ll make to the HTA will affect its size. We don’t want our HTA to fill the screen – we’d like something a little more subtle. So change the line

WINDOWSTATE="maximize"

to

WINDOWSTATE="normal"

Close your HTA and open it again. The HTA should be less intrusive.

Next, let’s remove the button and replace it with the drop-down list we’ll need for displaying our WMI class names. Replace this line

<input type="button" value="Run Script" name="run_button"  onClick="TestSub">

with this one

<select name="WMIClasses"></select>

Your HTA now looks like this:

screenshot

Not exactly inspiring yet, is it? OK, let’s populate that drop-down list box with WMI classes. We already wrote a script to do this in our previous column, but we need to figure out how to make use of it in our HTA. Instead of just jumping in and trying to hook up all of the code in one shot, let’s start with the small step of programmatically adding a hard-coded option to our drop-down list.

We’ll do that by replacing the script section of the HTA:

<script language="VBScript">
    Sub TestSub
        Msgbox "Testing 1-2-3."
    End Sub
</script>

with the following

<script language="VBScript">
Sub FillClassDropDown
   Set objNewOption = document.createElement("OPTION")
   objNewOption.Text = "Test WMI Class"
   WMIClasses.options.Add(objNewOption)
End Sub
</script>

If you make that replacement and save and run your modified HTA, you should see something like the following:

screenshot

What, yours didn’t work? Oh yeah, that’s right. You need some way to indicate that the new code you added should actually be run. The example code you replaced was run when the Run Script button was pressed. We removed the Run Script button, so that won’t work. We want our newly-added code to be called when the HTA loads. You can make this happen by adding an onLoad parameter to the <body> tag like so:

<body onLoad=FillClassDropDown>

This tells the HTA runtime to call the FillClassDropDown subroutine once the <body> portion of the HTA has been loaded. Your HTA should now look like this:

<head>
<title>HTA Test</title>
<HTA:APPLICATION 
     APPLICATIONNAME="HTA Test"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
     WINDOWSTATE="normal"
>
</head>

<script language="VBScript">
Sub FillClassDropDown
   Set objNewOption = document.createElement("OPTION")
   objNewOption.Text = "Test WMI Class"
   WMIClasses.options.Add(objNewOption)
End Sub

</script>

<body onLoad=FillClassDropDown>
<select name="WMIClasses"></select><p> 

</body>

Note. If after making these changes your HTA still doesn’t work – stand up, stretch, howl loudly and think about the positive impacts computing technology has had on our society.

OK, even once it does work for you, it’s still not going to make the front page of Wired or anything – but we’ve taken a small step towards our final goal. Especially for the beginning scripters among you, this method of taking small steps to build your HTA is a really wise way to work – at least early in your learning. It’s much easier to move from an empty drop-down, to one with a hard-coded string, to one with programmatically-generated strings, than it is to aim for the prize in one step. There’s an important psychological advantage to seeing something work along the way toward solving a multipart problem.

Dropping WMI Classes

But enough psychology; the Scripting Guys would probably make better experimental fodder than advisors in that particular realm. We should take a closer look at the script code we just added, starting with the first line:

Set objNewOption = document.createElement("OPTION")

This line creates a new option object. We want to add a new option to our drop-down list, so it makes some sense that we start off by creating one.

Next, we set the Text property of the new option:

objNewOption.Text = "Test WMI Class"

We’ve used some placeholder text here, “Test WMI Class” – but eventually, this is where the WMI class names will be input.

Lastly, we add the new option to our drop-down by referencing the <select> tag by its name, WMIClasses, and using the Add method of the options collection, passing it the name of our newly-created option.

WMIClasses.options.Add(objNewOption)

Now that we have a drop-down list with an option in it, we can finally get to work hooking up our WMI class dumping script. Recall that the original script uses WScript.Echo to display the class names to the screen:

WScript.Echo objClass.Path_.Class

We need to replace the line that is doing the displaying with the code we just created for filling in the options of a drop-down list:

Set objNewOption = document.createElement("OPTION")
objNewOption.Text = objClass.Path_.Class
WMIClasses.options.Add(objNewOption)

Here’s what the FillClassDropDown subroutine ends up looking like:

Sub FillClassDropDown
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}root\cimv2")
   Set colClasses = objWMIService.SubClassesOf
   
   For Each objClass In colClasses
      If Left(objClass.Path_.Class,6) = "Win32_" Then
         Set objNewOption = document.createElement("OPTION")
         objNewOption.Text = objClass.Path_.Class
         WMIClasses.options.Add(objNewOption)
      End If
   Next
End Sub

The For Each loop works its way through the collection of WMI classes in the cimv2 namespace. For each class that begins with “Win32_”, a new option object is created and its Text property is set to the name of that WMI class. Then the option is added to the WMIClasses drop-down.

Things are starting to take shape. After sprucing up the FillClassDropDown subroutine, here’s what our HTA looks like:

screenshot

It would be nice to have the classes listed in alphabetical order – but we’ll leave that as an exercise for the reader. If you are interested, there is sample code in the previous GUI Guy article that you can leverage.

Methods for Displaying Properties & Methods

The next step in the challenge is to figure out how to get the following property and method listing script hooked-up appropriately.

strClass = "Win32_PageFile"

Set objWMIService = _ 
   GetObject("winmgmts:{impersonationLevel=impersonate}root\cimv2")

Set objClass = objWMIService.Get(strClass)

WScript.Echo "* Properties *"
For Each objProperty In objClass.Properties_
   WScript.Echo objProperty.Name
Next

WScript.Echo vbNewLine & "* Methods *"
For Each objMethod In objClass.Methods_
   WScript.Echo objMethod.Name
Next

This seems as though it might be a bit trickier. The script, as it stands, returns the properties and methods of the hard-coded WMI class stored in the strClass variable - Win32_PageFile in this case. We need to modify this script to populate this variable with the class that is currently selected in the WMI class drop-down list. Then we need to load the results into another drop-down list; we already know how to do that.

Once again, we’ll start with a small step. We’ll create a message box that displays the currently-selected WMI class. We need to display a message when the HTA first loads (since the first WMI class in the list is effectively chosen) and whenever the user selects a new WMI class from the drop-down list.

We have already hooked up the onLoad event to call the FillClassDropDown subroutine. In order to display the currently-selected WMI class when the HTA first loads, we have to create a new subroutine to call on load. The new subroutine first calls FillClassDropDown and then proceeds to display the currently-selected WMI class.

Change the <body> tag in the HTA to look like the following:

<body onload=CallMeFirst>

Then update the <script> block in the HTA with the new CallMeFirst function:

<script language="VBScript">
Sub CallMeFirst
   
   FillClassDropDown
   
   For Each objOption In WMIClasses.Options
      If objOption.Selected = True Then
         MsgBox objOption.Text
      End If
   Next

End Sub


Sub FillClassDropDown
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}root\cimv2")
   Set colClasses = objWMIService.SubClassesOf
   
   For Each objClass In colClasses
      If Left(objClass.Path_.Class,6) = "Win32_" Then
         Set objNewOption = document.createElement("OPTION")
         objNewOption.Text = objClass.Path_.Class
         WMIClasses.options.Add(objNewOption)
      End If
   Next
End Sub

</script>

That takes care of displaying the WMI class “selected” in the drop-down when the HTA first loads. Next, since we want something to happen whenever the user changes the selected option in the drop-down list, we need to add an onChange directive to the <select> tag. Now, when the user selects a different class, the HandleClassChange subroutine will be called.

<select onChange=HandleClassChange name="WMIClasses"></select><p>

In the HandleClassChange subroutine (which you can insert below the existing FillClassDropDown subroutine) we iterate through the options, checking for the one that is currently selected. When we find it, we retrieve its Text property and display it in a message box.

Sub HandleClassChange
   For Each objOption In WMIClasses.Options
      If objOption.Selected = True Then
         MsgBox objOption.Text
      End If
   Next
End Sub

Here’s the result of selecting the Win32_QuickFixEngineering class once the new code has been added.

screenshot

Our next step will be to get the property- and method-listing code hooked up. We’ll start by adding it to the HandleClassChange subroutine, substituting the selected WMI class name for the hard-coded class name. The result will be that the properties and methods for that WMI class will be listed in the message box.

Here’s the modified HandleClassChange subroutine:

Sub HandleClassChange
   For Each objOption In WMIClasses.Options
      If objOption.Selected = True Then
 strClass = objOption.Text
 Set objWMIService = _
 GetObject("winmgmts:{impersonationLevel=impersonate}root\cimv2")
 Set objClass = objWMIService.Get(strClass)

 For Each objProperty In objClass.Properties_
  strProperties = strProperties & objProperty.Name & vbCrLf
 Next
   
 For Each objMethod In objClass.Methods_
  strMethods = strMethods & objMethod.Name & vbCrLf
 Next

      MsgBox strProperties & strMethods
      End If
   Next
End Sub

We identify the selected option in the WMIClasses drop-down list, like we did before, and store its value in the strClass variable. We then pass that value into the Get method, retrieving an object representing the corresponding WMI class. This time, when we iterate through the Properties_ and Methods_ collections, we store them in variables (strProperties and strMethods, respectively) rather than displaying them to the screen. Finally, we concatenate the results and use MsgBox to display them. Here’s the result of selecting the Win32_Share class.

Note. If this were what we were after, rather than just an intermediate step, we’d take a little more care in the presentation – indicating where the properties stop and the methods begin for instance.

screenshot

Let’s wrap things up by presenting the property and method information in the body of our HTA. We’ll create a couple of text boxes in which to store the information. Add two <textarea> tags to the body section of your HTA following the <select> tag:

<body onLoad=FillClassDropDown>
<select onChange=HandleClassChange name="WMIClasses"></select><p> 
<textarea name="Properties"></textarea>
<textarea name="Methods"></textarea>
</body>

The HTA should now look something like the following:

screenshot

Note. Instead of shutting down and restarting your HTA to see your changes, you can right-click within the body of the HTA and select Refresh.

Now we just need to fill in these text boxes with properties and methods, rather than displaying them all munged together in a message box. This is quite straightforward. We simply change this line of code in the HandleClassChange subroutine

MsgBox strProperties & strMethods

and replace it with these two lines of code that treat properties and methods separately, displaying them in their respective text boxes:

Properties.Value = strProperties
Methods.Value    = strMethods

The result would be quite a useful WMI browsing tool, were it not for the fact that the property and method text boxes are too short to be very readable.

screenshot

But that’s easy enough to fix. In your <textarea> tags, specify the number of rows and columns to include in your text boxes. You might need to fiddle with the exact numbers to get something readable.

<textarea name="Properties" rows="30" cols="45"></textarea>
<textarea name="Methods"    rows="30" cols="45"></textarea>

Note. If you want to get fancy, you could configure the number of rows and columns dynamically in accordance with the number (and length) of the properties and methods associated with a given WMI class.

screenshot

We’ve come a long way in this column. We’ve conquered the challenge of melding the WMI class script with the property-and-method script from the previous issue and we’ve ended up with something that mimics some of the basic functionality of the wbemtest tool.

Why did we bother creating a tool that has significantly less functionality than an existing tool? For one thing, along the way we learned some valuable WMI and HTA scripting techniques that will serve you well. Additionally, you now have a WMI browsing tool that you can build upon. You can customize and expand it to fit your particular needs. And if you want to dive into the Scriptomatic and figure out how it works, you’re in a much better position to do so.

Bonus – Auto-Generating Scripts

While it’s great to have your own scripting tool for rooting through the respository, the magic of the Scriptomatic lies in its ability to auto-generate scripts. Let’s have a quick look at how you might go about adding that functionality to our little HTA.

WMI scripts usually involve a significant amount of boilerplate code, with only a few real parameters to that code. The simplest case, and the one that elevated the Scriptomatic to its current status in the scripting world, is a WMI script that displays the properties of a given WMI class.

A typical script in this genre looks like the following:

Set objWMIService = GetObject("winmgmts:")
Set colInstances = objWMIService.ExecQuery("SELECT * FROM <wmi_class>") 
For Each objInstance In colInstances
   WScript.Echo objInstance.<wmi_class_property>
Next

Note. There will be as many of the WScript.Echo lines as there are properties associated with the given WMI class.

We already know how to retrieve WMI classes – we can use that knowledge to populate the <wmi_class> parameter. We also know how to retrieve the properties of a given class, so we can use that knowledge to populate the <wmi_class_property> parameters. But how do you go about “generating” script code? Well, script code is just text, so you use the same mechanisms you use for generating any type of textual output.

Let’s add a “Show Code” button to our HTA. We’ll hook it up to a subroutine named (oddly enough) ShowCode, where we’ll take a shot at auto-generating a Scriptomatic-like script. Start by adding an <input> tag to the <body> section of your HTA following the <select> tag, like this:

<body onLoad=FillClassDropDown>
<select onChange=HandleClassChange name="WMIClasses"></select><p> 
<input onClick=ShowCode type="submit" value="Show Code"></input><p>
<textarea name="Properties" rows="30" cols="45"></textarea>
<textarea name="Methods" rows="30" cols="45"></textarea>
</body>

Then add the corresponding subroutine, ShowCode. You can slip it in below your other subroutines.

Sub ShowCode
   MsgBox "I show code"
End Sub

It obviously doesn’t do much just yet. Let’s get it to at least output the typical script boilerplate.To begin with, just cut and paste the boilerplate code we looked at a moment ago and put a MsgBox " at the beginning of each line and a closing " at the end of each line, resulting in the following:

MsgBox "Set objWMIService = GetObject("winmgmts:")"
MsgBox "Set colInstances = objWMIService.ExecQuery" & _
"("SELECT * FROM <wmi_class>")"
MsgBox "For Each objInstance In colInstances"
MsgBox "   WScript.Echo objInstance.<wmi_class_property>"
MsgBox "Next"

Next, work your way through the code and double up the internal quotation marks, resulting in the following, which you can embed in your subroutine:

Sub ShowCode
MsgBox "Set objWMIService = GetObject(""winmgmts:"")"
MsgBox "Set colInstances = objWMIService.ExecQuery" & _
    "(""SELECT * FROM <wmi_class>"")"
MsgBox "For Each objInstance In colInstances"
MsgBox "   WScript.Echo objInstance.<wmi_class_property>"
MsgBox "Next"
End Sub

Here’s the result; not quite what we were after. Each line of the script is displayed in its own message box.

screenshot

We can easily fix this by storing all the lines in a variable, strCode, and then displaying that variable with a single call to MsgBox. The ShowCode subroutine now looks like this:

Sub ShowCode
 strCode = strCode & "Set objWMIService = GetObject(""winmgmts:"")"
 strCode = strCode & "Set colInstances =  objWMIService.ExecQuery" & _
    "(""SELECT * FROM <wmi_class>"")"
 strCode = strCode & "For Each objInstance In colInstances"
 strCode = strCode & "   WScript.Echo objInstance.<wmi_class_property>"
 strCode = strCode & "Next"
 MsgBox(strCode)
End Sub

The resulting script displays in a single message box. Unfortunately, the script is somewhat unreadable because it doesn’t include line breaks.

screenshot

Adding line breaks in the form of vbCrLf constants, the subroutine is now:

Sub ShowCode
    strCode = strCode & "Set objWMIService = GetObject(""winmgmts:"")" & vbCrLf
strCode = strCode & "Set colInstances = objWMIService.ExecQuery" & _
    "(""SELECT * FROM <wmi_class>"")" & vbCrLf
strCode = strCode & "For Each objInstance In colInstances" & vbCrLf
strCode = strCode & "   WScript.Echo objInstance.<wmi_class_property>" & vbCrLf
strCode = strCode & "Next" 
MsgBox(strCode)
End Sub

And the output looks much better:

screenshot

Of course, we don’t really want our script code displayed in a message box. Let’s create a text box for it on our HTA. Modify the markup in the <body> section of your HTA to look like this:

<body onLoad=FillClassDropDown>
<select onChange=HandleClassChange name="WMIClasses"></select><p> 
<input onClick=ShowCode type="submit" value="Show Code"></input><p>
<textarea name="Properties" rows="5" cols="45"></textarea>
<textarea name="Methods" rows="5" cols="45"></textarea>
<textarea name="Code" rows="30" cols="93"></textarea>
</body>

We’ve added a new <textarea> in which to house the generated code and we’ve reduced the height of the Properties and Methods text boxes to accommodate by changing the number of rows in the respective <textarea> tags. Here’s what the result looks like:

screenshot

So, the next step is to display the generated code in the newly-added text box rather than the message box. This is a straightforward change. Just change this line in the ShowCode subroutine

MsgBox(strCode)

to this

Code.Value = strCode

The result is really starting to look like the Scriptomatic.

screenshot

The code we’re generating still has placeholder text for the WMI class (<wmi_class>) and its properties (<wmi_class_property>). Let’s fix that. We know that the drop-down list at the top of the HTA houses the WMI class name, and we’ve already written a little piece of script to find the value of the currently selected option. So, we just need to modify the ShowCode subroutine to determine the selected WMI class and insert it in place of the current <wmi_class> placeholder text. We do this by adding a For Each loop to loop through the options that were selected in the WMIClasses text box. We assign the selected task to a variable (strClass), and then substitute our <wmi_class> placeholder with that variable. Here’s the updated ShowCode subroutine:

Sub ShowCode

  For Each objOption In WMIClasses.Options
      If objOption.Selected = True Then
         strClass = objOption.Text
      End If
  Next

  strCode = strCode & "Set objWMIService = GetObject(""winmgmts:"")" & vbCrLf
  strCode = strCode & "Set colInstances = objWMIService.ExecQuery" & _
    "(""SELECT * FROM " & strClass & """)" & vbCrLf
  strCode = strCode & "For Each objInstance In colInstances" & vbCrLf
  strCode = strCode & "   WScript.Echo objInstance.<wmi_class_property>" &    vbCrLf
  strCode = strCode & "Next" 
  Code.Value = strCode
End Sub

Note. The trickiest part of the above code is getting the quotation marks right. Remember that when you break a string in order to insert something into it, you need to “plug” both ends of the break with a quotation mark. You then need to insert a couple of ampersands and something between those ampersands. The progression looks like this: “one_two_four” -> “one_two” “four” -> “one_two” & & “four” -> “one_two” & “_three_” & “four”. If you’re not comfortable with slicing and dicing strings, you might find enlightenment in the VBScript Special Characters Sesame Script column on the Script Center.

We now have some truly dynamic code generation. Select a new WMI class, click the Show Code button, and your selection will be reflected in the generated script.

screenshot

All that’s left is to inject the appropriate properties in place of the <wmi_class_property> placeholder text; we’re already displaying the properties, so we clearly have the code we need – we just need to put it in the right place.

Modify the ShowCode subroutine, leveraging code from the HandleClassChange subroutine, to look like this:

Sub ShowCode

For Each objOption In WMIClasses.Options
  If objOption.Selected = True Then
   strClass = objOption.Text
  End If
Next

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}root\cimv2")
Set objClass = objWMIService.Get(strClass)

strCode = strCode & "Set objWMIService = GetObject(""winmgmts:"")" & vbCrLf
strCode = strCode & "Set colInstances = objWMIService.ExecQuery" & _
    "(""SELECT * FROM " & strClass & """)" & vbCrLf
strCode = strCode & "For Each objInstance In colInstances" & vbCrLf

For Each objProperty In objClass.Properties_
  strCode = strCode & "   WScript.Echo objInstance." & objProperty.Name & vbCrLf
Next

strCode = strCode & "Next" 
Code.Value = strCode
End Sub

Basically, we’ve just wrapped our property output line within a For Each loop that iterates through all of the properties. And while the result isn’t quite as inspiring as Virtual Earth, it is a great start at your very own, customized Scriptomatic.

screenshot

Well folks, that’s probably more than enough learning for one article. We’ve started with a couple of simple WMI scripts and pretty much recreated the Scriptomatic. Hopefully we haven’t spoiled the magic of our favorite little utility and we look forward to seeing what you create. Let us know if you do craft something interesting and tell us whether you enjoyed the column.

Oh, and in case you lost your way with all the cutting and pasting, here’s the script code for that last HTA:

<head>
<title>HTA Test</title>
<HTA:APPLICATION 
     APPLICATIONNAME="HTA Test"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
     WINDOWSTATE="normal"
>
</head>

<script language="VBScript">
Sub FillClassDropDown

   Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}root\cimv2")
   Set colClasses = objWMIService.SubClassesOf
   
   For Each objClass In colClasses
      If Left(objClass.Path_.Class,6) = "Win32_" Then
         Set objNewOption = document.createElement("OPTION")
         objNewOption.Text = objClass.Path_.Class
         WMIClasses.options.Add(objNewOption)
      End If
   Next

 
End Sub

Sub HandleClassChange
   For Each objOption In WMIClasses.Options
      If objOption.Selected = True Then
      strClass = objOption.Text
      Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}root\cimv2")
      Set objClass = objWMIService.Get(strClass)

      For Each objProperty In objClass.Properties_
          strProperties = strProperties & objProperty.Name & vbCrLf
      Next
   
      For Each objMethod In objClass.Methods_
         strMethods = strMethods & objMethod.Name & vbCrLf
      Next

      Properties.Value = strProperties
      Methods.Value    = strMethods
      End If
   Next
End Sub

Sub ShowCode
For Each objOption In WMIClasses.Options
      If objOption.Selected = True Then
     strClass = objOption.Text
  End If
Next

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}root\cimv2")
Set objClass = objWMIService.Get(strClass)

strCode = strCode & "Set objWMIService = GetObject(""winmgmts:"")" & vbCrLf
strCode = strCode & "Set colInstances = objWMIService.ExecQuery" & _
    "(""SELECT * FROM " & strClass & """)" & vbCrLf
strCode = strCode & "For Each objInstance In colInstances" & vbCrLf

For Each objProperty In objClass.Properties_
   strCode = strCode & "   WScript.Echo objInstance." & objProperty.Name & vbCrLf
Next

strCode = strCode & "Next" 
Code.Value = strCode
End Sub

</script>

<body onLoad=FillClassDropDown>
<select onChange=HandleClassChange name="WMIClasses"></select><p> 
<input onClick=ShowCode type="submit" value="Show Code"></input><p>
<textarea name="Properties" rows="5" cols="45"></textarea>
<textarea name="Methods" rows="5" cols="45"></textarea>
<textarea name="Code" rows="30" cols="93"></textarea>
</body>
</html>