One of my jobs at work is managing and maintaining a VMware Horizon Horizon VDI environment for around 300 users.
We use non-persistent floating desktop pools meaning each virtual desktop is created from a master virtual machine snapshot. This master virtual machine also sometimes referred to as the “Golden Image” contains the base OS and applications.
One of the main benefits of this is that configuration changes only need to be performed on the master virtual machine which is then rolled out to all users who then get an identical image.
Unfortunately the process of booting into the master VM and manually patching Windows, Office and our third-party applications every month was becoming a very time consuming task, so with my limited PowerShell knowledge decided it was time to look at automating this a bit to make things more hands-off.
I know there are others out there who have completely automated the entire patching and deployment of their VDI environments, however for the moment I am only going to focus on patching and updating applications inside of the “Golden Image”
To use both of these scripts you will need to have the Windows Update PowerShell Module installed on your master VM along with the VMware OS Optimization Tool. In my example I am using a VM with Windows 10 Enterprise version 1909 x64 and have the scripts and VMware OS Optimization Tool in a folder “C:\Scripts”
The first script Update-GoldImage.ps1 will update the installed applications and OS then reboot Windows.
# This scrpt will install Chocolatey Package Manager, update installed applications including Windows and Office then restart the computer on completion # Requires the Windows Update PowerShell Module - https://www.powershellgallery.com/packages/PSWindowsUpdate/188.8.131.52 # Enable and Start Services Write-Host "Enabling and Starting Services" Set-Service -Name bits -StartupType Automatic Set-Service -Name wuauserv -StartupType Automatic Set-Service -Name ClickToRunSvc -DisplayName "Microsoft Office Click-to-Run Service" -StartupType Automatic Start-Service -Name bits Start-Service -Name wuauserv Start-Service -Name ClickToRunSvc # Install Chocolatey Package Manager Write-Host "Installing Chocolatey Package Manager" [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) # Update Adobe Actobat Reader DC Write-Host "Updating Adobe Acrobat Reader DC" choco upgrade adobereader -y -yes -confirm # Update Microsoft Edge Write-Host "Updating Microsoft Edge" choco upgrade microsoft-edge -y -yes -confirm # Update Google Chrome Write-Host "Updating Google Chrome" choco upgrade googlechrome -y -yes -confirm # Update Mozilla Firefox Write-Host "Updating Mozilla Firefox" choco upgrade firefoxesr -y -yes -confirm --params "/l:en-GB /NoTaskbarShortcut /NoDesktopShortcut /NoAutoUpdate /RemoveDistributionDir" # Update VLC Media Player Write-Host "Updating VLC Media Player" choco upgrade vlc -y -yes -confirm # Update GIMP Write-Host "Updating GIMP" choco upgrade gimp -y -yes -confirm # Update Windows Write-Host "Updating Windows" Import-Module PSWindowsUpdate Get-WUInstall -Install -AcceptAll -IgnoreReboot # Update Microsoft Office Write-Host "Updating Microsoft Office" cd "C:\Program Files\Common Files\microsoft shared\ClickToRun" .\OfficeC2RClient.exe /update user displaylevel=false forceappshutdown=true # Sleep for 5 minutes before proceeding with the next task Write-Host "Waiting for operation to complete" Start-Sleep -s 300
The second script Finalise-GoldImage.ps1 will stop and disable services and scheduled tasks, uninstall Chocolatey then clean up the OS and shut down Windows.
# This script will stop relevant services/tasks, uninstall Chocolatey Package Manager, clean up the OS then shutdown the VM to prepare it for snapshotting # Requires the VMware OS Optmization Tool for final clean up process - https://flings.vmware.com/vmware-os-optimization-tool # Stop and Disable Services Write-Host "Stopping and Disabling Services" Stop-Service -Name bits Stop-Service -Name wuauserv Stop-Service -Name ClickToRunSvc Set-Service -Name bits -StartupType Disabled Set-Service -Name wuauserv -StartupType Disabled Set-Service -Name ClickToRunSvc -DisplayName "Microsoft Office Click-to-Run Service" -StartupType Disabled Set-Service -Name gupdate -DisplayName "Google Update Service (gupdate)" -StartupType Disabled Set-Service -Name gupdatem -DisplayName "Google Update Service (gupdatem)" -StartupType Disabled Set-Service -Name edgeupdate -DisplayName "Microsoft Edge Update Service (edgeupdate)" -StartupType Disabled Set-Service -Name edgeupdatem -DisplayName "Microsoft Edge Update Service (edgeupdatem)" -StartupType Disabled # Disable Scheduled Tasks Write-Host "Disabling Scheduled Tasks" Disable-ScheduledTask -TaskName "Adobe Acrobat Update Task" Disable-ScheduledTask -TaskName "GoogleUpdateTaskMachineCore" Disable-ScheduledTask -TaskName "GoogleUpdateTaskMachineUA" Disable-ScheduledTask -TaskName "MicrosoftEdgeUpdateTaskMachineCore" Disable-ScheduledTask -TaskName "MicrosoftEdgeUpdateTaskMachineUA" # Uninstall Chocolatey Package Manager Write-Host "Uninstalling Chocolatey Package Manager" Remove-Item -Path "C:\ProgramData\chocolatey" -Recurse -Force # Clean up Image Write-Host "Cleaning up Image" Remove-Item -Path "C:\Users\Public\Desktop\*" -Recurse -Force Remove-Item -Path $Env:TEMP\* -Recurse -Force Remove-Item -Path "C:\Windows\Temp\*" -Recurse -Force Remove-Item -Path "C:\Windows\SoftwareDistribution\*" -Recurse -Force cd "C:\Scripts\OSOT" .\VMwareOSOptimizationTool.exe -f all # Set Execution Policy Write-Host "Setting PowerShell Execution Policy to Restricted" Set-ExecutionPolicy Restricted -Force # Shutdown VM Write-Host "Shutting down Computer" Stop-Computer -ComputerName localhost
And that’s it! You can add or remove anything when using these scripts in your environment, hopefully as time goes on I will improve these a bit more and look at automating more of my Horizon deployment process.
Happy patching! 🙂