PowerShell function to Provision a Windows Server EC2 Instance in AWS Cloud.

Microsoft just updated the ASWPowerShell module to better enable Cloud administrators manage and provision cloud resources in the AWS cloud space while using the same familiar PowerShell tool. As at last count today, the AWSPowerShell module contains almost four thousand cmdlets:

This means Microsoft is committed to expanding on PowerShell functionality as a robust tool for managing both Azure and Amazon cloud platforms.
In this post I want to quickly demonstrate how to provision an AWS EC2 instance using PowerShell. The following steps help accomplish this objective.

Install the ASWPowerShell Module.
For this post, I’ll be using the version 5.1.16299.98 of Windows PowerShell as indicated in the following screen shot:

I’ll install the AWSPowerShell module using the Find-Module cmdlet.

PS C:\Scripts> Find-Module -Name AWSPowerShell | Install-Module -Force

Configure AWS Credential Profile.
During initial signup for an AWS account, a root account is created with full administrative access. According to AWS best practices, while making API calls and using PowerShell to programmatically access and manage resources, a sub user account should be created with corresponding access key ID and secret key credentials. This way, if the keys are compromised, the associated user can be disabled instead of risking the compromise of the root account and all the resources associated with it.

Use the Users tab of the IAM (Identity and Access Management) console in the AWS portal to create a subuser and generate the corresponding access key ID and secret key.

After generating the keys, I’ll use the Set-AWSCredential cmdlet to save and persist the the credential keys to my local AWS SDK store for use across multiple PowerShell sessions. The Initialize-AWSDefaultConfiguration cmdlet sets the new profile and region as active within the PowerShell session. The following script accomplishes this task. Please note that the AccessKey and SecretKey parameter values are represented by variables:

#Set and Initialize AWS Credential and Profile for login and authentication
Set-AWSCredential -AccessKey $AccessKey -SecretKey $SecretKey -StoreAs AWSDemoProfile
Initialize-AWSDefaultConfiguration -ProfileName AWSDemoProfile -Region us-west-1

Create an EC2 Key Pair.
Use the New-EC2KeyPair cmdlet to create an EC2 key pair. This cmdlet calls the Amazon Elastic Compute Cloud CreateKeyPair API. It creates a 2048-bit RSA key pair with the specified name. Amazon EC2 stores the public key and displays the private key to be saved to a file. The private key is returned as an unencrypted PEM encoded PKCS#1 private key. The private key is used during the logon operation to a virtual machine to create a password for login. If a key with the specified name already exists, Amazon EC2 returns an error.Up to five thousand key pairs can be created per region. The key pair is available only in the region in which it is created. In the following script, I create the key, assign the key pair object to a variable and save the key material property of the key pair object locally to a file:

#Create Keypair for decrypting login creds
$awskey = New-EC2KeyPair -KeyName demo1key
$awskey.KeyMaterial | Out-File -FilePath C:\AWSCred\mykeypair.pem

Provision a Non-Default Virtual Private Cloud (VPC).
The first time I created my AWS account, a default VPC provisioned with a private ip address scheme.For the purpose of this post, I would prefer to create a custom non-default vpc with an address range of my choice. Unlike the default vpc, the non-default vpc does not have internet connectivity. Some extra configuration is needed to enable internet connectivity to the non-default vpc.
The following tasks are accomplished by the PowerShell script to enable internet connectivity for the custom non-default vpc:
Create the non-default vpc and enable dns hostnames
Tag the vpc with a friendly name
Create a custom subnet for the vpc and tag it
Create an internet gateway and attach it to the custom vpc
Create a custom route table for internet access and associate it with the custom subnet

#Create non default virtual private cloud/virtual network, enable dns hostnames and tag the vpc resource
$Ec2Vpc = New-EC2Vpc -CidrBlock "" -InstanceTenancy default
Edit-EC2VpcAttribute -VpcId $Ec2Vpc.VpcId -EnableDnsHostnames $true
$Tag = New-Object Amazon.EC2.Model.Tag
$Tag.Key = "Name"
$Tag.Value = "MyVPC"
New-EC2Tag -Resource $Ec2Vpc.VpcId -Tag $Tag

#Create non default subnet and tag the subnet resource
$Ec2subnet = New-EC2Subnet -VpcId $Ec2Vpc.VpcId -CidrBlock ""
$Tag = New-Object Amazon.EC2.Model.Tag
$Tag.Key = "Name"
$Tag.Value = "MySubnet"
New-EC2Tag -Resource $Ec2subnet.SubnetId -Tag $Tag
#Edit-EC2SubnetAttribute -SubnetId $ec2subnet.SubnetId -MapPublicIpOnLaunch $true

