Mr. Script
Welcome to Your Nightmare
Audit the software on users' machines with this month's handy script.
- By Chris Brooke
- 11/01/2002
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
up!”
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" ?>
<package>
<comment>
ListApps.wsf
This script enumerates the MSI installed applications as
well as all installed hotfixes.
</comment>
<job>
<runtime>
<description>
This script uses WMI to connect to the local or
remote computer and return a list of installed
applications and hotfixes
</description>
<example>
C:\cscript ListApps.wsf /Target:value /File:value
</example>
<named
name="Target"
helpstring="The name
of the target computer"
type="string"
required="true"
/>
<named
name="File"
helpstring="The name of the
text file to store the data"
type="string"
required="true"
/>
</runtime>
<object
id="objFSO" progid="Scripting.FileSystemObject"/>
<script language="VBScript">
<![CDATA[
Option Explicit
CONST ForAppending=8
Dim objFile, objWMI, colSoftware, clsSoftware,
colHotFixes,
clsHotFix, strComputer, strFile
strComputer = WScript.Arguments.Named.Item("Target")
strFile=WScript.Arguments.Named.Item("File")
Set objFile = objFSO.OpenTextFile(strFile,
ForAppending, True)
Set objWMI =
GetObject("winmgmts:{impersonationLevel=impersonate}!\\"
& strComputer & "\root\cimv2")
Set colSoftware = objWMI.ExecQuery(
"Select * from Win32_Product")
objFile.WriteLine
"Computer Name: " & strComputer
' Get the installed software data
For Each clsSoftware in colSoftware
objFile.WriteLine "Caption: " & clsSoftware.Caption
objFile.WriteLine "Description: "
& clsSoftware.Description
objFile.WriteLine "Identifying Number:
"
& clsSoftware.IdentifyingNumber
objFile.WriteLine "Install Date: "
& clsSoftware.InstallDate2
objFile.WriteLine "Location: "
& clsSoftware.InstallLocation
objFile.WriteLine "Install State: "
& clsSoftware.InstallState
objFile.WriteLine "Name: " & clsSoftware.Name
objFile.WriteLine "Package Cache: "
& clsSoftware.PackageCache
objFile.WriteLine "SKU Number: " & clsSoftware.SKUNumber
objFile.WriteLine "Vendor: " & clsSoftware.Vendor
objFile.WriteLine "Version: " & clsSoftware.Version
objFile.WriteLine
Next
objFile.WriteLine
"Hotfixes:"
Set colHotFixes
= objWMI.ExecQuery("Select * from Win32_QuickFixEngineering")
' Get the
installed hotfixes
For Each clsHotFix in colHotFixes
objFile.WriteLine "Description: " & clsHotFix.Description
objFile.WriteLine "ID: " & clsHotFix.HotFixID
objFile.WriteLine "Installation Date: "
& clsHotFix.InstallDate
objFile.WriteLine " Installed By: "
& clsHotFix.InstalledBy
Next
objFile.WriteLine
objFile.Close
]]>
</script>
</job>
</package>
Bonus!
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.
Another Bonus?
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,
too.
' GetVersions.vbs
' 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
' computers
Dim objWMI, colWMISettings, clsWMISetting, objShell,
strADSIVersion
' Display WSH version
WScript.Echo "WSH
Version: " & WScript.Version
' Display WMI version
Set objWMI = GetObject(
"winmgmts:{impersonationLevel=impersonate}!\\
computername\root\cimv2")
Set colWMISettings
= objWMI.ExecQuery("Select * from
Win32_WMISetting")
For Each clsWMISetting
in colWMISettings
Wscript.Echo "WMI Version:
" & clsWMISetting.BuildVersion
Next
' Display ADSI version
Set objShell = CreateObject("WScript.Shell")
strADSIVersion = objShell.RegRead(
"HKLM\SOFTWARE\ Microsoft\Active Setup\
Installed Components\
{E92B03AB-B707-11d2-9CBD-0000F87A369E}\Version")
If strADSIVersion
= vbEmpty Then
strADSIVersion = objShell.RegRead(
"HKLM\SOFTWARE\Microsoft\ ADs\Providers\LDAP\")
If strADSIVersion
= vbEmpty Then
strADSIVersion = "ADSI is not installed."
Else
strADSIVersion = "2.0"
End If
End If
WScript.Echo "ADSI Version: " & strADSIVersion
Set objWMI=Nothing
Set colWMISettings=Nothing
Set clsWMISetting=Nothing
Set objShell=Nothing
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.
About the Author
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 [email protected].