Finding Windows and Amazon Linux AMIs with PowerShell

Amazon Web Services (AWS) provides some built-in parameters in the AWS Systems Manager Parameter Store service, which expose pointers to the latest version of Amazon Machine Images (AMI) for Windows Server and Amazon Linux. These special parameters are called “public parameters” in the Parameter Store services; for more information, check out the official documentation. In addition to the service documentation, there are also two blog posts that talk about the Windows Server AMI parameters and the Amazon Linux AMI parameters.

In this article, we’ll take a look at how to use the AWS PowerShell module to retrieve and filter these public parameters. PowerShell’s built-in commands, such as Where-Object, Sort-Object and Format-Table can help us manipulate the data from the public parameters, harnessing it for our specific needs.

Windows AMIs

There are many different Microsoft Windows Server AMIs available, depending on the desired language. Additionally, AWS provides Windows Server AMIs that include various editions of Microsoft SQL Server installed. Having all of these extra AMIs can make it hard to find the right AMI for a vanilla installation of Windows Server.

If you’d like to filter out older versions of Windows Server, and return English-only results, you can use the command below. This command will also filter out the images that include Microsoft SQL Server pre-installed, so you can focus on the OS-only base images.

NOTE: This will only retrieve the SSM public parameters for the “current” (default) AWS Region that’s configured in your shell. Use the Set-DefaultAWSRegion command to configure your “current” operating region, otherwise tack on the -Region parameter to the Get-SSMParametersByPath command below.

Get-SSMParametersByPath -Path /aws/service/ami-windows-latest/ |
  Where-Object -FilterScript { $PSItem.Name -match 'English' -and $PSItem.Name -notmatch '2003|2008|2012|sql' } |
  Sort-Object -Property Name | 
  Format-Table -Property Name, Value

If you’d like to gather the AMI IDs from all AWS Regions in a single command, try the following:

Get-AWSRegion | ForEach-Object -Process {
  Get-SSMParametersByPath -Path /aws/service/ami-windows-latest/ -Region $PSItem.Region |
    Where-Object -FilterScript { $PSItem.Name -match 'English' -and $PSItem.Name -notmatch '2003|2008|2012|sql' } |
    Add-Member -MemberType NoteProperty -Name Region -Value $PSItem.Region -PassThru
  } |
  Sort-Object -Property Name |
  Format-Table -Property Name, Value, Region

If you receive an error message with the text “The security token included in the request is invalid“, just ignore it. You probably are seeing that because your account doesn’t have access to AWS GovCloud regions.

Once you run the command above, you should see some output similar to the following. It may take some time for the command to run, as it must query each of the AWS regions individually, before aggregating, sorting, and displaying, the results.

Name                                                                              Value                 Region
----                                                                              -----                 ------
/aws/service/ami-windows-latest/Windows_Server-1709-English-Core-Base             ami-01720a00e5b591f60 us-west-2
/aws/service/ami-windows-latest/Windows_Server-1709-English-Core-Base             ami-0308954f5c68838e1 ap-southeast-2
/aws/service/ami-windows-latest/Windows_Server-1709-English-Core-Base             ami-08e35adb597d62a15 ap-southeast-1
/aws/service/ami-windows-latest/Windows_Server-1709-English-Core-Base             ami-054c90a12eb119646 ca-central-1
/aws/service/ami-windows-latest/Windows_Server-1709-English-Core-Base             ami-0c09695ebd93d4d08 eu-central-1
...

Amazon Linux AMIs

There are many fewer Amazon Linux AMIs exposed as public parameters, as of this writing. Hence, we don’t need to perform the same level of filtration to the data, to make it usable.

Get-SSMParametersByPath -Path /aws/service/ami-amazon-linux-latest | 
  Format-Table -Property Name, Value

You should receive some results similar to the following:

Name                                                                  Value
----                                                                  -----
/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-ebs          ami-0d1d9e1864d1494b6
/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-gp2          ami-07a0c6e669965bb7c
/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-s3           ami-0a5181755fb620f2c
/aws/service/ami-amazon-linux-latest/amzn-ami-minimal-hvm-x86_64-s3   ami-0148d8b4516099462
/aws/service/ami-amazon-linux-latest/amzn-ami-minimal-pv-x86_64-s3    ami-05c390c7e9936df84
...