It’s an all to familiar story. You need to reboot a server, and then you need to start a remote desktop connection into it. So what do you do? You open up a command prompt, type
ping -t <HOSTNAME> and wait until the server responds to pings. When that happens, you keep trying to connect via remote desktop, until it works. There’s got to be an easier way. You should write a PowerShell script to automate the process. However, its one of those things that not quite annoying enough to get you to actually take action and write the script. Luckily, thanks to the power of twitter, I reached a tipping point this week, and wrote the script. It all started out with some innocent whining:
You know what I need in an RDP client. I need an “”I just rebooted so ping it for me and autoreconnect”.
Then d0tk0m and Yanni Robel retweeted my whining. They say necessity is the mother of invention. In this case the commiseration off two tweeps was the father. So I spent a Saturday with PowerGUI, and came up with a script to solve the problem.
I wanted my script to automate what I already did. From the perspective a system administrator that wants to reboot a server and then remote desktop into it, the following happens.
- All the processes, including the remote desktop service (termsrv.dll) are shut down. When that happens the remote desktop port (default 3389) no longer has anything listening on it.
- Eventually the network adapter is shutdown and it will stop responding to ICMP echo requests, or pings.
- The server will finish shutting down, the BIOS will POST, and Windows will begin booting
- Eventually the network adapter will come up and start responding to pings.
- The remote desktop service will start and bind to the remote desktop port.
Therefore, I made my script to do the following.
- Ping the server until it answered five successive ping requests. Yes this might be naive and optimistic in many cases. However, it worked in my use case. I used the Send() method of the .NET System.Net.NetworkInformation.Ping class to do this.
- Once I was sure the host was up, I’d try to connect to it on port 3389, or another port if I passed a different port as a parameter. To do this I used the System.Net.Sockets.TcpClient class.
- After this it was simply a matter of passing the right parameters to the remote desktop client, mstsc.exe. I initially attempted to use the simple
& mstsc <Arguments>. However, that didn’t work to well so I ended up resorting to Invoke-Expression.
Below is the current version of the script, hosted on poshcode.org. The current version is stored in gist repository. While you are free to post changes to poshcode.org (or anywhere), in accordance with the license, I’d prefer if you notified me of any changes so that they may be placed in the gist git repo.