Last active
September 13, 2021 11:47
-
-
Save kspeeckaert/ef4b00f22f35267e83c023e4b505e1bc to your computer and use it in GitHub Desktop.
Wait until a remote host comes online and has RDP available, after a reboot.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires -Module BurntToast | |
[cmdletbinding()] | |
param ( | |
[Parameter(Mandatory)][string]$ComputerName, | |
[Parameter(Mandatory)][string]$ConnectionID | |
) | |
function Test-TCPPort { | |
# Replacement for Test-NetConnection, because ping cannot be disabled. | |
param ( | |
[Parameter(Mandatory)][string]$ComputerName, | |
[Parameter(Mandatory)][int]$Port | |
) | |
$Connection = New-Object System.Net.Sockets.TCPClient | |
try { | |
$Connection.Connect($ComputerName, $Port) | |
return $true | |
} | |
catch { | |
return $false | |
} | |
finally { | |
$Connection.Dispose() | |
} | |
} | |
function Get-DisplayName { | |
param ( | |
[Parameter(Mandatory)][string]$ComputerName | |
) | |
if ($ComputerName -match '\d+\.\d+\.\d+\.\d+') { | |
# We have received an IP | |
$HostDisplayName = $ComputerName | |
} else { | |
# We received a hostname, possibly with FQDN | |
$HostDisplayName = $ComputerName.split('.')[0] | |
} | |
return $HostDisplayName | |
} | |
function Wait-RDPAvailable { | |
param ( | |
[Parameter(Mandatory)][string]$ComputerName, | |
[Parameter()][int]$DelaySeconds = 2 | |
) | |
Write-Host "Waiting for RDP to become available..." | |
while ($true) { | |
$ConnectSuccess = Test-TCPPort ` | |
-ComputerName $ComputerName ` | |
-Port 3389 | |
if ($ConnectSuccess) { | |
break | |
} | |
Write-Verbose "Sleeping $DelaySeconds seconds..." | |
Start-Sleep $DelaySeconds | |
} | |
} | |
function Wait-StatusChange { | |
param ( | |
[Parameter(Mandatory)][string]$ComputerName, | |
[Parameter(Mandatory)][bool]$Online, | |
[Parameter()][int]$DelaySeconds = 2 | |
) | |
if ($Online) { | |
Write-Host "Waiting for $ComputerName to come online..." | |
} else { | |
Write-Host "Waiting for $ComputerName to go offline..." | |
} | |
while ($true) | |
{ | |
$HostOnline = Get-OnlineStatus -ComputerName $ComputerName | |
if ($HostOnline -eq $Online) { | |
break | |
} | |
Write-Verbose "Sleeping $DelaySeconds seconds..." | |
Start-Sleep -Seconds $DelaySeconds | |
} | |
} | |
function Get-OnlineStatus { | |
param ( | |
[Parameter(Mandatory)][string]$ComputerName | |
) | |
return $(Test-NetConnection -ComputerName $ComputerName -InformationLevel Quiet) | |
} | |
Set-Variable AppLogo -Option Constant -Value "C:\Work\scripts\royalts.png" | |
# Disable progress bars | |
$OriginalProgressPreference = $Global:ProgressPreference | |
$Global:ProgressPreference = 'SilentlyContinue' | |
try { | |
# Shorten the host's display name, if a FQDN is passed (otherwise it might be too long for the notification text) | |
$HostDisplayName = Get-DisplayName -ComputerName $ComputerName | |
# Bind hash table for notifications | |
$ToastDataBind = @{ | |
FirstLine = "Host Monitor" | |
SecondLine = "Monitoring $HostDisplayName" | |
Thirdline = '' | |
ProgressStatus = '' | |
} | |
$ToastID = "HostMonitor_${HostDisplayName}" | |
$Progress = New-BTProgressBar -Status 'ProgressStatus' -Indeterminate | |
New-BurntToastNotification ` | |
-AppLogo $AppLogo ` | |
-Text 'FirstLine','SecondLine','Thirdline' ` | |
-UniqueIdentifier $ToastID ` | |
-DataBinding $ToastDataBind ` | |
-ProgressBar $Progress | |
# Get the initial state | |
$HostOnline = Get-OnlineStatus -ComputerName $ComputerName | |
if ($HostOnline) { | |
# Host is still online, wait for it to go offline | |
Write-Verbose 'Host is online' | |
$ToastDataBind['Thirdline'] = "Host is online" | |
$ToastDataBind['ProgressStatus'] = 'Waiting to go offline...' | |
Update-BTNotification -UniqueIdentifier $ToastID -DataBinding $ToastDataBind | |
Wait-StatusChange -ComputerName $ComputerName -Online $false | |
} | |
Write-Verbose 'Host is offline' | |
$ToastDataBind['Thirdline'] = "Host is offline" | |
$ToastDataBind['ProgressStatus'] = 'Waiting to come online...' | |
Update-BTNotification -UniqueIdentifier $ToastID -DataBinding $ToastDataBind | |
Wait-StatusChange -ComputerName $ComputerName -Online $true | |
Write-Verbose 'Host is online' | |
$ToastDataBind['Thirdline'] = "Host is online" | |
$ToastDataBind['ProgressStatus'] = 'Waiting for RDP service...' | |
Update-BTNotification -UniqueIdentifier $ToastID -DataBinding $ToastDataBind | |
Wait-RDPAvailable -ComputerName $ComputerName | |
Write-Verbose 'RDP is available' | |
$ToastDataBind['Thirdline'] = "RDP is available" | |
# Provide a button to connect to the host using RoyalTS | |
$Button = New-BTButton -Content 'Connect' -Arguments "rtscli://local/action/connect?-id=${ConnectionID}" | |
# Replace the notification, thereby removing the progressbar and offer a connect button | |
New-BurntToastNotification ` | |
-AppLogo $AppLogo ` | |
-Text 'FirstLine','SecondLine','Thirdline' ` | |
-Button $Button ` | |
-UniqueIdentifier $ToastID ` | |
-DataBinding $ToastDataBind | |
} | |
finally { | |
# Restore progress preference setting | |
$Global:ProgressPreference = $OriginalProgressPreference | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment