Patch Tuesday VDI Pains? We’ve got a script for that…Part 2

In my last post, I went discussed the thought process that went into the Patch Tuesday script that we use at $work for updating our Linked-Clone parent VMs. In this post, I will dive deeper into the code itself, including the tools that we need to execute this script.


There are only two prerequisites for actually running this script. There is one prerequisite that is needed on the machine that will execute the script, and there is one that will need to be installed on the linked-clone parent VMs. The server prerequisite is PowerCLI.

As I mentioned in the last post, the Windows Update PowerShell Module will need to be deployed on each of the linked-clone parents that you wish to update with this script. I use Group Policy Preferences to deploy these files to the same folder on each machine. This has the two benefits – they are deployed the same spot automatically via policy and I can make updates on the version that is stored centrally, and they will propogate via policy. Because this module will be invoked using Invoke-VMScript, I’m not sure how it will work if it is called directly from a network share.

The Windows Update PowerShell Module has one main limitation that will need to be worked around. That limitation is that the Windows Update API cannot be called remotely, so PowerShell remoting cannot be used to launch a script using this module. It’s fairly simple to work around this, though, by using the Invoke-VMScript cmdlet.

This script will need to be executed in a 32-bit PowerShell session in order to use Invoke-VMScript to install Windows Updates. As of PowerCLI 5.1, VIX was a 32-bit only component, and the Invoke-VMScript and Wait-VMTools commands will not work if used in a 64-bit PowerShell window.


There are a number of parameters that will control how this script is executed. The parameters and their descriptions are below.

vCServer – vCenter Server
Folder – vCenter Folder where templates are located
ParentVM – Name of a specific Linked-Clone ParentVM that you want to update
SnapshotType – Type of updates that are being installed. This is used for building the snapshot name string. Defaults to Windows Updates
Administrator – Account with local adminsitrator privileges on the ParentVM. If using a domain account, use the domain\username format for account names. Mandatory parameter
Password – Password of the local adminsitrator account. Mandatory Parameter

The Administrator and Password parameters are mandatory, and the script will not run without these parameters being defined. The account that is used in this section should have local administrator rights on the target linked-clone parent VMs as administrator permissions will be required when executing the Windows Updates section.

There are two parameters for determining which VMs are updated. You can choose to update all of the Linked-Clone parents that exist within a vCenter folder with the -Folder parameter, or you can use a comma-separated list of VMs with the -ParentVM parameter.

Finally, if your environment is small, I would recommend setting defaults for the vCServer, Folder, and SnapShotType parameters. Having a few default values coded in will make executing this script easier.

Executing the Script

The first thing that the script does is build the string that will be used for the snapshot name. The basic naming scheme for snapshots in the $work environment is “Month SnapshotType Parameter Date installed.” So if we’re doing Windows Updates for the month of September, the snapshot name string would look like “September Windows Update 9-xx-2013.”

After the snapshot name is created, the script will take the following actions:

  1. Power-on the VM
  2. Execute the Windows Update script
  3. Reboot the VM
  4. Wait for the VM to come up, then shut it down
  5. Take Snapshot

Step 1 Power On VM

Powering on the VM is probably the easiest step in this whole script. It’s a simple Start-VM command to get it powered up, and then the output from this command is piped into Wait-VMTools. Wait-VMTools is used here to wait for the VMware Tools to be registered as running before continuing onto the next step, which will rely heavily on the tools.

Step 2. Execute the Windows Update Script

Once the VMware Tools are ready, we can continue onto the next step – installing Windows Updates. To do this, the script will use the Invoke-VMScript cmdlet to execute a command from the Windows Update PowerShell Module from within the VM. In order to execute this successfully, the Invoke-VMScript cmdlet will need to use credentials that have local administrator rights on the linked-clone parent VM.

The command for this section will look something like this:

Invoke-VMScript -VM $vm -ScriptText “Path\to\script\get-wuinstall.ps1 -acceptall” -GuestUser $Administrator -GuestPassword $Password

This section of the script will take longer to run than any other section.

Step 3 – Reboot the VM

Once the updates have finished installing, we need to reboot the VM so they take effect. There is a AutoReboot switch as part of the Get-WUInstall script that is run to install the updates, but it doesn’t seem to work correctly when using the Invoke-VMScript cmdlet. This job also needs to watch the status of the VM and VMware Tools as we’ll need to know the status of both in order to know when to shut the VM down and snapshot it.

Rebooting the VM is fairly simple, and it just uses the Restart-GuestVM cmdlet.

Checking the status of VMware Tools during the shutdown phase of the reboot, thoutgh, is difficult. The normal method of checking status is to use the Wait-VMTools cmdlet, but if you pipe the output from Restart-GuestVM to Wait-VMTools, it will immediately move onto the next section because it shows that the tools are up and online. So this script needs a different method for checking the status of VMware Tools, and for that, a custom function will need to be written.

The custom function will use the Get-VM and Get-View to return the status of VMware tools The results of will be put into a Do-Until loop to watch for a change in the status before continuing onto the next section. We’ll run this Do-Until loop twice – once to check to see if the tools are shut down, and then once to see that the tools come back up.

The code for checking the status of the VMware Tools is:

$toolstatus = (Get-VM $vm | % { get-view $_.ID } | Select-Object @{ Name=”ToolsStatus”; Expression={$_.guest.toolsstatus}}).ToolsStatus

Step 4 – Shut down the VM

Once the reboot completes and the VMware Tools show that they are ready, it is time to shut down the linked-clone parent vm. The Shutdown-GuestVM cmdlet is used for this. After the shutdown is initiated, the script checks to see that the VM is fully powered off before moving onto the final step.

Step 5. – Snapshot the VM

The final step of this process is to take a snapshot of the updated linked-clone parent. This snapshot will be used for the linked-clones in VMware View during the next recompose operation. The snapshot name that the script put together as it’s first action will be used here. The command for taking the snapshot is New-Snapshot -VM vmname -Name $snapshotname.


If you’re only updating one VM, then the script will disconnect from vCenter and end. If you have multiple VMs that need updating, then it will look through and start at step 1 for the next linked-clone parent, and it will continue until all of the of the desktops have been updated.

The code for this script and others is available on github.