Microsoft Workloads on AWS

Update AWS Tools for PowerShell at scale with AWS Systems Manager

In this blog post, I will show you how to update AWS Tools for PowerShell at scale within your environment by using the AWS Systems Manager Run Command.

Manually updating AWS Tools for PowerShell across multiple instances can be time-consuming, inefficient, and error prone. These manual operational efforts typically result in a logistical nightmare, especially within large enterprise environments. The AWS Tools for PowerShell are a set of PowerShell modules that are built on the functionality exposed by the AWS SDK for .NET, which enable you to script operations on your AWS resources within the PowerShell command line. And with AWS Systems Manager, you can automate operational tasks across both your AWS cloud environment and on-premises servers, simplifying resource and application management. This facilitates operation and management of your infrastructure securely at scale.

For this blog post, I will create a workflow that uses the AWS Systems Manager Run Command feature. This workflow will run a PowerShell script that captures the AWS Tools for PowerShell version across all managed Amazon Elastic Compute Cloud (Amazon EC2) instances within an AWS account and update it to the latest version, if required.

Prerequisites

Walkthrough

  1. Open the AWS Systems Manager console and select the Run Command option under Node Management (Figure 1).

    Figure 1 - AWS Systems Manager - Run Command

    Figure 1 – AWS Systems Manager – Run Command

  2. Within the Commands pane, choose Run command (Figure 2).

    Figure 2 - Commands - Run a command

    Figure 2- Commands – Run command

  3. Within the Command document search box, type AWS-RunPowerShellScript and select the radio button for the AWS-RunPowerShellScript command (Figure 3).

    Figure 3 - Select RunPowerShellScript command type

    Figure 3- Run Command – Select RunPowerShellScript command type

  4. Under the Command parameters pane, paste the following PowerShell script, as shown in Figure 4:
    $repo = "PSGallery" # PowerShell Gallery (powershellgallery.com)
    
    # Validate NuGet provider is available (required to interact with PowerShell Gallery)
    if(-not (Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue)) {
    
      # Install NuGet provider if not present (required to interact with PowerShell Gallery)
      try {
        Install-PackageProvider -Name NuGet -Force | Out-Null
      }
      catch {
        Write-Error "Failed to install NuGet provider: $($_.Exception.Message)"
        Exit
      }
    
    }
    
    # Set approved repository
    Set-PSRepository -Name $repo -InstallationPolicy Trusted
    
    # Retrieve installed modules
    $installedModules = Get-InstalledModule -Name AWS* -ErrorAction Stop
    
    # Check if AWS modules are not installed
    if(-not $installedModules) {
      Write-Output "No AWS modules installed."
      Exit
    }
    
    # Loop through each installed AWS module
    foreach ($module in $installedModules) {
    
      # Try to get module from repository
      try {
        $repoModule = Find-Module -Name $module.Name -Repository $repo -ErrorAction Stop
      }
      catch {
        Write-Error "Failed to find $($module.Name) in repository: $($_.Exception.Message)"
        Continue
      }
    
      # Check if newer version available
      if ($repoModule.Version -gt $module.Version) {
    
        Write-Output "$($module.Name) $($module.Version) installed. $($repoModule.Name) $($repoModule.Version) available."
    
        # Uninstall outdated version
        try {
          Uninstall-Module -Name $module.Name -AllVersions -Force -ErrorAction Stop
        }
        catch {
          Write-Error "Failed to uninstall $($module.Name): $($_.Exception.Message)"
          Continue
        }
    
        # Install latest version
        try {
          Install-Module -Name $module.Name -Force -ErrorAction Stop -Repository $repo
          Write-Output "Updated $($module.Name) to $($repoModule.Version)"
        }
        catch {
          Write-Error "Failed to install $($repoModule.Name): $($_.Exception.Message)"
          Continue
        }
    
      }
      # Latest version is already installed
      else {
        Write-Output "$($module.Name) $($module.Version) is installed and is the latest available version."
      }
    
    }

    Figure 4- Run Command - PowerShell command parameters

    Figure 4- Run Command – PowerShell command parameters

This PowerShell script will search for all installed AWS PowerShell modules within the instance it is being run on. It will then compare the installed module version to the latest version available within the PowerShell Gallery and install the latest version, if applicable.

