Wait for it

A better way to wait for a remote host to become available through RDP after a reboot.

— Binary Adventures

If you use RDP (Remote Desktop), it can become tedious when rebooting the remote server or workstation, having to wait for it to come back online until you can reconnect to it.

The usual strategy is to use a continuous ping (e.g. ping -t -w 30 <remote-host-name-or-ip>) to check whether the computer goes offline and comes online again. Next, you’re either a patient person who waits a minute before initiating an RDP connection, or you’re like me, which means instantly trying to connect over and over again.

A better way

There has to be a more eloquent approach, right? Why not have PowerShell take over from ping.exe and add a little intelligence to the whole ordeal, leaving our hands free until the remote host is actually ready to receive RDP connections.

PowerShell contains the function Test-NetConnection that can perform a ping test and TCP test. We’ll use the former to check if the host is online or not, and the latter to verify if the RDP service is running (i.e. if we can connect with Remote Desktop).

You can find the complete script below.

  • Check if the remote host is offline. If not, wait for it to go offline (this assumes that we start monitoring as soon as, or before, we issue a reboot, when the host is still available).
  • When the remote host is offline, wait for it to come online again.
  • After it comes online, check if the host reponds on the RDP port (3389).

Update: the Test-NetConnection call has been replaced with a custom function Test-TCPPort for the RDP test, as the former always performs a ping (which takes additional time and is not necessary in this scenario).

Added sugar

Notifications

You probably don’t want to keep an eye on the command output, checking the host’s status (as you did with the ping command). Ideally, the script should notify you of any status changes. That’s why I’ve opted to included the BurntToast module, which makes it possible to display Windows notifications from within PowerShell. You’ll obviously need to install BurntToast, using the following PowerShell command:

Install-Module -Name BurntToast

The script contains a variable $AppLogo, which refers to an image file used in the notifications.

Set-Variable AppLogo -Option Constant -Value "royalts.png"

If you’re prefer using the default image, remove the variable and the -AppLogo parameter passed to the New-BurntToastNotification cmdlet.

RoyalTS

I use RoyalTS to manage my RDP connections, and I’ve configured a Task object, so that I can execute the script on any given host. RoyalTS will execute the script, passing the hostname and the internal ID.

Here’s how to configure the Task object:

  • Command: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  • Arguments: -WindowStyle Minimized -File WaitForIt.ps1 -ComputerName "$URI$" -ConnectionID "$ID$"

The PowerShell window is minimised when run, as we’re not interested in its contents (we’re using Windows notifications, remember?). You could hide the window completely using -WindowStyle Hidden, but this would complicate things if for some reason you want to cancel/abort the script (you’d have to kill the PowerShell process).

Remember to modify the value for the -File parameter in the Task’s arguments, to include the full path where you’ve stored it.

The object ID is used in the final notification, where we show a button to connect to the remote host. Behind it is a URL, using RoyalTS’s URI scheme, seamlessly establisting the RDP connection in the app.

Preview

Code

Reference