Hunting for Objects

By The Microsoft Scripting Guys

Sesame Script

Welcome to Sesame Script, the column for beginning script writers. The goal of this column is to teach the very basics of Windows scripting for system administration automation. We’ll provide you with the information you’ll need to begin reading and understanding scripts and to start modifying those scripts to suit your own needs. If there’s anything in particular about scripting you’re finding confusing, let us know; you’re probably not alone.

Check the Sesame Script Archives to see past articles.

Download all the Sesame Script columns (from the very first column through the June, 2007 edition) in one easy-to-read, fully-searchable .chm file.

On This Page

The Hunt is On
Just Take It
WMI is a Good Place to Start
Script Center Tools
Microsoft Office
Other Applications
Windows PowerShell
Tally-Ho!

The Hunt is On

One of the questions we get frequently here at the Script Center is something along the lines of this: “Where do I find the objects and methods I need to do what I want to do in my script?” And you know, that’s a great question. Wouldn’t it be nice if we had a great answer for you?

Well, we don’t. Instead what we have are a lot of answers, some of them great, some not-so-great. The main problem, which you’ve probably already discovered, is that information on objects and methods is scattered - where you find it depends on the technology you need to use. For example, you’ll find information about Windows Management Instrumentation (WMI) in a different place than you’ll find information about Microsoft Office objects. We know this can be kind of a tough task sometimes, but we’re going to take a shot at helping you out as much as we can.

Note: If you don’t really understand the whole concept of objects, methods, and so on, read the Sesame Script article Class is in Session. Then come back here and all this will make more sense. It might not make a lot of sense, but it will make more sense than if you don’t know what objects are.

Just Take It

We here at the Script Center do not, under any circumstances, encourage, condone, or promote any illegal activities of any kind. We just needed to say that before we tell you that your best bet for finding the classes and properties that will do what you need is to find someone else who’s already found them and then steal their script. Technically it’s not stealing if you find it freely-available on the Internet, but you know what we mean. (Unless you work for certain groups at Microsoft, in which case - we’ll say this once more just for you - the Scripting Guys do not encourage, condone, or promote any sort of theft.) Obviously the best place to start is the Script Center, especially the Script Repository, the Hey, Scripting Guy! archive, the Community-Submitted Scripts Repository, and the Windows 2000 Scripting Guide (still applicable to more recent versions of Windows). But on the off-chance that you don’t find what you need there, just search the Internet, there’s a lot out there if you can find it.

Of course, there’s always the possibility that, after all your searching, you’ll still need to find your own solution. For that, you’ll then need some tools to help you out.

WMI is a Good Place to Start

We tend to work under the assumption that our readers are system administrators. This isn’t the case for everyone, and if you’re not a system administrator don’t worry;, all this will apply to you too. But given that assumption, we’re going to start with some tools that will help you write scripts to manage your Windows systems. In managing Windows you’ll most often work with WMI. There are various tools available for exploring WMI objects, but the one we’re going to focus on first is the Windows Management Instrumentation Tester, more commonly referred to as WbemTest (web-em-test).

WbemTest

We call this WbemTest rather than WMI Tester for the simple reason that, in order to run this tool, all you need to do is type wbemtest at the command prompt or in the Run box (the Search box in Windows Vista) and WbemTest will run. Here’s what it looks like:

WbemTest Step 1

WbemTest is a good tool because, like VBScript, WSH, WMI, Notepad, and various other things you can use to write system administration scripts, WbemTest ships with Windows. You don’t need to install anything extra to use it. It is, however, a little intimidating to look at when you first open it up. As you can see, most of the buttons are grayed out.

To get started with WbemTest, click the Connect button. That will bring up this dialog box:

WbemTest Step 2

The main thing to notice here is the Namespace field up at the top. Most of the WMI classes are located in the root\cimv2 namespace. In Windows Vista this field is filled in, by default, with root\cimv2. However, in previous versions of Windows the default namespace is root\default; more often than not, you’ll want to change that to root\cimv2.

