Saturday, April 26, 2014

Windows update pipelines with PowerShell

Testing a set of Windows updates before pushing them to production is a fairly typical strategy, but WSUS doesn't provide great tools for it out of the box. With a bit of PowerShell you can generate a file containing a list of new updates, approve them for the test environment, and later approve the same set for prod.

This works even if your test and production environments are connected to separate WSUS servers (for reasons that are too frightening to go into here). As long as all WSUS servers further along the pipeline have synchronized with Microsoft in sync with the initial server or afterward, the update list contains all the information required to coordinate the deployment.

The scripts are hosted on GitHub; there's not much to them, as they build on services of the Microsoft.UpdateServices.Administration namespace in the WSUS 3.0 class library. Thanks to this Stack Overflow post for the pointer.

The expected computer group tree is a pair of computer groups underneath All Computers - one for test computers and one for production. You could add additional pre-prod environment groups or break out groups for different classes of machines. Here's a sample workflow:

  1. Synchronize WSUS with Microsoft after Patch Tuesday;
  2. Get a list of new updates: .\list-unapproved.ps1 > updates-YYYY-MM-DD.txt
  3. View the list of updates and ensure the expected date ranges are covered;
  4. Approve updates for a test computer group: cat updates-YYYY-MM-DD.txt | .\approve-updates.ps1 "Test_Servers"
  5. Deploy patches and test;
  6. Approve updates for the production computer group: cat updates-YYYY-MM-DD.txt | .\approve-updates.ps1 "Production_Servers"

The update list includes a line for each update. Each update is formatted as an update GUID, a colon, and the update revision number, like "f49a461d-9fa0-484b-9db5-b14e9a3d9bd3:203". After a semicolon the remainder of the line describes the update date and title; it's ignored by the rest of the scripts but makes it easier for humans to manage the update list. Here's a sample entry:

f49a461d-9fa0-484b-9db5-b14e9a3d9bd3:203;4/8/2014;Security Update for Windows 7 for x64-based Systems (KB2922229)

I've also included a pair of scripts, list-approved.ps1 and unapprove-updates.ps1, to make it easier to back out changes. list-approved.ps1 lists all the updates approved for a computer group, while unapprove-updates.ps1 removes the approval for a list of updates.

Windows Server 2012 R2 supports a series of PowerShell 4.0 cmdlets for WSUS automation. I tested the scripts in this post with Windows Server 2008 R2 and PowerShell 2.0, so the new cmdlets won't work for me, but everything I needed was available through the .NET class library. For all my griping about PowerShell syntax it really is far more powerful than what I'm accustomed to in bash.

No comments: