Welcome to Your Nightmare
Audit the software on users' machines with this month's handy script.
- By Chris Brooke
Your phone rings. It’s one of your users—the user who has come to be
known as The Hurricane due to his capacity to leave destruction in his
wake. “I can’t get my e-mail!” “I can’t print!” “My computer is locked
You arrive at Hurricane’s desk and begin looking for the problem. Usually,
Hurricane offers little or no help—providing completely useless clues
such as, “It just died,” or “It’s too slow.” Today, however, Hurricane
is feeling generous.
“I was installing The Bridges of Madison County screensaver…” A cold
chill runs through you. You begin to shake.
It’s OK. We’ve all been there. “Hi, my name is Chris, and my users are
idiots.” (Chorus) “Hi, Chris!” There may still be hope. Perhaps you can
write a script to remotely connect to users’ machines and enumerate installed
software. If you schedule it to run regularly, you can review the listing
for any new (and probably unauthorized) software and get it removed before
it’s too late!
<?xml version="1.0" ?>
This script enumerates the MSI installed applications as
well as all installed hotfixes.
This script uses WMI to connect to the local or
remote computer and return a list of installed
applications and hotfixes
C:\cscript ListApps.wsf /Target:value /File:value
of the target computer"
helpstring="The name of the
text file to store the data"
Dim objFile, objWMI, colSoftware, clsSoftware,
clsHotFix, strComputer, strFile
strComputer = WScript.Arguments.Named.Item("Target")
Set objFile = objFSO.OpenTextFile(strFile,
Set objWMI =
& strComputer & "\root\cimv2")
Set colSoftware = objWMI.ExecQuery(
"Select * from Win32_Product")
"Computer Name: " & strComputer
' Get the installed software data
For Each clsSoftware in colSoftware
objFile.WriteLine "Caption: " & clsSoftware.Caption
objFile.WriteLine "Description: "
objFile.WriteLine "Identifying Number:
objFile.WriteLine "Install Date: "
objFile.WriteLine "Location: "
objFile.WriteLine "Install State: "
objFile.WriteLine "Name: " & clsSoftware.Name
objFile.WriteLine "Package Cache: "
objFile.WriteLine "SKU Number: " & clsSoftware.SKUNumber
objFile.WriteLine "Vendor: " & clsSoftware.Vendor
objFile.WriteLine "Version: " & clsSoftware.Version
= objWMI.ExecQuery("Select * from Win32_QuickFixEngineering")
' Get the
For Each clsHotFix in colHotFixes
objFile.WriteLine "Description: " & clsHotFix.Description
objFile.WriteLine "ID: " & clsHotFix.HotFixID
objFile.WriteLine "Installation Date: "
objFile.WriteLine " Installed By: "
Did you notice? I gave you a bonus in this script. That’s right!
In addition to listing all software installed using the Windows Installer,
this script also enumerates all installed hotfixes. This means that while
you’re reviewing the listings to see if any of your users installed “Dark
Age of Camelot,” you’ll also be able to ensure that they’re completely
up to date with any required hot fixes.
A Minor Limitation
While this script is very powerful, it does have one significant
weakness: It’ll only itemize software installed using the Windows Installer.
Granted, most contemporary software uses Windows Installer, but it’s something
to keep in mind. When I ran this script on my notebook computer and compared
it to the listing in my “Add/Remove Programs” applet, the script didn’t
show five applications.
Since I began this series on using WMI to perform administrative
tasks, I’ve received a few e-mails from people having difficulty running
them in different environments (I use XP). For that reason, I’m giving
you another bonus this month: A diagnostic script that returns the version
numbers of the various scripting elements.
In the interest of space, I’ve written this as a .VBS script (complete
with “standard” VBScript color coding, as opposed to the XML color coding
I use in .WSF scripts). If you wish, you can put this in a .WSF file,
' This script writes the version number of the individual
' scripting components to the screen. It can also be modified
' to write the information to a file and/or run on multiple
Dim objWMI, colWMISettings, clsWMISetting, objShell,
' Display WSH version
Version: " & WScript.Version
' Display WMI version
Set objWMI = GetObject(
= objWMI.ExecQuery("Select * from
For Each clsWMISetting
Wscript.Echo "WMI Version:
" & clsWMISetting.BuildVersion
' Display ADSI version
Set objShell = CreateObject("WScript.Shell")
strADSIVersion = objShell.RegRead(
"HKLM\SOFTWARE\ Microsoft\Active Setup\
= vbEmpty Then
strADSIVersion = objShell.RegRead(
= vbEmpty Then
strADSIVersion = "ADSI is not installed."
strADSIVersion = "2.0"
WScript.Echo "ADSI Version: " & strADSIVersion
Compare the results of this script with the list below. It outlines the
recommended minimum version numbers for each scripting element.
- WSH (Win9x, NT 4/2000/XP)—V5.6
- WMI (Win9x, NT 4/2000)—1085.0005, (WinXP)—2600.0000
- ADSI (Win9x, NT 4/2000/XP)—5,0,00,0
If any component on your system is older than the ones on this list,
download the most recent version from the appropriate Microsoft site below.
Chris Brooke, MCSE, is a contributing editor for Redmond magazine and director of enterprise technology for ComponentSource. He specializes in development, integration services and network/Internet administration. Send questions or your favorite scripts to firstname.lastname@example.org.