Managing Windows Updates with PowerShell

Recently, I ran into a challenge while creating a Windows 8.1 deployment image. I create my images just like many other IT pros do using Microsoft’s Sysprep utility. A good deployment image is current with all critical Windows Updates applied. In many cases, there are also a number of recommended and optional updates that I want incorporated into an image.

Unfortunately, while creating an image using Sysprep’s Audit Mode in Windows 8.1, the standard Windows Update GUI isn’t an option. While in Audit Mode, Windows believes the Setup Out-of-Box Experience (OOBE) is running. By design, Windows Update will not run during the OOBE phase. This is primarily to prevent an unexpected reboot during the setup process. Leveraging the power of PowerShell and the ingenuity of fellow Microsoft MVP Michal Gajda, an elegant and easy solution is available. Today I’ll show you how to manage Windows updates using the PowerShell PSWindowsUpdate module.

Before I go further, let me mention that options do exist for applying updates to Windows deployment images after the fact. Primary among these is the Deployment Image Servicing and Management tool (DISM), which is great, but in some instances using this tool is an extra complexity IT pros just don’t need. These are the cases where being able to find and apply Windows Updates from within Sysprep’s Audit Mode is a major boon.

Using PowerShell to Manage Windows Updates:  PSWindowsUpdate

The secret to deploying Windows Updates from within Audit Mode is an excellent PowerShell module created by Michal Gajda. This module, aptly called PSWindowsUpdate, allows managing Windows Update on any computer running PowerShell 2.0 or higher. This module even enables Windows admins to check for and install updates on remote PCs and servers. PSWindowsUpdate is particularly handy for installing updates on Server Core machines that have no GUI, or in instances such as Sysprep’s Audit Mode where the Windows Update GUI doesn’t work.

Downloading PSWindowsUpdate.zip

  • Once downloaded, extract the contents of the zip file to C:\Windows\System32\WindowsPowerShell\v1.0\Modules\.
Extracting files from PSWindowsUpdate.zip
Extracting files from PSWindowsUpdate.zip.
  • Click Continue if a UAC prompt appears.

UAC prompt copying files

  • When the files have been extracted into the PowerShell Modules folder, open an elevated PowerShell prompt. Change PowerShell’s Execution Policy to RemoteSigned. The RemoteSigned Execution Policy allows PowerShell scripts downloaded from the Internet to run on a PC as long as they are signed by a trusted publisher.
  • Type Set-ExecutionPolicy RemoteSigned and press Enter. When prompted, confirm the change by pressing Y and then Enter.
Changing PowerShell's Execution Policy
Changing PowerShell’s execution policy

This completes the one-time configuration of the module! Now it’s time to put PSWindowsUpdate to use!

  • If running PowerShell v2.0, type Import-Module PSWindowsUpdate and hit Enter. This isn’t necessary in PowerShell v3 and higher, but it doesn’t hurt anything either. This step simply guarantees that the modules cmdlets will be available to the PowerShell v2.0 session.
  • Display a list of all the module’s available cmdlets by typing Get-Command –module PSWindowsUpdate and hitting Enter.
Using Get-Command -module PSWindowsUpdate
Using Get-Command -module PSWindowsUpdate.
  • Possibly the most important function for getting and installing updates is Get-WUInstall. Help for each cmdlet is available, so to see full help for Get-WUInstall type Help Get-WUInstall –full and press Enter.
Managing Windows Updates: Get-WUInstall
Looking at help for Get-WUInstall.

When applying updates, I prefer connecting to the Microsoft Update servers. Using these instead of the standard Windows Update servers allows installing updates to Office and other Microsoft products in addition to the normal Windows updates. Unfortunately, trying to connect to the Microsoft Update servers using the PSWindowsUpdate module from a fresh Windows installation will produce an error, as shown below.

Error connecting to Microsoft Update

  • The reason for this error is because Windows is registered to use only the standard Windows Update servers by default. To use the Microsoft Update servers, the Microsoft Update Service must be registered on the computer. In the GUI, this is done by selecting the checkbox for Give me updates for other Microsoft products when I update Windows from the Control Panel – Windows Update – Change Settings applet.
  • In the PSWindowsUpdate module, the same process is completed by using the Add-WUServiceManager cmdlet with the ServiceID for the Microsoft Update service specified. Type Add-WUServiceManager -ServiceID 7971f918-a847-4430-9279-4a52d1efe18d and press Enter. When prompted, confirm registering the service by typing Y and pressing Enter one more time.
Register the Microsoft Update servers
Registering the Microsoft Update servers.
  • List available updates from the Microsoft Update servers by typing Get-WUInstall –MicrosoftUpdate –ListOnly and pressing Enter. After a few moments, the system will return a list of the available updates for the current machine. No error this time!

Listing available updates

  • The same results are produced by typing Get-WUList –MicrosoftUpdate and pressing Enter.

Using Get-WUList

  • Type Get-WUInstall –MicrosoftUpdate and press Enter to go through the available updates, confirming installation of each one manually.

Retrieving updates

PSWindowsUpdate and Parameter Support

Another awesome feature of the PSWindowsUpdate module is its support of parameters. For example, using the –AcceptAll and the –AutoReboot parameters with the Get-WUInstall cmdlet changes the manual process into an automated one. Type Get-WUInstall –MicrosoftUpdate –AcceptAll –AutoReboot and press Enter. The system will download and install all available updates and then automatically reboot if any of the updates require a reboot.

Microsoft Update Manager: Retrieving updates and installing automatically
Retrieving updates and installing automatically.

Don’t want a particular update to be installed? No problem! Use Hide-WUUpdate. Selection parameters such as –Title or –KBArticleID narrow in and hide specific updates. Feel free to use wildcards with these parameters. As an example, type Hide-WUUpdate –Title “Bing*” –KBArticleID “KB2673774” –MicrosoftUpdate –Confirm:$false and press Enter to hide the Bing Bar 7.3 update.

Hiding an unwanted update with parameters
Hiding an unwanted update.

Notice that I used the –Confirm parameter, along with the $false switch, to automatically confirm hiding the selected update. In the future the update won’t appear when listing available updates.

Did you make a mistake and hide the wrong update? No problem! Hide-WUUpdate can unhide an update by using the –HideStatus parameter with the $false switch. To unhide the update hidden earlier, type Hide-WUUpdate –Title “Bing*” –KBArticleID “KB2673774” –MicrosoftUpdate –HideStatus:$false –Confirm:$false then press Enter. As before, I used the –Confirm:$false parameter to keep everything streamlined.

Unhiding a previously hidden update in Windows PowerShell
Unhiding a previously hidden update.

I started out seeking simply to solve a challenge installing updates within Sysprep’s Audit mode. The PSWindowsUpdate module goes far beyond simply solving this problem. It offers to automate and simplify dealing with Windows Updates. In addition to all the functionality discussed in this article, it can be scripted and even used to process updates on remote computers. Want my advice? Download PSWindowsUpdate and put it to use on your systems today!