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;
}