Note: How do we know what namespace to use? Well, it will probably be either root\default or root\cimv2, and, unless you’re working with the registry it’s most likely root\cimv2. That’s the namespace where most of the classes of interest to system administrators are found.

Click Connect. That will bring you back to the main window, but this time all those disabled buttons are enabled:

WbemTest Step 3

Click the Enum Classes button. In the Superclass Info dialog box, click the Recursive button, then click OK:

WbemTest Step 4

This will bring up a dialog box showing the names of all the WMI classes in the root\cimv2 namespace:

WbemTest Step 5

At this point you’ll mostly want to scroll through the list looking for class names that seem to match what it is you want to do. For most operating system tasks you’ll want to scroll down to the classes that begin with Win32_, as we’ve done here. For example, if we want to find information on the disk drives on a computer, the Win32_DiskDrive class sounds like a good bet. (Not that the Scripting Guys encourage, condone, or promote betting.) Let’s choose that one: double-click on Win32_DiskDrive. Here’s what you should see:

WbemTest Step 6

Click Hide System Properties to remove some of the clutter. At this point you have a list of all the properties and methods associated with the Win32_DiskDrive class. If, by looking at property and method names, you’re still not sure whether this is the object you’re looking for, you can try clicking the Instances button. That will bring up a dialog box like this:

WbemTest Step 7

Here we’ve simply queried the local computer for all instances of the Win32_DiskDrive class. As you can see, in our case that returned information on one disk drive. Double-click the drive listed. This will bring up the same window we had previously, the one that showed us all our properties and methods. This time, however, most of the properties have values in them:

WbemTest Step 8

For example, you can see the BytesPerSector for this disk drive is 512. If that’s the kind of information you were hoping to find, then you obviously chose the right class; if not, it’s back to the drawing board: close this window and go back to the query that listed all the classes and choose another one.

Okay, not the easiest way to find what you’re looking for, but sometimes the most successful. Now let’s take a look at another useful tool.

More Information

To find out more about WbemTest, check out the Scripting Week 1 Webcast WMI Is Not a Four-Letter Word. About 30 minutes in there’s a more in-depth discussion of how to work with WbemTest.

For a really thorough explanation and walk-through of WbemTest, see the article Wbem What?.

Scriptomatic

Scriptomatic is an HTML Application (HTA) you can download from the Script Center that allows you to query for WMI classes and that will build scripts for you in several different scripting languages. Here’s what it looks like:

Scriptomatic

We’re not going to go into a lot of detail about using the Scriptomatic. There’s an entire readme devoted to the Scriptomatic that’s really more a piece of classic literature than a readme file. Okay, not so much classic literature, but it definitely ranks as one of our more entertaining works.

But just to give you an idea of what this is all about, the Scriptomatic provides drop-down lists that allow you to select the namespace (no more guessing there) and the WMI class you want to look at. It outputs a script that you can edit right there in the HTA and that you can run (again, right from the HTA, or you can copy and paste it to a script file) to see all the properties and their values on a given computer - local or remote. As you can see, you can also choose from among several scripting languages, and you can choose the format of the output.

Again, still a matter of hunting down classes and properties that look right, but the hunt’s at least getting a little more fun, right? Okay, maybe not.

Note to Windows Vista Users: Unfortunately the User Account Control (UAC) in Windows Vista has wreaked a bit of havoc with our dear Scriptomatic. When UAC is turned on, access to various namespaces and classes is restricted. What that means is that if you download Scriptomatic and run it on Windows Vista with UAC turned on, Scriptomatic will crash.

Now for the semi-good news: Because Scriptomatic is an HTA, you can simply go in and, with some well-placed On Error Resume Next statements, you can prevent Scriptomatic from crashing. The downside to this is that Scriptomatic will still try to connect to those namespaces, and it will try for a long time. That means starting Scriptomatic will be very, very slow. But once it’s running it will work pretty well.

