A function to set up AWS PowerShell credentials

If you have several different identities you use in your AWS PowerShell scripts, you might find this “cmdlet function” useful. It allows you to specify a region and stored profile to be used in your script. It also determines if you are running PowerShell 6 or Windows PowerShell and loads the proper module.

My habit is to store AWS credentials for the various different accounts and different identities within those accounts using Set-AWSCredentials with the -StoreAs parameter. This is a convenient way to have several different identities available as you develop AWS PowerShell scripts.

But it’s not as convenient as it could be. In addition to the AWS credentials used to establish identity, you typically need to switch to or specify an AWS region and, when switching PowerShell versions, you need to load the proper AWS PowerShell module, either AWSPowerShell for Windows or AWSPowerShell.NetCore for PowerShell 6.

That old saying that if you’re doing something manually more than once you should code it led me to create the function below. It allows you to specify the name of a previously stored AWS credentials file you have along with a region. It then uses Initialize-AWSDefaultConfiguration with those parameters. If successful, it calls Get-STSCallerIdentity and returns a hashtable with the account, userid and ARN of the currently authenticated user. To do this, it also checks which version of PowerShell you are running and loads the proper AWS PowerShell module.

Best of all, it’s written as a PowerShell advanced function, meaning you can pass the two required parameters ($AWSProfile and $AWSRegion) in the pipeline by name or by value. It also means that if you place the file with the .psm1 extension in a directory pointed to by $Env:PSModulePath it will be loaded in every console and shell.

To do this, create a subdirectory (I called mine “ConnectAWS”) in one of the module path directories and then copy this file into it using exactly the same filename as the directory name. The filetype must be .psm1.

Here’s a screenshot showing what I mean.

Setting up a function as a cmdlet in PowerShell 6
Setting up a function as a cmdlet in PowerShell 6 (click to enlarge)

Then, it’s a simple matter of using the function exactly like a cmdlet. In this screenshot, you can see that I call the cmdlet as normal, assigning its output to a variable and then displaying the output on the console.

Connect to AWS with stored credentials in PowerShell
Connect to AWS with stored credentials in PowerShell (click to enlarge)

I hope you find this useful.

Update: 2019-01-24: I wanted to be able to use tab completion with the two required parameters for the function so I added the obscure Register-ArugmentCompleter cmdlet to the function. It works like a charm and will save you plenty of keystrokes!

<#
    .SYNOPSIS
        A function to set up AWS credentials using a stored profile for a PowerShell script
    
    .DESCRIPTION
        This function initializes AWS defaults using stored credentials and returns the user, ARN and account number. Also, automatically loads the proper AWS PowerShell module for PowerShell 6 or Windows PowerShell.
    
    .PARAMETER AWSProfile
        Name of stored profile containing account credentials.
    
    .PARAMETER AWSRegion
        AWS region to be set as default.
    
    .EXAMPLE
        PS C:\> Connect-AWS -AWSProfile 'Name of stored profile' -AWSRegion 'AWS region name'
    
    .NOTES
        Alex Neihaus 2019-01-23
        (c) 2019 Air11 Technology LLC -- licensed under the Apache OpenSource 2.0 license, https://opensource.org/licenses/Apache-2.0
        Licensed under the Apache License, Version 2.0 (the "License");
        you may not use this file except in compliance with the License.
        You may obtain a copy of the License at
        http://www.apache.org/licenses/LICENSE-2.0
    
        Unless required by applicable law or agreed to in writing, software
        distributed under the License is distributed on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        See the License for the specific language governing permissions and
        limitations under the License.
        
        Author's blog: https://www.yobyot.com
#>
function Connect-AWS
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 1)]
        [System.String]$AWSProfile,
        [Parameter(Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 2)]
        [System.String]$AWSRegion
    )
    
    Begin
    {
        switch ($PSVersionTable.PSEdition)
        {
            "Core"
            {
                Import-Module AWSPowerShell.NetCore
            }
            "Desktop"
            {
                Import-Module AWSPowerShell
            }
            default
            {
                "There's a big problem; this version of PowerShell is unknown"
                "Returned edition of PowerShell is: $PSVersionTable.PSEdition"
                exit
            }
        }
        $error.clear() # Reset the error variable
    }
    Process
    {
        If ( ! (Get-AWSCredential -ProfileName default) ) # There is no default profile so set the input profile/region to be the default
        {
            Initialize-AWSDefaultConfiguration -Region $AWSRegion -ProfileName $AWSProfile
        }
        Set-DefaultAWSRegion -Region $AWSRegion # Output is in the local scope even though the function is probably running in the global or script scope
        $Global:StoredAWSRegion = $StoredAWSRegion # Set the global variable
        Set-AWSCredential -ProfileName $AWSProfile # Output is in the local scope even though the function is probably running in the global or script scope
        $Global:StoredAWSCredentials = $StoredAWSCredentials # Set the global variable
        if ( $null -eq $error[0] ) # Call succeeded
        {   
            $info = Get-STSCallerIdentity
            [hashtable]$ConnectAWS = @{
                AWSAccount = $info.Account;
                AWSArn     = $info.Arn;
                AWSUserid  = $info.UserId
            }
        }
        else
        {
            exit
        } 
    }
    End
    {
        return $ConnectAWS
    }
}
Register-ArgumentCompleter -CommandName 'Connect-AWS' -ParameterName 'AWSProfile' -ScriptBlock {
    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
    
    Get-AWSCredentials -ListProfileDetail |
        ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_.ProfileName, $_.ProfileName, 'ParameterValue', ("Group: " + $_.Group))
    }

}
Register-ArgumentCompleter -CommandName 'Connect-AWS' -ParameterName 'AWSRegion' -ScriptBlock {
    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)

    Get-AWSRegion |
        ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_.Region, $_.Region, 'ParameterValue', ("Group: " + $_.Group))
    }

}

Posted

in

, ,

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *