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.
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.
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://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)) } }
Leave a Reply