Thursday, March 19, 2015

Automating Windows patching for VM templates



# This script will convert template to VM, Power On VM, run Windows Update remotely, reboot VMGuest, shut VM down and finally convert back to template
# From https://communities.vmware.com/message/2470778
# Modified by Antonio Sotelo

# Requires Windows Update PowerShell Module installed on the template to run Get-WUInstall cmdlet.
# https://gallery.technet.microsoft.com/scriptcenter/2d191bcd-3308-4edd-9de2-88dff796b0bc/file/41459/43/PSWindowsUpdate.zip
# Extract to %WINDIR%\System32\WindowsPowerShell\v1.0\Modules

# Connect to vCenter
# http://blogs.vmware.com/PowerCLI/2013/03/back-to-basics-connecting-to-vcenter-or-a-vsphere-host.html
# Get the Credentials (Using VICredentialStore "C:\Scripts\vicredentials.xml" is created running the PowerCLI  console as the user account that runs the scheduled task.
# Example of scheduled task command: 
#   powershell.exe -PSconsolefile "c:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\vim.psc1" "& 'C:\Scripts\PatchVMTemplates.ps1'"
#   Scheduled to run second Tuesday of the month

$vicreds = Get-VICredentialStoreItem -file  "C:\Scripts\vicredentials.xml"

Connect-VIServer $vicreds.host -User $vicreds.User -Password $vicreds.Password


Function PatchVMTemplate ($VMTemplate){
# Convert template to VM
Set-Template -Template $VMTemplate -ToVM -Confirm:$false -RunAsync
Start-sleep -s 30

# Start VM template
# Thanks to http://theboywonder.co.uk/2012/10/19/catching-virtual-machine-questions-with-powercli/
try
{
    try
    {
        Start-VM -VM $VMTemplate -ErrorAction Stop -ErrorVariable custErr
    }
    catch [System.Management.Automation.ActionPreferenceStopException]
    {
        throw $_.Exception
    }
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.VMBlockedByQuestionException]
{
        Get-VMQuestion -VM $VMTemplate | Set-VMQuestion –Option "I copied it" -Confirm:$false 
}

Start-sleep -s 120
 
# Create variables for Guest OS credentials - This is needed for the Invoke-VMScript cmdlet to be able to execute actions inside the Guest.
$Username = "administrator"
# Note: Password is encrypted in OSPwd.txt which needs to be created beforehand using this command: read-host -assecurestring | convertfrom-securestring | out-file C:\Scripts\OSPwd.txt
# This file is created running the PowerCLI console as the user account that runs the scheduled task.
$OSPwd = cat C:\Scripts\OSPwd1.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.
# Requires Windows Update PowerShell Module installed on the template to run Get-WUInstall cmdlet.
# Results are exported to a log file to see the patches installed and related results.
Invoke-VMScript -ScriptType PowerShell -ScriptText "Get-WUInstall –WindowsUpdate –AcceptAll –AutoReboot" -VM $VMTemplate -GuestCredential $Cred | Out-file -Filepath C:\$VMTemplate-WUResults.log # -Append
 
Start-sleep -s 120
 
# Restart VMGuest one more time in case Windows Update requires it and for whatever reason the –AutoReboot switch didn’t complete it.
Restart-VMGuest -VM $VMTemplate -Confirm:$false
 
Start-sleep -s 300

# Shutdown the server and convert it back to Template.
Shutdown-VMGuest $VMTemplate -Confirm:$false
Start-sleep -s 120
Set-VM –VM $VMTemplate -ToTemplate -Confirm:$false

} #End of Function

PatchVMTemplate "Test_Template"


# Send an email with WU Results
$EmailTo = "admin@somewhere.com"
$EmailSubject = "WSUS Patching for VM Templates"
  Send-MailMessage -To $EmailTo `
  -Subject $EmailSubject -From "WSUSReporting@somewhere.com" `
  -Body "VM templates have been patched. See attachments for details. This is an automated message. Do not reply to this email." `
  -Attachments "C:\Test_Template-WUResults.log"
  -SmtpServer "mail.smtpserver.com"



1 comment:

  1. Hi,
    this script is vert good but its not working for windows 7 and windows 2008.

    ReplyDelete