Day 34: Deploying instances in Amazon Web Services with PowerShell

Welcome to Day 34 of the “100 Days of DevOps with PowerShell”! For background on our goals in this series, see Announcing the “100 Days of Devops with PowerShell” Series here at SCC.

In the previous post from Day 29 we looked at getting started with Amazon Web Services (AWS), so in this post we’re going to deploy some instances from an Amazon Machine Image (AMI).  These are images provided by AWS, of which there are over 800 and in the previous post we looked at using filters to find the image that we wanted to use.  Rather than using filters there is another cmdlet that can be used to find a suitable image and that is Get-EC2ImageByName.  Running Get-EC2ImageByName by itself will list the following AMIs:


Note: if you don’t see a list similar to the above, check the version of AWS Tools installed (Get-AWSPowerShellVersion), running the latest version of the tools will return later versions of the images.

We want to deploy the latest operating system so running the following will return not just the latest version of Windows Server 2012 R2:

We specify [0] because previous versions of the image are also returned in a list.  [0] is the most current version based on the patch level for the month.  For example $ami[1] would be image based on the previous month’s Microsoft patches.


Deploying An Instance

To deploy an instance using the New-EC2Instance cmdlet we need to specify the the imageId which is highlighted above.  So with just a few lines we can deploy a new instance in AWS and it will be deployed into EC2-Classic.  EC2-Classic is the legacy compute cloud environment and all new product development is in Virtual Private Clouds (VPC).  We’ll look at what VPCs offer in a later post, but for now EC2-Classic will fit the bill.  In the code below we’re also specifying the KeyName parameter which is the name of the key pair that AWS will use to encrypt the Windows password and if we remember from Day 29 we made sure that we stored that key file in a secure location so the password can be decrypted.  Finally the last few lines will show how to retrieve information on the instance we have just deployed.  Running Get-EC2Instance won’t return a great deal of information, but will return a series of reservations.  It’s possible using the –MinCount and –MaxCount parameters to specify more than one instance to deployed, so the reservation contains all the instances we may have deployed.  In this example we’re only deploying one instance so we can refer to the instance in the reservation as [0] or not specify the item  number and it will retrieve the only one.  The –InstanceType parameter specifies the hardware specifications of the instance and this is typically RAM, CPU and disk speed.  The ‘t1.micro’ is one of the smaller instance specifications, but for a full list and their costs refer to AWS Monthly Calculator.

In line 4 of the code sample, we’re retrieving the public DNS name that we’ll use to RDP into the server.  To get the publicDNSname we’re using the Get-EC2Instance cmdlet and searching using a filter for the ReservationId that was returned when we initially launched the instance.  This returns the $reservation object and we’re using the RunningInstance list to retrieve all the properties of the instance, but also specifying PublicDNSName.  To view all the properties, we can simply run the same line again, but without PublicDNSName:


You could also retrieve the PublicDNSName by running the line below, but I have found that sometimes the RunningInstance list is empty immediately after deployment and searching for the reservation-id using a filter is more reliable.

Retrieving The Windows Password

You may also notice that in the code to deploy the instance we pause for 180 seconds while the instance is being provisioned.  This process typically takes 1-3 minutes, but the process is not over yet because we still need to decrypt the Windows password and this takes slightly longer.  To decrypt the Windows password we need to use the pem file from our key pair, but most importantly we need to use the Get-Ec2PasswordData cmdlet when the instance deployed and ready.  In the code below is a function that will keep checking if the password is available and then retrieve it once it’s ready.


And finally a password!


In this post we’ve looked at deploying an EC2 instance and in the context of DevOps it demonstrates that server provisioning no longer has to be the sole responsibility of IT operations.  Developers can provision their own environments without the dependency on other people and departments, but critically because it’s cloud based the resource constraints from storage and capacity on the host hypervisors are no longer a factor.

3 thoughts on “Day 34: Deploying instances in Amazon Web Services with PowerShell

  1. Shaun Collins

    Great article Luke! Do you know how Amazon’s VM updates vary from Azure? Is there a good source of info on how to configure the Amazon equivalent of an availability set?

  2. Luke Swords Post author

    Hi Shaun,

    From my experience with AWS I have never received any notifications to say my instances will be unavailable due to host OS patching in the same way you do with an Azure VM not part of an availability set.  AWS has distinct regions across the globe and within each region are availability zones.  For example the us-east-1 region has three availability zones.  You can find more information on regions and availability zones here: and also in the EC2 FAQ .



  3. Wilson W.

    In my company we don’t patch AWS instances.  We roll OS patches into our CloudFormation scripts and simply blow away the old instance and redeploy it.  This ensures that when our instances auto-scale they are always current and up-to-date…. and it eliminates the delta between your images and your deployed environments that change over time.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.