Automating Windows Patches on Templates

Back in 2015, I posted a use case on the VMware Communities that described a process I implemented to keep various Windows Templates up to date with Microsoft patches on multiple vSphere 5.5 environments.
It was common to run into situations where a virtual machine would be deployed from a template and it was way behind on Microsoft patches; this incurred additional time to bring the server up-to-date, time that could've been used in better ways.


For those managing multiple sites and not running vSphere 6.x which provides the ability of using Content Libraries where a single or less quantity of templates can be kept updated and shared with Subscribed Libraries (vCenters), this solution may still be applicable.

The Tasks involved: Convert template to VM, power on VM, run Windows Update remotely, reboot VMGuest, shut VM down and finally convert back to template.

What's required on Templates:

  • Server 2008/2012 Templates need to be running PowerShell v.3 minimum but v.4 is highly recommended. 
    • PowerShell 4 for 2008 server can be downloaded here 
  • The Windows Update PowerShell Module needs to be installed on your templates. 
    • It can be downloaded from here

Note: The Windows Update PowerShell Module includes the command
Get-WUInstall which is what I used to initiate patch installations remotely (from the script).





Since there were multiple Templates at each site, the final script contained multiple/duplicate lines where applicable for each VM Template.

Here are the steps configured.


Connect to vCenter
Connect-VIServer "vCenterServer"
Convert template to VM
Set-Template -Template W2K12Template -ToVM -Confirm:$false -RunAsync
Start-sleep -s 15
Start VM - I saw some converted templates that prompted with the VMQuestion, so adding the command to answer with the default option was my response to it.
Start-VM -VM W2K12Template | Get-VMQuestion | Set-VMQuestion -DefaultOption -Confirm:$false
Start-sleep -s 45
Create variables for Guest OS credentials - This is needed for the Invoke-VMScript cmdlet to be able to execute actions inside the Guest.
#If you don't want to enter the Guest OS local administrator password as clear text in the script, follow the steps here to create a file and store it as an encrypted string.
$Username = "administrator"$OSPwd = cat C:\Scripts\OSPwd.txt | convertto-securestring$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $OSPwd
The following is the cmdlet that will invoke the Get-WUInstall inside the GuestVM to install all available Windows updates; optionally results can be exported to a log file to see the patches installed and related results.
Invoke-VMScript -ScriptType PowerShell -ScriptText "Get-WUInstall –WindowsUpdate –AcceptAll –AutoReboot" -VM W2K12Template -GuestCredential $Cred | Out-file -Filepath C:\WUResults.log -Append
Start-sleep -s 45

Alternatebly, restart the VMGuest one more time in case Windows Update requires it and for whatever reason the –AutoReboot option in the above command didn’t complete it.
Restart-VMGuest -VM W2K12Template -Confirm:$false
On a separate scheduled script or after a desired wait period, Shutdown the server and convert it back to Template.
Shutdown-VMGuest –VM W2K12Template -Confirm:$false –RunAsync
Start-sleep -s 120 (here I elected to wait 2 minutes due to some SQL Templates taking longer to  power down cleanly)
Set-VM –VM W2K12Template -ToTemplate -Confirm:$false

The script can be scheduled to run a couple of days after Patch Tuesdays or whenever you desire. In my case, having multiple vCenter Servers, the scheduled scripts were spanned over different weeks of the month.




3 comments:

  1. Did you manually install the Windows Update Module on each template VM, or did you automate that part as well? :)

    ReplyDelete
    Replies
    1. Hi Ben,

      Thanks a lot for your question and for reading the post.
      I manually installed the update module on templates.
      Let me know if you have any other questions.

      Best regards.

      Delete
  2. When you install the PSWindowsUpdate module, the powershell files are blocked. Now we can easily unblock them, but is there a way to perform this permanently so they remain unblocked across all templates deployed? Would we have to place the unblock-file commands in our scripts for each clone?

    ReplyDelete