,

AWS Tools for Powershell

Goals

  • Set up the tools
  • Get familiar with the tools
  • Launch some instances
  • Launch the full stack from VPC to Windows Based EC2 Instances  with a Domain Controller, IIS Web Server, Remote Desktop Gateway

What You Need

  • Basic PowerShell knowledge
  • Powershell v2 or later / Windows Management Framework
  • Powershell ISE
  • AWS Tools for Windows PowerShell
  • AWS Account and an IAM role with Administrator permissions.

AWS Tools for Powershell

Check your powershell version $psversiontable

If you you do not have a version listed at all, you have v 1.0. You will need to upgrade so go ahead and download the latest version of the Windows Management Framework available for you OS.

Install the AWS Tools for Windows PowerShell.

Setting up Your AWS Profile in Powershell

AWS IAM User

If you don’t have an AWS account, stop here and get one, then set up an IAM user that has Administrator permissions.

Be sure to make note of the AccessKey and SecretKey of that user.

In my case my user is in a group  called “Admins” and that group has the following policy attached.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}
Setting up Your AWS Profile in PS

In order to interact with AWS we usually have to tell it who we are (authentication credentials) and what region we are looking to work in.

We could certainly provide this info for each command we issue, but we would have to type that info out everytime and potentially expose your credentials. Lets simplify and secure by storing this information in a profile.

The AWS Tools for Windows PowerShell can use either of two credentials stores.

  • The AWS SDK store, which encrypts your credentials and stores them in your home folder.
  • The credentials file, which is also located in your home folder, but stores credentials as plain text. By default, the credentials file is stored here: C:\Users\username\.aws\credentials.

We will store them in the AWS SDK store so they are encrypted with the following powershell command.

Set-AWSCredential -AccessKey AAAAAAAAAAAAAAAAAAAAAAAAAAAA -SecretKey SSSSSSSSSSSSSSSSSSSSSSSSSSSS -StoreAs YourProfileName

Note that AAAAAAAAAAAAA and SSSSSSSSSSSSSSS represent the AccessKey and Secret key for your IAM user with Administrator permissions.

Verify the profile is properly stored

Get-AWSCredential -ListProfileDetail

You should see that YourProfileName is securely stored

ProfileNameStoreTypeName ProfileLocation
----------- ------------- ---------------
YourProfileName NetSDKCredentialsFile

Now if we tried to run Get-Ec2Instance we would get an error because we still haven’t told AWS who we are to what region we want to work in.

Lets do that.

Get-EC2Instance -ProfileName YourProfileName -Region us-east-1

We get now get some info on our EC2 instances.

GroupNames : {}
Groups : {}
Instances : {WebServerKey}
OwnerId : 659152461139
RequesterId :
ReservationId : r-00fa002c52b620dd

But we don’t want to have to specify the Profile Name and Region on every command. It takes too long. Let’s set these as defaults so thay are assumed every time we open up Powershell and issue AWS commands.

Initialize-AWSDefaults -ProfileName YourProfileName -Region us-east-1

Ok that does it for the high-level setup. Lets do some discovery of whats under the covers.

Cmdlets Discovery

