We generally connect to backend servers via a jump-box or bastion host. On Windows this means RDP into the jump-box, then RDP from the jump-box to the backend server. However, recently a Windows update meant that the jump-box (which had the update) couldn’t RDP to the backend server (which hadn’t got the update). No RDP => no access to update the VM to restore RDP. Lots of fun!
In that case I managed to use Remmina from a Linux box to access the backend directly; however since we are going to hit this issue again we needed a better fix.
Cue PowerShell; this is deployed via Octopus so will work when RDP doesn’t. As an additional perk it means updating becomes much easier.
function Get-WIAStatusValue($value) { switch -exact ($value) { 0 {"NotStarted"} 1 {"InProgress"} 2 {"Succeeded"} 3 {"SucceededWithErrors"} 4 {"Failed"} 5 {"Aborted"} } } # Stop after any error $ErrorActionPreference = "Stop"; # Whether an update requires a reboot $needsReboot = $false; # Since WU can be slow tell the user something is happening Write-Host "Starting Update"; $UpdateSession = New-Object -ComObject Microsoft.Update.Session; $UpdateSearcher = $UpdateSession.CreateUpdateSearcher(); Write-Host " - Searching for updates; this may take some time..."; $SearchResult = $UpdateSearcher.Search("IsAssigned=1 and IsHidden=0 and IsInstalled=0"); Write-Host " - Found [$($SearchResult.Updates.count)] updates to download and install"; foreach($Update in $SearchResult.Updates) { # Add Update to Collection $UpdatesCollection = New-Object -ComObject Microsoft.Update.UpdateColl; if ( $Update.EulaAccepted -eq 0 ) { $Update.AcceptEula(); } $UpdatesCollection.Add($Update) | Out-Null; # Download Write-Warning " + Downloading update '$($Update.Title)'"; $UpdatesDownloader = $UpdateSession.CreateUpdateDownloader(); $UpdatesDownloader.Updates = $UpdatesCollection; $DownloadResult = $UpdatesDownloader.Download(); $Message = " - Download {0}" -f (Get-WIAStatusValue $DownloadResult.ResultCode); Write-Warning $message; # Install Write-Warning " - Installing update"; $UpdatesInstaller = $UpdateSession.CreateUpdateInstaller(); $UpdatesInstaller.Updates = $UpdatesCollection; $InstallResult = $UpdatesInstaller.Install(); $Message = " - Install {0}" -f (Get-WIAStatusValue $DownloadResult.ResultCode); Write-Warning $message; if ($installResult.rebootRequired) { Write-Warning " - Update requires reboot"; $needsReboot = $true; } } if ($needsReboot) { Write-Warning "Rebooting following updates..."; Start-Sleep -Seconds 10; Restart-Computer -Force; }