Using rdesktop to script Windows

For the past couple months, our university has been spending a huge amount of money and workforce to deploy a Microsoft Exchange environment in place of our current well-functioning, well-tested, lowmaintenance and cheap mail solution.

To make this Exchange environment available from the outside, ISA Server 2006 Enterprise Edition (Internet Security and Acceleration Server 2006 from Microsoft) will be implemented to publish the different services to the internet. This task falls onto 2 people, of which I represent half.

Being the lazy sucker that I am, I plan to not do a lot of clicking, because that would mean making very detailed documentation with screenshots and whatnot. Instead, I want everything to be scripted. To do this, I decided to use a combination of rdesktop (for the RDP connection to the Windows Server) and powershell (for the scripting on the Windows side).

There is not that much information on automating the ISA Server 2006 installation, once the installation of the executables is done. But I've managed to advance a great deal in this area in the last week. The question I ask myself now, is how to transfer this knowledge into the Internet knowledge pool.

Executing a batch script remotely using rdesktop

Rdesktop opens an RDP connection to a host and shows the result. But just having a Windows desktop sitting there is not of much use to me. I want to execute a command on that Windows server. The rdesktop tool has a "-s" flag which specifies which shell to run on the remote side. And we can use that one to start pretty much anything. However, just opening "cmd.exe" will suffice.

rdesktop -u p0036393 -d PAD -g 1240x1024 -s "cmd.exe"

The above command has quite a few options that I will explain:

The remote host we want to connect to, in this case, the ISA server

-u p0036393

The user to login as

-d PAD

The domain to logon to

-g 1240x1024

The resolution of the displayed desktop

-s "cmd.exe"

The shell to use

You can also specify a password on the commandline with the "-p" flag, but I won't do that here.

Executing cmd.exe by itself is not of much use either. We want to execute a script or something like that. This can be accomplished with the "/C" and "/K" flags of cmd.exe. They both do almost the same thing. The difference is that "/C" will close the cmd.exe windows when the specified command finished, while "/K" will keep it open.

When doing tests, I recommend using "/K", because then you can type "logoff" to log out of the Windows environment. If you use "/C", cmd.exe terminated and you are left in a empty desktop, where even right-click doesn't do anything. The only way to get out of there is then to close the rdesktop window, but that won't close the session. You'll have to log into the Windows server and kill the session manually. I think there are only 3 available RDP sessions. When you've used them up, you need to clean up the mess or won't be able to login with RDP again.
So take the advise, and just use "/K" and logout every time.

This command will echo "hello world" and drop you into the shell:

rdesktop -u p0036393 -d PAD -g 1240x1024 -s "cmd.exe /K echo hello world"

This is the basis to do some nice scripting on Windows with rdesktop, but it's really impractical to put the entire script on 1 line behind cmd.exe, if it even allows long lines (which I doubt).

Another way to do this, would be to create a batch file like this:

echo hello world

save it as "C:\hello.bat"

and execute it with rdesktop:

rdesktop ... -s "cmd.exe /K C:\hello.bat"

Of course, if you're like me, you don't want to go through the trouble of copying your files to a Windows server, with the intent to execute them through rdesktop later on. The whole idea is to script everything using rdesktop.

Fortunately, rdesktop has a cool feature that allows you to make a local directory available on the remote server. You can do this with the "-r disk:" option, which looks like this:

rdesktop -r disk:local="/home/deepstar/"

In this example, I make my homedirectory "/home/deepstar" available on for the duration of the RDP session. The directory will be called "local" on the remote side and you can find it as "\\tsclient\local"

Now I can access all my files on the Windows host, including the batch script I created locally.
Unfortunately, cmd.exe can not access \\tsclient\local for some reason (something to do with UNC path and a registry setting). So we have to make it available in another way.

Using the "net" command in Windows, you can map a network drive onto a local drive:

net use x: \\tsclient\local

This will map \\tsclient\local to X:, which is available from cmd.exe.

Now, unlike in bash, cmd.exe uses the "&" or "&&" keyword to separate commands on the commandline. So, to map the networkdrive to X: and execute the batch script all in a single invocation of rdesktop, this would be the commandline:

rdesktop -r disk:local="/home/deepstar/" -s "cmd.exe /K net use x: \\\\tsclient\local & x:\hello.bat"

Mind the 4 backslahes before "tsclient", this is to escape the \ character in bash.
X:\hello.bat is actually /home/deepstar/hello.bat on the client computer.

Well, that is really something.
Still, something is missing to make this method really usable for scripting. After the command is executed on the remote side, we want to log out and close rdesktop automatically. To do that, we need to log off of Windows.

Windows has the "logoff" command for that, which does exactly what you'd expect: log you off. After logging off, rdesktop exits automatically.

This rdesktop invocation will start the batch script and log out of windows:

rdesktop -r disk:local="/home/deepstar/" -s "cmd.exe /K net use x: \\\\tsclient\local & x:\hello.bat & logoff"

Just as an extra, it is also possible to reboot your Windows server from the commandline. To do that, invoke the "shutdown /r" command on Windows. This will announce that a reboot will happen in 30 seconds, and after those 30 seconds, it will actually reboot. There is also a "/t" option to specify how long should be waited instead of the default 30 seconds.

This command will execute the batch script and reboot the server without waiting:

rdesktop -r disk:local="/home/deepstar/" -s "cmd.exe /K net use x: \\\\tsclient\local & x:\hello.bat & shutdown /t 0 /r"