There are three AWS Tools for PowerShell package options available for Windows-based computers:

  • AWS.Tools – The modularized version of AWS Tools for PowerShell. Each AWS service is supported by its own individual small module.
  • AWSPowerShell.NetCore – The single large module version of AWS Tools for PowerShell. All AWS services are supported by this single large module.
  • AWSPowerShell – The legacy Windows-specific, single large module version of AWS Tools for PowerShell. All AWS services are supported by this single large module.

This script will only update the existing packages to a newer version. It will not replace one package with another (e.g., update AWSPowerShell to AWSPowerShell.NetCore). For more information on each available package, including how to determine which package to use, refer to What are the AWS Tools for PowerShell? in the user guide.

It is also worth noting that currently AWS Tools for PowerShell version 4 is the latest major release and provides backwards compatibility with AWS Tools for PowerShell version 3.3. If you are upgrading from version 3.3 to version 4, your existing scripts should continue to work with the new version. I recommend testing each of your scripts thoroughly prior to upgrading. For more information, refer to Migrating from AWS Tools for PowerShell Version 3.3 to Version 4.

  1. Once you have pasted the script within the Command parameters pane, scroll down to the Target selection pane. There are three methods for selecting targets within AWS Systems Manager Run Command:
    • Specify instance tags – Specify one or more tag key-value pairs to select instances that share those tags.
    • Choose instances manually – Manually select the instances you want to register as targets.
    • Choose a resource group – Choose a resource group that includes the resources you want to target.

In this example, I used the Specify instance tags method. I assigned a tag key of update-pstools with a value of yes to all the targets where I wanted to update AWS Tools for PowerShell (Figure 5).

Figure 5- Run Command - Target selection

Figure 5- Run Command – Target selection

The Run Command functionality within AWS Systems Manager allows for command output to be written to an Amazon Simple Storage Service (Amazon S3) bucket. You have the ability to stream command output to Amazon CloudWatch logs as well.

  1. Scroll down to the Output options section. In this example, I will disable the ability to write command output to an Amazon S3 bucket (Figure 6).
Figure 6- Run Command - Output options

Figure 6- Run Command – Output options

When ready to proceed, scroll to the bottom of the page and click on the Run button (Figure 7).

Figure 7- Run Command – Run

Command status and output

The command will now be run on all nodes with the tags specified in the previous step. You can check on the status of the command on each node by consulting the Status column under the Targets and outputs section. The status will be In Progress and eventually change to Success once the script is run on the target nodes (Figure 8).

Figure 8- Run Command - Targets and outputs

Figure 8- Run Command – Targets and outputs

Once the status changes to Success for a certain instance (Figure 9), you can click on the Instance ID to view the command output for that instance (Figure 10).

Figure 9- Run Command – Targets and outputs Status

Figure 10- Run Command - Command Output

Figure 10- Run Command – Command Output

Figure 10 shows that the sample instance had modularized versions of AWS Tools for PowerShell for multiple services. Each individual module was outdated and therefore updated to the most recent available version available when I ran the script.

Cleanup

Since no resources are created within your AWS account by following the steps outlined in this example, no cleanup is required.

Conclusion

In this blog post, I demonstrated how you can use the AWS Systems Manager Run Command to update AWS Tools for PowerShell within your managed nodes in a seamless and automated manner. This will allow you to reduce operational overhead, improve consistency within your environment, as well as enhance security by enabling updates to be performed in a timely, repeatable manner. To learn more about other AWS Systems Manager features, refer to the AWS Systems Manager documentation.


AWS has significantly more services, and more features within those services, than any other cloud provider, making it faster, easier, and more cost effective to move your existing applications to the cloud and build nearly anything you can imagine. Give your Microsoft applications the infrastructure they need to drive the business outcomes you want. Visit our .NET on AWS and AWS Database blogs for additional guidance and options for your Microsoft workloads. Contact us to start your migration and modernization journey today.

Andre Faria

Andre Faria

Andre Faria is a Senior Technical Account Manager based in Milford, Connecticut. He works within AWS Enterprise Support's Automotive Strategic Industries organization, supporting large automotive companies with their cloud journey. Outside of work, he is an aviation enthusiast and private pilot, so you will likely find him flying around the US Northeast.