How can I find out how many updates are waiting to be installed on a remote server

Is there a way to find out if a Windows Server (2003, 2008) has downloaded the Microsoft Windows updates and is just waiting for the user to confirm "Install Updates and Restart the server"?

We use WSUS and SSCM to collect and publish the updates, and the majority of the servers are on automatic install on a Sunday morning, mostly development and test server.

We have setup our important production servers to only install manually, but occastionally some servers are not rebooted manually for a while (humans forget!)

It would be nice if there was some method (powershell script, WMI query, some magic command) that I could use to count or discover if there where updates pending.


Here is the script I wrote. It will tell you:

  • How many patches are waiting to be installed
  • If the patches will require a reboot
  • If the server is currently waiting on a reboot to enable the patches

Example usage: C:\> cscript ServerPendingUpdates.vbs myserver01 myserver02

Connecting to myserver01 to check software update status...
myserver01 has 2 updates pending installation
myserver01 WILL need to be rebooted to complete the installation of these updates.
myserver01 is waiting for a REBOOT to complete a previous installation.

<snip>

Script:

'#
'# ServerPendingUpdates.vbs
'#
'# Usage: cscript ServerPendingUpdates.vbs {servername} {servername} {servername} {servername}
'#    If no {servername} specified then 'localhost' assumed
'#
'# To do: Error handling
'#
Option Explicit
Dim strServer        : strServer         =  GetArgValue(0,"localhost")


'#
'# Loop through the input parameters for each server
'#
Dim i
For i = 0 To WScript.Arguments.Count - 1
    CheckServerUpdateStatus GetArgValue(i,"localhost") 'strServer
Next

WScript.Quit(0)

Function CheckServerUpdateStatus( ByVal strServer )

    WScript.Echo vbCRLF & "Connecting to " & strServer & " to check software update status..."

    Dim blnRebootRequired    : blnRebootRequired     = False
    Dim blnRebootPending    : blnRebootPending     = False
    Dim objSession        : Set objSession    = CreateObject("Microsoft.Update.Session", strServer)
    Dim objUpdateSearcher     : Set objUpdateSearcher    = objSession.CreateUpdateSearcher
    Dim objSearchResult    : Set objSearchResult     = objUpdateSearcher.Search(" IsAssigned=1 and IsHidden=0 and Type='Software'")

    '#
    '#
    '#
    Dim i, objUpdate
    Dim intPendingInstalls    : intPendingInstalls     = 0

    For i = 0 To objSearchResult.Updates.Count-1
        Set objUpdate = objSearchResult.Updates.Item(I) 

        If objUpdate.IsInstalled Then
            If objUpdate.RebootRequired Then
                blnRebootPending     = True
            End If
        Else
            intPendingInstalls    = intPendingInstalls + 1
            'If objUpdate.RebootRequired Then    '### This property is FALSE before installation and only set to TRUE after installation to indicate that this patch forced a reboot.
            If objUpdate.InstallationBehavior.RebootBehavior <> 0 Then
                '# http://msdn.microsoft.com/en-us/library/aa386064%28v=VS.85%29.aspx
                '# InstallationBehavior.RebootBehavior = 0    Never reboot
                '# InstallationBehavior.RebootBehavior = 1    Must reboot
                '# InstallationBehavior.RebootBehavior = 2    Can request reboot
                blnRebootRequired     = True
            End If

        End If
    Next

    WScript.Echo strServer & " has " & intPendingInstalls & " updates pending installation"

    If blnRebootRequired Then
        WScript.Echo strServer & " WILL need to be rebooted to complete the installation of these updates."
    Else
        WScript.Echo strServer & " WILL NOT require a reboot to install these updates."
    End If


    '#
    '#
    '#
    If blnRebootPending Then
        WScript.Echo strServer & " is waiting for a REBOOT to complete a previous installation."
    End If 
End Function



'#
'#
'#
Function GetArgValue( intArgItem, strDefault )
    If WScript.Arguments.Count > intArgItem Then
        GetArgValue = WScript.Arguments.Item(intArgItem)
    Else
        GetArgValue = strDefault
    End If
End Function

you can use wuinstall. It has a /search switch to see if there are updates pending. You can execute remotely with psexec.

Another option is to parse the %windir%\windowsupdate.log and look for stuff like this: # WARNING: Install call completed, reboot required = Yes, error = 0x00000000


I use the UpdateHf.vbs script authored by Rob Dunn & contributors. Because it runs locally on the host it is reporting on, I have it installed on all my machines. I created an MSI package and pushed it via GPO.

To trigger the reporting, I have a collection of powershell scripts that create scheduled tasks on an OU worth of servers, where each machine is scheduled to run UpdateHF.vbs locally and email me the results. I then use sorting rules to colorcode the resulting emails based on searching for distinctive text in the report.

UpdateHF.vbs is basically a wrapper around Microsoft's published Automatic Updates API, so with some digging I bet you could figure out which bit of script handles the "Reboot Pending" check, if all you wanted was a boolean reboot-status flag.

Here's the core of my system: Powershell fills in the variables on a call to schtasks.exe. (Note that if the password has complex characters, you need to escape them with a backtick.)

schtasks.exe /create /F /S $TargetHost /tn Patch /sc once /st $TargetTime /sd $StartDate /ru User /rp Password /tr "$WinPath\system32\cscript.exe $WinPath\UpdateHF.vbs $UpdateArgs"