Now for the very good news: If you run Scriptomatic with elevated privileges, it will run just fine - no crashing, no slow starting, no problems. To run Scriptomatic under elevated privileges, click on the Start button (or whatever that button is in Windows Vista) and under All Programs/Accessories right-click on Command Prompt and choose Run as Administrator. When the command prompt opens, navigate to the folder where you’ve downloaded Scriptomatic and run the HTA file from the command line. Scriptomatic will start normally and run normally.

WMI Code Creator

Okay, one more and we’re done looking at WMI classes. We just want to give a quick mention to the WMI Code Creator, which is also downloadable from the Script Center. It’s a lot like Scriptomatic but it’s a full-blown executable and has a little more functionality. Here’s a glimpse of the WMI Code Creator:

WMI Code Creator

Oops, One More

Did we say we were done with WMI? Sorry, not just yet. There’s one more place to look for WMI information, and that’s the WMI SDK. SDKs are typically designed for developers and can be a little tough to read for scripters, but we’ve provided a How To article on reading SDKs.

Script Center Tools

Not to toot our own horn here (we know, too late), but the Script Center has even more freely-downloadable tools that can help you out. Just check out our Scripting Tools and Utilities page to find such inspiring tools as the ADSI Scriptomatic (no, sorry, the ADSI Browser is still not available), Tweakomatic, and HTA Helpomatic.

Microsoft Office

There are really two places to get information on scripting the Office products (besides that stealing thing we mentioned that isn’t really stealing).One option is to look at the Object Browser in one of the Office products. To do that, you first need to open the Visual Basic Editor. In Office 2003 you do this by selecting Visual Basic Editor under Macro in the Tools menu. In Office 2007 you’ll probably have to do some digging to find this. Once the Visual Basic Editor is open, press F2 to open the Object Browser:

Excel Object Browser

Here you’ll get a list of all the classes available to Office products along with their properties and methods (Members). As usual, you’re still trying to find a class name that seems to fit what you want to do, but it’s pretty easy to scroll through and look at everything.

Your other option for Office is the Developer Reference. Let’s look at an example:

Let’s say you want to change the name of a worksheet within a particular workbook. First you can go to the Excel 2007 Developer Reference; you might even want to just start at the Excel Object Model Reference. From there if you scroll down you’ll eventually find a class named Worksheet. It’s a pretty good bet that if we want to change the name of a worksheet, we’ll need to use a Worksheet object. Under Worksheet you’ll find a property named Name:

Excel Object Model

As you can see (sort of), the Name property “Returns or sets a String value representing the name of the object.” In other words, assign a string value to the Name property to name your worksheet. Pretty simple.

Note: If you’re interested in doing this, here’s the script:

Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Set objWorkbook = objExcel.Workbooks.Add()
Set objWorksheet = objWorkbook.Worksheets(1)
objWorksheet.Name = "Invoice"

We start by creating a reference to the Excel.Application object and setting its Visible property to True. This gives us an instance of Excel we can see onscreen. We then use the Add method to add a new worksheet to the workbook, then we create a new Worksheet within that workbook. Finally, we use the Name property of our Worksheet to change the name of the worksheet, in this case to “Invoice.”

Other Applications

As with everything else we’ve talked about in this column, finding information on other applications is usually a matter of searching around in the SDK. Unfortunately not everything you find in the SDK will work in a script. Remember, SDKs are typically written for developers, not scripters, so the examples could be a little confusing (they might even be written in C++), and many of the classes aren’t even available to scripts.

Oh, but wait…there’s one more thing you can try: Windows PowerShell.

Windows PowerShell

