Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I tell which service packs have been installed on my computers?

-- FR

SpacerHey, Scripting Guy! AnswerScript Center

Hey, FR. That’s a very good question; as you know better than we do, in this day and age it’s really important to make sure all your computers have the latest service pack, the latest hot fixes, and the latest downloads from Windows Update installed. But, like you said, how can you do that?

Ah, you’re way ahead of us: yes, scripting is a good way to track this information. For example, this simple script reports the latest service pack installed on a computer:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
    ("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
    Wscript.Echo objOperatingSystem.ServicePackMajorVersion  _
        & "." & objOperatingSystem.ServicePackMinorVersion
Next

Now you might be thinking, “Oh, the latest service pack. But I need to know about all the service packs that have been installed on a computer.” If that’s the case, relax; when you install, say, Service Pack 3.0, you automatically get everything that was included in Service Packs 1.0 and 2.0. Because of that, it doesn’t really matter whether Service Pack 1.0 was installed; by installing Service Pack 3.0, you got all the functionality of Service Pack 1.0. Which is a somewhat convoluted way of saying that all you really care about is the latest service pack that was installed on a computer. And the preceding script will do just that.

But what about those hot fixes we mentioned; how can you audit a computer and see which hot fixes have been installed? Try this script:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colQuickFixes = objWMIService.ExecQuery _
    ("Select * from Win32_QuickFixEngineering")
For Each objQuickFix in colQuickFixes
    Wscript.Echo "Computer: " & objQuickFix.CSName
    Wscript.Echo "Description: " & objQuickFix.Description
    Wscript.Echo "Hot Fix ID: " & objQuickFix.HotFixID
    Wscript.Echo "Installation Date: " & objQuickFix.InstallDate
    Wscript.Echo "Installed By: " & objQuickFix.InstalledBy
Next

Two things to keep in mind here. First, hot fixes haven’t always been released in standard fashion. That doesn’t mean they don’t work, it just means that some hot fixes might not populate all the above fields; for example, many hot fixes won’t return a value for the InstallDate property. Second, hot fix information is recorded in several places on your computer and, because there hasn’t always been a standard way of doing this, WMI checks all of these locations and retrieves hot fix information. That’s good, except that once in awhile a hot fix will actually record information in multiple locations. Again, that’s not really a problem; it just means that when you get your information back from WMI you might see or 2 or 3 instances of hot fix QFE 1111111. That’s because QFE 1111111 recorded information about itself in several different spots.

Hey, that’s right: we did mention Windows Update, didn’t we? Well, if you’ve installed the latest version of Windows Update, you might very well have a new COM object that enables you to retrieve update information. For example:

Set objSession = CreateObject("Microsoft.Update.Session")
Set objSearcher = objSession.CreateUpdateSearcher
intHistoryCount = objSearcher.GetTotalHistoryCount
'Wscript.Echo intHistoryCount

Set colHistory = objSearcher.QueryHistory(1, intHistoryCount)

For Each objEntry in colHistory
    Wscript.Echo "Operation: " & objEntry.Operation
    Wscript.Echo "Result code: " & objEntry.ResultCode
    Wscript.Echo "Date: " & objEntry.Date
    Wscript.Echo "Title: " & objEntry.Title
    Wscript.Echo "Description: " & objEntry.Description
    Wscript.Echo "Client application ID: " & objEntry.ClientApplicationID
    Wscript.Echo "Server selection: " & objEntry.ServerSelection
    Wscript.Echo "Service ID: " & objEntry.ServiceID
    i = 1
    For Each strStep in objEntry.UninstallationSteps
        Wscript.Echo i & " -- " & strStep
        i = i + 1
    Next
    Wscript.Echo "Uninstallation notes: " & objEntry.UninstallationNotes
    Wscript.Echo "Support URL: " & objEntry.SupportURL
    Wscript.Echo
Next

To be honest, we only know for sure that the Microsoft.Update.Session object gets installed on Windows XP (and is automatically installed when you install XP Service Pack 2). If you’re running Windows 2000, you might want to visit Windows Update, install the latest version, then run the preceding script and see if it works.