#Create Internet Gateway and attach it to the VPC
$Ec2InternetGateway = New-EC2InternetGateway
Add-EC2InternetGateway -InternetGatewayId $Ec2InternetGateway.InternetGatewayId -VpcId $ec2Vpc.VpcId
$Tag = New-Object Amazon.EC2.Model.Tag
$Tag.Key = "Name"
$Tag.Value = "MyInternetGateway"
New-EC2Tag -Resource $Ec2InternetGateway.InternetGatewayId -Tag $Tag

#Create custom route table with route to the internet and associate it with the subnet
$Ec2RouteTable = New-EC2RouteTable -VpcId $ec2Vpc.VpcId
New-EC2Route -RouteTableId $Ec2RouteTable.RouteTableId -DestinationCidrBlock "" -GatewayId $Ec2InternetGateway.InternetGatewayId
Register-EC2RouteTable -RouteTableId $Ec2RouteTable.RouteTableId -SubnetId $ec2subnet.SubnetId

Create Security Group.
In this section, I’ll create a security group with a rule to enable remote desktop access to the EC2Instance VM.
#Create Security group and firewall rule for RDP
$SecurityGroup = New-EC2SecurityGroup -Description "Non Default RDP Security group for AWS VM" -GroupName "RDPSecurityGroup" -VpcId $ec2Vpc.VpcId
$Tag = New-Object Amazon.EC2.Model.Tag
$Tag.Key = "Name"
$Tag.Value = "RDPSecurityGroup"
New-EC2Tag -Resource $securityGroup -Tag $Tag
$iprule = New-Object Amazon.EC2.Model.IpPermission
$iprule.ToPort = 3389
$iprule.FromPort = 3389
$iprule.IpProtocol = "tcp"
Grant-EC2SecurityGroupIngress -GroupId $securityGroup -IpPermission $iprule -Force

Get the AMI (Amazon Machine Image) and create an Elastic Public IP Address to be attached to the EC2Instance after initialization..
#Retrieve Amazon Machine Image Id property for Windows Server 2016
$imageid = (Get-EC2ImageByName -Name WINDOWS_2016_BASE).ImageId

#Allocate an Elastic IP Address for use with an instance VM
$Ec2Address = New-EC2Address -Domain vpc
$Tag = New-Object Amazon.EC2.Model.Tag
$Tag.Key = "Name"
$Tag.Value = "MyElasticIP"
New-EC2Tag -Resource $Ec2Address.AllocationId -Tag $Tag

Launch or Provision the EC2 Instance Virtual machine.
#Launch EC2Instance Virtual Machine
$ec2instance = New-EC2Instance -ImageId $imageid -MinCount 1 -MaxCount 1 -InstanceType t2.micro -KeyName mykeypair -SecurityGroupId $securityGroup -Monitoring_Enabled $true -SubnetId $ec2subnet.SubnetId
$Tag = New-Object Amazon.EC2.Model.Tag
$Tag.Key = "Name"
$Tag.Value = "MyVM"
$InstanceId = $ec2instance.Instances | Select-Object -ExpandProperty InstanceId
New-EC2Tag -Resource $InstanceId -Tag $Tag

Associate the Elastic Public IP Address to the EC2 Instance.
#Assign Elastic IP Address to the EC2 Instance VM
$DesiredState = “Running”
while ($true) {
$State = (Get-EC2Instance -InstanceId $InstanceId).Instances.State.Name.Value
if ($State -eq $DesiredState) {
“$(Get-Date) Current State = $State, Waiting for Desired State=$DesiredState”
Start-Sleep -Seconds 5
Register-EC2Address -AllocationId $Ec2Address.AllocationId -InstanceId $InstanceId

Display EC2 Instance Properties.
#Display VM instance properties
(Get-EC2Instance -InstanceId $InstanceId).Instances | Format-List

Remove or Terminate EC2 Instances.
#Clean up and Terminate the EC2 Instance
Get-EC2Instance | Remove-EC2Instance -Force

Logon to the EC2Instance using Remote Desktop protocol.
Login to the EC2 Instance Virtual machine can be initiated using the AWS EC2 Dashboard.The private key portion of the keypair will be used to create a password to login to the Virtual Machine as indicated in the following screen shots:

Select the EC2 Instance and click on the Connect button. On the Connect to your Instance page, click on the Get Password button.

On the Get Password page, copy and paste the private key from the keypair file into the content field and click to decrypt the key.

Copy the displayed password, download the RDP file and login to the EC2Instance. It is recommended to change the password and create a new local user after logon.

The full PowerShell Script can be found at my Github Repository

This entry was posted in AWS and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s