Querying Active Directory for Computer Operating System, Service Pack, and Hotfix Details

One of the most painful tasks for administrators is keeping track of the service pack level of their servers and workstations. Thankfully, WMI affords a simple and automated method to retrieve this information from computers. Using ADSI to enumerate all machines within a domain, it is extremely simple to automate the WMI query to obtain this information as the following script demonstrates. Comments have been added for description of each process:

On Error Resume Next
'Instantiate objects
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set outfile = objFSO.OpenTextFile("C:\SP_Output.txt", 2, True)

'Obtain current domain name via RootDSE
Set objRootDSE = GetObject("LDAP://rootDSE")
strADsPath = "'"&"LDAP://" & objRootDSE.Get("defaultNamingContext")&"'"

'Connect to the current domain partition in AD and enumerate all computer
'objects via the filter to enumerate computer objects.
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open "Provider=ADsDSOObject;"
Set objCommand = CreateObject("ADODB.Command")
objCommand.ActiveConnection = objConnection
objCommand.CommandText = "SELECT Name FROM " & strADsPath & _
" WHERE objectClass='computer'"
objCommand.Properties("Page Size")= 1000
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst

'Control Loop to cycle through enumeration results from ADO query.
Do Until objRecordSet.EOF
strCompName = objRecordSet.Fields("Name").Value
outfile.writeline UCase(strCompName)
outfile.writeline "-"
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strCompName & "\root\cimv2")

'Error handling in case the script is unable to connect to the computer.
If Err.Number <> 0 Then
On Error GoTo 0
outfile.writeline Ucase(strCompName ) & " is not responding to the query."
outfile.writeline ""
outfile.writeline "==================="
outfile.writeline ""
On Error Resume Next
Else
Set colOperatingSystems = objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
outfile.writeline "Operating System: " &objOperatingSystem.Caption _
& " " & objOperatingSystem.Version
outfile.writeline "Service Pack: " & objOperatingSystem.ServicePackMajorVersion _
& "." & objOperatingSystem.ServicePackMinorVersion
Next
outfile.writeline ""
outfile.writeline "==================="
outfile.writeline ""
End If
objRecordSet.MoveNext
Loop
MsgBox “Script Completed.” & VbCrLf _
& “Results located at c:\SP_Output.txt”
WScript.Quit
'Clean up
Set objFSO = Nothing
Set objConnection = Nothing
Set objCommand = Nothing

In addition to service packs, another enjoyable task is staying current with the deluge of hotfixes as they are released. Thankfully, WMI also offers a class to enumerate installed hotfixes. The above script can be modified to include hotfixes by adding a query to the appropriate class, Win32_QuickFixEngineering. For example:

Set colHotFixes = objWMIService.ExecQuery _
("Select * from Win32_QuickFixEngineering")

After adding this query to the script, add the properties to the script to output the results to the text file. Something similar to this example would work:

For Each objHotFix in colHotFixes
outfile.writeline “Description: “ & objHotFix.Description
outfile.writeline “HotFix ID : “ & objHotFix.HotFixID
outfile.writeline “Install Date: “ & objHotFix.Install.Date
Next

Don’t bother cutting and pasting the text from this file. Instead, get a copy of the completed script by accessing the text version found here. Don’t forget to save it with a VBS extension!

Then, when you’re ready to run the script, just use the cscript scriptname.vbs command.

There are other properties available for this class; however these examples are a good start. The additional properties can be found at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_quickfixengineering.asp.

When it comes to automation, WMI is an extremely powerful tool that can save literally hours of administrative work as is easily demonstrated in these examples.