Hey, Scripting Guy! Question

Hey, Scripting Guy! I am looking for a script that will list program identifiers on my computer. Have one of those?

-- CG

Hey, Scripting Guy! Answer

Hello CG,

Microsoft Scripting Guy Ed Wilson here. It is interesting you ask for a script that will list program identifiers on your computer. Program identifiers (PIDs) are the secret word combinations that are used when creating objects in VBScript. Knowing what PIDs are available and how to use them can open many new scripting doors while working in either VBScript or in Windows PowerShell.

When I flew to Sao Paulo, Brazil, a few years ago to teach a VBScript class at our Microsoft Office (I fell in love with feijoada while I was there), I wrote a really cool script while on the plane. This script trolled the registry (HKEY_CLASSES_ROOT) to look for PIDs. When a PID was found, the script would call CreateObject and pass the PID to it. The script would then look for errors. If no error was generated, the PID was written to a text file. Because I was calling CreateObject, you might have guessed that I wrote the script in VBScript.

As luck would have it, the first day I was in Sao Paulo, I was asked by one of my students about masking a password for a script. I went back to the hotel room, and searched the Internet, but was unable to find anything. On a lark, I searched my text file of PIDs for an object that might have something to do with scripts and passwords. I found a COM object named scriptpw.password. With a name like that, it is bound to have something to do with passwords and scripts. As a matter of fact, it does have something to do with masking passwords. We even have a Hey, Scripting Guy! article that talks about this: How Can I Mask Passwords Using an Input Box? Back then, there was no documentation for the scriptpw.password object (and certainly no Hey, Scripting Guy! article), so how did I figure out if I could use the object, and more importantly, how to use it? I opened the COM object in an object browser. Object browsers allow you to look at objects in a graphical fashion. Many programming environments have object browsers, and you can even download them from the Internet. If you have installed the Windows software development kit (SDK) to your computer, you will have an object browser available to you, as seen here:

Image of object browser in Windows SDK

As you can see, the scriptpw.password class contains a single method that is called Get-Password. The method takes no arguments and returns a string. Armed with that information, I was able to write the script the student required. 

(The scriptpw.password object is no longer available beginning with Windows Vista. However, Windows PowerShell includes the Get-Credential and the Read-Host cmdlets that can be used instead.)

A VBScript that will list PIDs is seen here. I found it by searching for “Program ID” in the new TechNet Script Center Gallery.  


On Error Resume Next

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

Set colItems = objWMIService.ExecQuery _
    ("Select * from Win32_ProgIDSpecification")

For Each objItem in colItems
    Wscript.Echo "Caption: " & objItem.Caption
    Wscript.Echo "Check ID: " & objItem.CheckID
    Wscript.Echo "Name: " & objItem.Name
    Wscript.Echo "Parent: " & objItem.Parent
    Wscript.Echo "ProgID: " & objItem.ProgID

The ListProgIDs.vbs script uses the Win32_ProgIDSpecification WMI class. To query the WMI class, the ExecQuery method is used from the WMI service object. The WMI query returns a collection of information that is stored in the colItems variable. The For Each Next statement is used to walk through the collection, and Wscript.Echo prints out each property.

In the ListProgIds.ps1 script that follows this paragraph, the Get-WmiObject cmdlet is used to query the Win32_ProgIDSpecification WMI class. Instead of storing the results in a variable, the results are pipelined to the Format-Table cmdlet. There is much redundancy between the properties of the Win32_ProgIDSpecification WMI class. Therefore, a better display of information can be made by creating a table and displaying the progID property and the description property. The autosize property will size the table to avoid wasting space. The more function is used to display one page of information at a time. The complete ListProgIDs.ps1 script is seen here.


Get-WmiObject -Class Win32_ProgIDSpecification |

Format-Table –Property ProgID, description -AutoSize | more

The same display information that is returned by the ListProgIDs.vbs script could be obtained by not using the formatting cmdlets. The command could be written by using the gwmi alias (instead of the full Get-WmiObject). The revised command is seen here:

Gwmi win32_ProgIDSpecification

The ListProgIDs.ps1 script produces the output seen here:

Image of ListProgIDs.ps1 output

To explore the objects and find out what an object can do, you can use the New-Object cmdlet with the comobject parameter. This will create an instance of the object. You will want to use a variable to hold the object. This is seen here:

$access = New-Object –comobject Access.Application

With Windows PowerShell, you do not need to download and install an object browser, because you can use the Get-Member cmdlet to display the methods and the properties of the object. The syntax for the command is seen here:

$access | Get-Member

When you run the above command, the results seen here are displayed:

Image of results of running Get-Member cmdlet

Well, CG, that is all there is to listing PIDs. You can use a WMI class to list the PIDs. After you find a PID, you can look it up on MSDN or on the Script Center. You can also use the New-Object cmdlet to create an instance of the object and pass it to the Get-Member cmdlet. Keep in mind that all objects are not designed to be worked with directly.

Join us tomorrow as we continue exploring Script Center Gallery scripts. If you want to keep up to date on activities on the Script Center, follow us on Twitter or Facebook. If you have questions, you can post them on the Official Scripting Guys Forum, or send e-mail to scripter@microsoft.com. Until tomorrow, have a great day!


Ed Wilson and Craig Liebendorfer, Scripting Guys