Trigger Remote WUA to Install Updates

Suppose Windows Update Agent (WUA) on your clients is configured to only download approved Windows updates and to let the user decide when to install them.

When following-up statuses of these clients via WSUS or SCCM reporting, you’ll undoubtedly be faced with the following caveats:

  • Some users stubbornly ignore the Windows update notifications and never install pending updates
  • In industrial environments, clients might take the role of a server on which users never login interactively

Hopefully reporting shows that your clients’ compliance level is acceptable; if not, you’ll have to revise your patching policy.

So how can you easily enforce these few remote clients to download (if that hasn’t happened yet) and install all pending updates? Here’s a simple and quick ad hoc solution.

ForceUpdates.vbs

First of all, we need a script that triggers WUA to:

  1. download approved updates (if still needed)
  2. install each update that has been downloaded
  3. reboot if required (after prompting the user)

Option Explicit

Dim updateSession, updateSearcher, searchResult, installationResult
Dim updatesToDownload, updatesToInstall
Dim downloader, update, installer
Dim i: i = 0

WScript.Echo "Searching for updates..."

Set updateSession = CreateObject("Microsoft.Update.Session")
Set updateSearcher = updateSession.CreateupdateSearcher()
Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software'")

WScript.Echo "Updates to download and/or install: " & searchResult.Updates.Count

If searchResult.Updates.Count = 0 Then
WScript.Quit
End If

Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")

For i = 0 to searchResult.Updates.Count - 1
Set update = searchResult.Updates.Item(i)
updatesToDownload.Add(update)
Next

WScript.Echo "Downloading updates..."

Set downloader = updateSession.CreateUpdateDownloader()
downloader.Updates = updatesToDownload
downloader.Download()

Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl")

For i = 0 To searchResult.Updates.Count - 1
Set update = searchResult.Updates.Item(i)
If update.IsDownloaded = true Then updatesToInstall.Add(update)
Next

Set installer = updateSession.CreateUpdateInstaller()
installer.Updates = updatesToInstall

WScript.Echo "Installing updates..."
Set installationResult = installer.Install()

If installationResult.RebootRequired Then
MsgBox "Press OK to REBOOT now!"
Dim objShell: Set objShell = CreateObject("WScript.Shell")
objShell.Run "%COMSPEC% /C SHUTDOWN.EXE -R -F -T 0", 0, False
End If

The WUA API can be used on a remote computer if the remote user or application has administrator privileges. So yes, it is possible to instantiate a WUA session on a remote machine by specifying the computername:

Set updateSession = CreateObject("Microsoft.Update.Session", computername)

The problem occurs later on. The IUpdateSession::CreateUpdateDownloader and IUpdateSession::CreateUpdateInstaller methods are not supported on a remote client (typically a permission denied error occurs), like many other methods outlined here. Consequently, we’ll use a different approach. The idea is to trigger the remote machine to execute the script (designed to run locally).

Psexec.exe could be your first choice if the administrative shares on the target machine haven’t been deleted. Schtasks.exe, the command-line utility of the Windows Task Scheduler could be used to execute the script immediately or at a point in time. You could write a VBScript or PowerShell script that creates a Win32_ScheduledJob instance (WMI) on the remote client.

But why not use the good old simple at.exe utility?

AT

AT jobs typically run under the local SYSTEM account but in this case that shouldn’t be a issue. Put the above ForceUpdates.vbs on a network share and trigger the remote client to execute the script by specifying the current time + 61 seconds (AT’s time precision is limited to minutes). Here’s another script that will prompt for a computername and launch at.exe to create a scheduled task on the remote machine:

Option Explicit

Dim dtmCurrentTime, strTargetTime
Dim strComputer, strHour, strMin

strComputer = Inputbox("WS:")

If Len(strComputer) = 0 Then WScript.Quit

dtmCurrentTime = DateAdd("s", 61, Now)
strHour = CStr(Hour(dtmCurrentTime))
strMin = CStr(Minute(dtmCurrentTime))

If Len(strHour) = 1 Then strHour = "0" & strHour
If Len(strMin) = 1 Then strMin = "0" & strMin

strTargetTime = strHour & ":" & strMin

Dim objShell: Set objShell = CreateObject("WScript.Shell")
objShell.Run "%COMSPEC% /C AT \\" & strComputer & " " & strTargetTime & " /interactive ""cscript.exe \\servername\sharename\ForceUpdates.vbs""", 0, False

That’s it. At hh:nn:00 the remote task scheduler will execute ForceUpdates.vbs from the network share. On completion, it will reboot the machine if required (after prompting the user).

Note: wcuaclt.exe has a variety of undocumented command-line switches, e.g. /updatenow. Unfortunately their explanation is obscure (you might find some resources) and more importantly, in my experience their behaviour is unpredictable and unreliable.

Advertisements
%d bloggers like this: