For administrators without a WSUS server, you need this script.

Well, I got good news, annoying news, then great news for this post! The good news is that the strike at my work is over now! YAY! The annoying news is that the staff systems haven’t been turned on for 4 months to do updates! The great news is that I can tell all the Windows systems in my network to install their updates, without needing a WSUS server!

First off, let’s make it clear that I have the technology to run programs, as my Domain Admin user, from a central location, on to all the other Windows systems in my network. I use a program called PDQ Deploy to do this. Secondly, note that I made some tweaks to the script I found!

The credit goes to the Microsoft Developer Network (MSDN) for the script, which runs as a .VBS command. It looks for the updates available, downloads the available updates, then checks if you need to accept a EULA, and if it needs to reboot your computer to finish. Because my goal is to push this out to 300+ computers, I just want them to download the updates, install them, and shut down! Ahh, the goodness that can come from using Linux servers in a Windows-workstation environment (sarcasm intended)!

First off, download the script from MSDN, and save it somewhere accessible to the clients. If you want to push it out, you’ll need to make 2 changes to it. On Line 39, change it to strInput = "Y". You’ll need to make the same change on Line 96. When I did it to my script, I commented out the original lines, then added my new lines directly after it. Save the script.

A quick note

Another thing to mention is that sometimes, the updates are quite large! When I ran it on my tech laptop that reboots about once per month, the biggest update was 715MB in size (the Microsoft SQL Server 2012 Service Pack)! So, it will take a while to run. The good news about my setup though, is that I have a Squid Proxy server setup, which will cache 50GB of Windows Updates for my company, so it is only ever the first computer needing the update that is slow at downloading. If you have a proxy server, you can push out a netsh command to force the Windows Update service to use your proxy server, which will speed up the other machines.

Use a specific proxy server for Windows Updates:

netsh.exe winhttp set proxy <ipaddress>:<port>

The code (save to a .VBS file)

Original Windows Update script

My Updated script (which says YES to the EULA and to installing the updates found):

Set updateSession = CreateObject("Microsoft.Update.Session")
updateSession.ClientApplicationID = "MSDN Sample Script"

Set updateSearcher = updateSession.CreateUpdateSearcher()

WScript.Echo "Searching for updates..." & vbCRLF

Set searchResult = _
updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")

WScript.Echo "List of applicable items on the machine:"

For I = 0 To searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    WScript.Echo I + 1 & "> " & update.Title
Next

If searchResult.Updates.Count = 0 Then
    WScript.Echo "There are no applicable updates."
    WScript.Quit
End If

WScript.Echo vbCRLF & "Creating collection of updates to download:"

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

For I = 0 to searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    addThisUpdate = false
    If update.InstallationBehavior.CanRequestUserInput = true Then
        WScript.Echo I + 1 & "> skipping: " & update.Title & _
        " because it requires user input"
    Else
        If update.EulaAccepted = false Then
            WScript.Echo I + 1 & "> note: " & update.Title & _
            " has a license agreement that must be accepted:"
            WScript.Echo update.EulaText
            WScript.Echo "Do you accept this license agreement? (Y/N)"
            'strInput = WScript.StdIn.Readline
            strInput = "Y"
            WScript.Echo
            If (strInput = "Y" or strInput = "y") Then
                update.AcceptEula()
                addThisUpdate = true
            Else
                WScript.Echo I + 1 & "> skipping: " & update.Title & _
                " because the license agreement was declined"
            End If
        Else
            addThisUpdate = true
        End If
    End If
    If addThisUpdate = true Then
        WScript.Echo I + 1 & "> adding: " & update.Title
        updatesToDownload.Add(update)
    End If
Next

If updatesToDownload.Count = 0 Then
    WScript.Echo "All applicable updates were skipped."
    WScript.Quit
End If

WScript.Echo vbCRLF & "Downloading updates..."

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

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

rebootMayBeRequired = false

WScript.Echo vbCRLF & "Successfully downloaded updates:"

For I = 0 To searchResult.Updates.Count-1
    set update = searchResult.Updates.Item(I)
    If update.IsDownloaded = true Then
        WScript.Echo I + 1 & "> " & update.Title
        updatesToInstall.Add(update)
        If update.InstallationBehavior.RebootBehavior > 0 Then
            rebootMayBeRequired = true
        End If
    End If
Next

If updatesToInstall.Count = 0 Then
    WScript.Echo "No updates were successfully downloaded."
    WScript.Quit
End If

If rebootMayBeRequired = true Then
    WScript.Echo vbCRLF & "These updates may require a reboot."
End If

WScript.Echo  vbCRLF & "Would you like to install updates now? (Y/N)"
'strInput = WScript.StdIn.Readline
strInput = "Y"
WScript.Echo

If (strInput = "Y" or strInput = "y") Then
    WScript.Echo "Installing updates..."
    Set installer = updateSession.CreateUpdateInstaller()
    installer.Updates = updatesToInstall
    Set installationResult = installer.Install()

    'Output results of install
    WScript.Echo "Installation Result: " & _
    installationResult.ResultCode
    WScript.Echo "Reboot Required: " & _
    installationResult.RebootRequired & vbCRLF
    WScript.Echo "Listing of updates installed " & _
    "and individual installation results:"

    For I = 0 to updatesToInstall.Count - 1
        WScript.Echo I + 1 & "> " & _
        updatesToInstall.Item(i).Title & _
        ": " & installationResult.GetUpdateResult(i).ResultCode
    Next
End If