Now, you might be thinking “Hey, I’m not working with Windows PowerShell, I’m working with [fill in your scripting language of choice here]. Windows PowerShell won’t help me.” (Of course, you might also be thinking “Great, I’m using Windows PowerShell right now.”) Well, guess what? Windows PowerShell can help you whether you’re writing your scripts in Windows PowerShell or not. You can find out all sorts of information about the methods and properties of a class simply by using the Get-Member cmdlet.

COM Objects

Keep in mind that you still have to go through the sometimes-painful processes we already talked about of hunting down the class you want - Windows PowerShell doesn’t help with that. But once you know the class, PowerShell can tell you all about it. For example, let’s say you want to find out about a regular old COM object like the Wscript.Shell object. Just enter this command in Windows PowerShell:

new-object -com wscript.shell | get-member

Before we find out about a particular class, we need to create an object reference to that class. That’s why we need to start by using the New-Object cmdlet, a cmdlet that just happens to create an object reference. We pass the -com parameter with a value of wscript.shell to tell the New-Object cmdlet that the object we want to create is a COM object , and that the name of the class is Wscript.Shell. Here’s what PowerShell returns:

TypeName: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090}

Name                     MemberType            Definition
----                     ----------            ----------
AppActivate              Method                bool AppActivate (Variant, Variant)
CreateShortcut           Method                IDispatch CreateShortcut (string)
Exec                     Method                IWshExec Exec (string)
ExpandEnvironmentStrings Method                string ExpandEnvironmentStrings (string)
LogEvent                 Method                bool LogEvent (Variant, string, string)
Popup                    Method                int Popup (string, Variant, Variant, Variant)
RegDelete                Method                void RegDelete (string)
RegRead                  Method                Variant RegRead (string)
RegWrite                 Method                void RegWrite (string, Variant, Variant)
Run                      Method                int Run (string, Variant, Variant)
SendKeys                 Method                void SendKeys (string, Variant)
Environment              ParameterizedProperty IWshEnvironment Environment (Variant) {get}
CurrentDirectory         Property              string CurrentDirectory () {get} {set}
SpecialFolders           Property              IWshCollection SpecialFolders () {get}

As you can see, we have a list of all the methods and properties belonging to the Wscript.Shell object, along with the syntax and types of each.

Microsoft Office COM Objects

We can do the same thing with Office classes, but this gets a little tricky. The reason it gets a little tricky is the point we mentioned already - you need an object reference, not just a class name, in order to get information about the class. As you saw from our VBScript example earlier, it takes several steps to get some of the objects in an Office application. Let’s use our Worksheets object again as an example. You can copy this to a script or you can run each of these lines individually from the PowerShell command line:

$a = new-object -com excel.application

$wb = $a.workbooks.add()
$ws = $wb.worksheets.item(1)

$ws | get-member

$a.Quit()

We first use the New-Object cmdlet to create a reference to the Excel.Application object, storing that object in the variable $a. Next we add a new workbook:

$wb = $a.workbooks.add()

Now it’s time to get the object reference to the Worksheet object. We do this by assigning the Item property, with a parameter of 1, of the Worksheets object to the variable $ws. The Item property contains a collection of all the worksheets in a workbook - you reference individual worksheets with the parameter. In this case we’re retrieving a reference to the first (Item 1) worksheet in the collection:

$ws = $wb.worksheets.item(1)

Now we simply pipe our Worksheet object reference (stored in the $ws variable) to the Get-Member cmdlet:

$ws | get-member

We then call the Quit method on our Excel application and we’re done. In the meantime, here’s a sampling of what the Get-Member cmdlet has returned:

TypeName: System.__ComObject#{000208d8-0000-0000-c000-000000000046}

Name                              MemberType            Definition
----                              ----------            ----------
Activate                          Method                void Activate ()
Arcs                              Method                IDispatch Arcs (Variant)
Buttons                           Method                IDispatch Buttons (Variant)
Calculate                         Method                void Calculate ()
ChartObjects                      Method                IDispatch ChartObjects (Variant)
CheckBoxes                        Method                IDispatch CheckBoxes (Variant)
CheckSpelling                     Method                void CheckSpelling (Variant, Variant, Variant, Variant)
…
Range                             ParameterizedProperty Range Range (Variant, Variant) {get}
Application                       Property              Application Application () {get}
AutoFilter                        Property              AutoFilter AutoFilter () {get}
AutoFilterMode                    Property              bool AutoFilterMode () {get} {set}
Cells                             Property              Range Cells () {get}
CircularReference                 Property              Range CircularReference () {get}
CodeName                          Property              string CodeName () {get}
Columns                           Property              Range Columns () {get}
Comments                          Property              Comments Comments () {get}
…

Note: We did run into one issue while working with this script. Even though we called the Quit method at the end to terminate the Excel application, we continued to have a running instance of the excel.exe process on our machine. Here’s a revised script that includes a function that will actually terminate the process when you close Excel (thanks to our good friend Kent Finkle):

function Release-Ref ($ref) {
([System.Runtime.InteropServices.Marshal]::ReleaseComObject(
[System.__ComObject]$ref) -gt 0)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers() 
}
$a = new-object -com excel.application
$wb = $a.workbooks.add()
$ws = $wb.worksheets.item(1)
$ws | get-member
$a.quit()
$b = Release-Ref($ws)
$b = Release-Ref($wb)
$b = Release-Ref($a)

Basically all we’ve done here is use some .NET objects to release all references to the Excel objects we created - this will remove the excel.exe process when the Quit method is called.

Maybe that does seem like a lot of work, but remember that we were looking for an object that we needed to spend some time retrieving. If we wanted to retrieve the methods and properties of the Excel.Application object, well, that’s pretty simple:

new-object -com excel.application | get-member

.NET Objects

You can also use the Get-Member cmdlet to retrieve information on .NET classes. However, there are various ways of retrieving those objects depending on which class you’re looking at. We’re already pretty far beyond the scope of our typical Sesame Script - retrieving .NET objects is going to have to be a topic for a future Windows PowerShell article. But here’s a very simple example of retrieving properties from a .NET object, in this case the System.Version object:

new-object -typename system.version | get-member

Here we’re once again using the New-Object cmdlet to get a reference to the object. Notice this time, though, that we didn’t use the -com parameter; instead we used the -typename parameter. We then specified the class we want to retrieve a reference to, the System.Version class. Now that we have the object reference we can pipe it to the Get-Member cmdlet, and we have our output:

TypeName: System.Version

Name              MemberType Definition
----              ---------- ----------
Clone             Method     System.Object Clone()
CompareTo         Method     System.Int32 CompareTo(Object version), System.Int32 CompareTo(Version value)
Equals            Method     System.Boolean Equals(Object obj), System.Boolean Equals(Version obj)
GetHashCode       Method     System.Int32 GetHashCode()
GetType           Method     System.Type GetType()
get_Build         Method     System.Int32 get_Build()
get_Major         Method     System.Int32 get_Major()
get_MajorRevision Method     System.Int16 get_MajorRevision()
get_Minor         Method     System.Int32 get_Minor()
get_MinorRevision Method     System.Int16 get_MinorRevision()
get_Revision      Method     System.Int32 get_Revision()
ToString          Method     System.String ToString(), System.String ToString(Int32 fieldCount)
Build             Property   System.Int32 Build {get;}
Major             Property   System.Int32 Major {get;}
MajorRevision     Property   System.Int16 MajorRevision {get;}
Minor             Property   System.Int32 Minor {get;}
MinorRevision     Property   System.Int16 MinorRevision {get;}
Revision          Property   System.Int32 Revision {get;}

Tally-Ho!

That’s about it for our article on hunting down classes, methods, properties, and so on. No animals were harmed during the making of this article, with the exception of the spider the Scripting Dog just ate. And maybe anyone who happened to hit their head on their desk when they fell asleep reading this article.