PS C:\Users\Brahim> get-module AWSPowerShell

ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Binary 3.3.245.0 AWSPowerShell {Add-AASScalableTarget, Add-ACMCertificateTag, Add-ADSConf...

In version 3.3.245 of the module there are 4103 commands!

PS C:\Users\Brahim> get-command -Module AWSPowerShell | Measure-Object

Count : 4103
Average :
Sum :
Maximum :
Minimum :
Property :

Go ahead and see that they are.. I’ll wait…

get-command -Module AWSPowerShell

🙂

Lets see the 278 commands that have EC2 as the noun

get-command -Noun ec2*

Now that we have run a few commands lets get a history of the AWS related commands we have executed.

$AWSHistory


Item                :
Commands            : {Get-EC2Instance}
LastCommand         : Get-EC2Instance
LastServiceResponse : Amazon.EC2.Model.DescribeInstancesResponse
LastServiceRequest  :

In true .net fashion let’s use some dot notation to drill into the object further for a bit more debugging data.

PS C:\Users\Brahim>

$AWSHistory.Commands.LastServiceResponse | Format-List


LoggedAt         : 3/8/2018 6:10:08 PM
NextToken        :
Reservations     : {659152461139, 659152461139, 659152461139, 659152461139}
ResponseMetadata : Amazon.Runtime.ResponseMetadata
ContentLength    : -1
HttpStatusCode   : OK

Creating EC2 Instances

 

Finding an image to use

Let’s get a sense of what Windows AMI images are available

Get-EC2ImageByName


WINDOWS_2016_BASE
WINDOWS_2016_NANO
WINDOWS_2016_CORE
WINDOWS_2016_CONTAINER
WINDOWS_2016_SQL_SERVER_ENTERPRISE_2016
WINDOWS_2016_SQL_SERVER_STANDARD_2016
WINDOWS_2016_SQL_SERVER_WEB_2016
WINDOWS_2016_SQL_SERVER_EXPRESS_2016
WINDOWS_2012R2_BASE
WINDOWS_2012R2_CORE
WINDOWS_2012R2_SQL_SERVER_EXPRESS_2016
WINDOWS_2012R2_SQL_SERVER_STANDARD_2016
WINDOWS_2012R2_SQL_SERVER_WEB_2016
WINDOWS_2012R2_SQL_SERVER_EXPRESS_2014
WINDOWS_2012R2_SQL_SERVER_STANDARD_2014
WINDOWS_2012R2_SQL_SERVER_WEB_2014
WINDOWS_2012_BASE
WINDOWS_2012_SQL_SERVER_EXPRESS_2014
WINDOWS_2012_SQL_SERVER_STANDARD_2014
WINDOWS_2012_SQL_SERVER_WEB_2014
WINDOWS_2012_SQL_SERVER_EXPRESS_2012
WINDOWS_2012_SQL_SERVER_STANDARD_2012
WINDOWS_2012_SQL_SERVER_WEB_2012
WINDOWS_2012_SQL_SERVER_EXPRESS_2008
WINDOWS_2012_SQL_SERVER_STANDARD_2008
WINDOWS_2012_SQL_SERVER_WEB_2008
WINDOWS_2008R2_BASE
WINDOWS_2008R2_SQL_SERVER_EXPRESS_2012
WINDOWS_2008R2_SQL_SERVER_STANDARD_2012
WINDOWS_2008R2_SQL_SERVER_WEB_2012
WINDOWS_2008R2_SQL_SERVER_EXPRESS_2008
WINDOWS_2008R2_SQL_SERVER_STANDARD_2008
WINDOWS_2008R2_SQL_SERVER_WEB_2008
WINDOWS_2008RTM_BASE
WINDOWS_2008RTM_SQL_SERVER_EXPRESS_2008
WINDOWS_2008RTM_SQL_SERVER_STANDARD_2008
WINDOWS_2008_BEANSTALK_IIS75
WINDOWS_2012_BEANSTALK_IIS8
VPC_NAT

I noticed that this command only lists the Windows images. What about linux? That’s not nice! I will get back to options for discovering linux AMIs later on.

We can take a look at all of the properties of the object.

Get-EC2ImageByName windows_2016_base | Select-Object


Architecture : x86_64
BlockDeviceMappings : {/dev/sda1, xvdca, xvdcb, xvdcc...}
CreationDate : 2018-03-06T05:36:15.000Z
Description : Microsoft Windows Server 2016 with Desktop Experience Locale English AMI provided by Amazon
EnaSupport : True
Hypervisor : xen
ImageId : ami-cab14db7
ImageLocation : amazon/Windows_Server-2016-English-Full-Base-2018.03.06
ImageOwnerAlias : amazon
ImageType : machine
KernelId :
Name : Windows_Server-2016-English-Full-Base-2018.03.06
OwnerId : 801119661308
Platform : Windows
ProductCodes : {}
Public : True
RamdiskId :
RootDeviceName : /dev/sda1
RootDeviceType : ebs
SriovNetSupport : simple
State : available
StateReason :
Tags : {}
VirtualizationType : hvm

For now let’s inspect the image with a paired down set of properties. ImageId is of interest.

Get-EC2ImageByName windows_2016_base | Select-Object -Property Name,ImageId

Name                                             ImageId
----                                             -------
Windows_Server-2016-English-Full-Base-2018.03.06 ami-cab14db7

So to launch a Windows image I need the proper ImageID. Here, the ImageID is instantiated into a variable $WinImageID that will be used to launch the instances.

$WinImageID = Get-EC2ImageByName windows_2016_base | select -First 1  -expand imageid
Echo $WinImageID


ami-cab14db7

What about linux images? It is annoying to me that Get-EC2ImageByName only lists Windows images. If you know why, I’d love to know.

For linux, I had to determine the string pattern on the name and go with that to get a response which shows some nice fresh images.

Get-EC2ImageByName -Names *amzn2-ami-hvm*x86_64*  | select -First 1


Architecture        : x86_64
BlockDeviceMappings : {/dev/xvda}
CreationDate        : 2018-01-16T19:06:49.000Z
Description         : Amazon Linux 2 LTS Candidate AMI 2017.12.0.20180115 x86_64 HVM GP2
EnaSupport          : True
Hypervisor          : xen
ImageId             : ami-428aa838
ImageLocation       : amazon/amzn2-ami-hvm-2017.12.0.20180115-x86_64-gp2
ImageOwnerAlias     : amazon
ImageType           : machine
KernelId            :
Name                : amzn2-ami-hvm-2017.12.0.20180115-x86_64-gp2
OwnerId             : 137112412989
Platform            :
ProductCodes        : {}
Public              : True
RamdiskId           :
RootDeviceName      : /dev/xvda
RootDeviceType      : ebs
SriovNetSupport     : simple
State               : available
StateReason         :
Tags                : {}
VirtualizationType  : hvm

So to launch a Linux image I need the proper ImageID. Here, the ImageID is instantiated into a variable $LinuxImageID that will be used to launch the instance.

$LinuxImageID = Get-EC2ImageByName -Names *amzn2-ami-hvm*x86_64* | select -First 1  -expand imageid
echo $LinuxImageID

ami-428aa838

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Lets see what instances I have already deployed.

(Get-EC2Instance).Instances

InstanceId          InstanceType Platform PrivateIpAddress PublicIpAddress SecurityGroups       SubnetId        VpcId
----------          ------------ -------- ---------------- --------------- --------------       --------        -----
i-0746c6e7a12f92c94 t2.micro              172.31.82.219                    {Public - WebServer} subnet-4500e66a vpc-6477a41c
i-0b06e2ea62eeb074f t2.micro     Windows  172.31.91.213                    {Public - WebServer} subnet-4500e66a vpc-6477a41c
i-03bf964f8c8aa8b1f t2.micro              172.31.81.118                    {Public - WebServer} subnet-4500e66a vpc-6477a41c
i-07e4c360067205f61 t2.micro     Windows  172.31.36.155                    {Public - WebServer} subnet-6ccdd636 vpc-6477a41c

hmm

 

 

Resources

Video: AWS Tools for Windows PowerShell