Autolaunch + RDP

Warning: Long post ahead!
TL;DR = Download the script here:

Yes, the title is sub-optimal, indeed. But let’s roll with it.

I’ll try to do some RDP automation today. I’m not entirely sure this will be useful, but the idea looks interesting so bear with me for a while. We may yet learn something from this.

For the experiment, we need an instance. Let’s see what we’ve got to work with:

Uh-oh! Five seconds into execution I realized the mistake.
To make it fun – you try it, too!

Did it take you more than 5 seconds? ๐Ÿ™‚

Don’t get me wrong, Get-EC2Image is actually very powerfull.
We just don’t need to filter through 54k (!) images right now.

Easy solution is:

Easy, right?

We simply need basic Windows options.
Same ones we have in the “Launch Instance” section of AWS Console.

So we’re going to cheat. Get-EC2ImageByName ! Oh, the little things in life ๐Ÿ™‚

Get the latest AMI ID for your region.

Presently, latest one in eu-west-1 is ami-2a0c2a59 .

Now we need to take a break and read some documentation.
“Not again!” right? I know, I know. Just a little bit.

Official documentation is good stuff, trust me. I have no idea why nobody reads it and then cries… But, I digress. Check out New-EC2Instance reference page.
I’ll wait.

Did you notice?
Only one mandatory parameter!
It just can’t be!

I refuse to believe (Yes, I’m stubborn like that) so I’m going to try it.

Look at the devil! It actually works!

What do we have here?

What?! m1.small :O That’s a… relic.

Let’s try not to do that. Usage of m1.* has been very discouraged and, in fact, today they cost more than m3.* instances.

Let’s use our second mandatory parameter, then: -InstanceType t2.small .
t2.small instance type has a pretty good cost/performance balance for the server that’s not going to do anything ๐Ÿ™‚

Here we go:

As you’ve seen, new instance will be placed in one of subnets of your default EC2 VPC. We won’t play with this. It’s not at all important how you create your instance, as long as you have one.

What’s important though, is to specify a keypair during launch.
Otherwise you’ll see a beautiful message:

You won’t like this message very much.

In fact, I’m fairly certain you’ll only see it once in your life.
Because you’ll, from now on, treat -KeyName parameter as mandatory, too.

Let’s include it then, and make a final instance call with three mandatory parameters:

Here’s a funny variable. Don’t ask.

Capture KeyName as well.

Now we have all we need.

Define your keys folder where we’ll look for your .pem file:

If you get creative with folder and key names and above fails, use something like this:

Or even this if you really take it to over the top:

Instance is now starting up. We need to know when it’s going to be ready for RDP connection.
State ‘running’ or Checks ‘2/2’ won’t tell us anything. Until software in the background does its stuff, we’ll wait at the “Password not available yet. Try again in 4 minutes” menu.

I find those 4 minutes to be a very random amount of time, but whatever.
We need to wait anyway, so may as well say we’re about to wait for four minutes for instance to be ready. See what I did there? ๐Ÿ™‚

We can, 2, wait 4 4 minutes 4 instance i-42424242 2 be ready!

Man, that joke totally bombed. Like I’m 7 years old again.
And for a second there I though this was hilarious.

But, an effort was spent and bad pun stays.
Rejoice in knowledge your life rocks compared to mine.


Let’s make a loop and bang API endpoint every 3 seconds. We are not yet ready, though.

Password to get into the instance via RDP is encrypted and we’ll get it using Get-EC2PasswordData. If successful, exit loop. If not, retry after three seconds.

In the meantime, add a dot to our Super Counter. I’ll call it Das Super Zรคhler because it’s quite obvious that everything sounds better in German.

Once we get the password, we’ll look for public DNS name. It’s not visible in our $Instance variable that we got after provision request so we’ll ask AWS for it.

I agree that looks more sexy than but DNS is made for humans and that’s what we’re going to use.

If you only knew how many problems wouldn’t even exist if people only learned to use DNS instead of hard-coding the fragile server’s IP address in their cod– Digression!

In short: One day you’ll use your own domain instead of and this will make perfect sense. Stop fighting logic. DNS wins.

Have cmdkey store user login information for us so we can use automatic RDP login. Check with cmdkey /list. If you don’t like it, add cmdkey /delete:$PublicDnsName after next line:

If all went well, our server is up and we’re now successfully logged in.

If you don’t like storing/deleting credentials, then use Connect-Mstsc by awesome Jaap Brasser and have it connect you to the instance.

Make sure to be aware of one thing here: Unless your default security group allows port 3389 connections by default you’ll need to specify one which does in our opening line:

And that’s it!

Wow! This was a pretty long journey for something seemingly so trivial.

As with the Route 53 test-turned-tutorial, I had fun here as well. Hope you had, too, and you learned something new ๐Ÿ™‚

While I can’t really find a very good use case for this, perhaps it can do as an instant bastion host. Launch it from your fully prepared AMI with all the tools and whatnot and be instantly connected. Once you don’t need it anymore, kill it with fire.

Perhaps it can be a temporary fix instance. You know when you screw up your instance so bad that you need to attach its root volume to a temporary instance and then have it fixed with EC2 Savior, edit offline registry or check crash dump?
Yes, that temporary instance ๐Ÿ™‚

I don’t know what else, you decide. If there’s a good use case you can think of, let me know!

An important note: At one point, in the middle of writing this post I remembered this is a blog, and my personal at that, and I don’t have to be official, tiptoe around people’s feelings nor refrain from using smileys.

So there you have it.
It’s not an apology by any means, just a clarification in case you wondered why this post got so horribly derailed near the end ๐Ÿ™‚

But I really do hope you enjoyed reading it as much as I did writing!

Oh, oh! Almost forgot! Mail server is up now, so make sure to drop me an email at or comment here!

If you feel like, you know, emailing or commenting ๐Ÿ˜‰

That’s all for today!
Fight well, and may the Force be with you!


Edit: After everything, I actually forgot to paste the complete script and link it! *facepalm*

Alright, here it is. I took another look at it and improved some basic try/catch error catching.
May be discussed further in some of the future posts.

Choose ‘Copy’ (5th icon) in the script header or click here to get it from S3:

Leave a Comment