Using AWS CLI on Windows PowerShell with an MFA-Protected IAM User

7 min read

Introduction

In AWS, if you use the AWS CLI with an IAM user who has MFA (Multi-Factor Authentication) enabled, you must use the GetSessionToken API to obtain temporary credentials. This article shows you how to use the AWS CLI with an MFA-enabled IAM user on Windows and how to automate these steps using PowerShell scripts.

Environment

The AWS CLI is already installed in this environment.

Device name Version
PowerShell 5.1.19041.3031
AWS CLI 2.13.11
Python 3.11.4

Preparation

Before performing MFA authentication, register an AWS CLI profile with the aws configure command. The steps are described below.

Obtain access keys from the AWS Management Console

First, get the information you need to use the AWS CLI.

  • Sign in to the AWS Management Console.
  • Select “IAM” from the service menu.
  • Click Users in the left navigation pane.
  • Click on the name of the user for whom you want to create an access key.
  • Open the Security Credentials tab.
  • Click “Create new access key” in the “Access keys” section.
  • Copy or download the “Access Key ID” and “Secret Access Key” in the popup that appears.

Configure the mfa profile in the AWS CLI

Start PowerShell and run the following command to create the mfa profile.

PS C:\Users\MuNeNiCK> aws configure --profile mfa
AWS Access Key ID [****************KGOB]: access key ID
AWS Secret Access Key [****************MdNo]: secret access key
Default region name [ap-northeast-1]: default region
Default output format [json]:json

Confirm that MFA is required

Run the following command and confirm that it fails because MFA authentication has not been completed.

PS C:\Users\MuNeNiCK> aws s3 ls --profile mfa

An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

Use MFA with AWS CLI

When using MFA with the AWS CLI, you can obtain temporary credentials with the aws sts get-session-token command.

Use MFA and register temporary session credentials

  • Check and copy the MFA device ARN in the management console.

  • Execute the following command to perform MFA authentication.

    • serial-number: Specify the ARN of the copied MFA device
    • token-code: Specify the 6-digit code displayed by your authenticator app
aws sts get-session-token --serial-number arn:aws:iam::xxxxxxxx:mfa/your-mfa-device --token-code YOUR_MFA_CODE --profile mfa
  • When you run the command, the output will be as shown below.
PS C:\Users\MuNeNiCK> aws sts get-session-token --serial-number arn:aws:iam::xxxxxxxx:mfa/your-mfa-device --token-code YOUR_MFA_CODE --profile mfa
{
    "Credentials": {
        "AccessKeyId": "ASIAXXXXXXXXXXXXXX",
        "SecretAccessKey": "vFoFKlR+TaFvU3XXXXXXXXXXXXXX",
        "SessionToken": "IQoJb3JpZXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx//////////ARAAGgw2OTQ1NzQyMjc5MjUiDCwKeVHXobfuNVNOkyrMAbzuKEopURC9M9ghYeQH5bstFnfFCmDlrJw9xg4wR4P9ZlwvXt+ckq+A/c7WY7yCvZPIde7VeBDcGFKemyZe24K5JUXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "Expiration": "2023-08-21T20:52:56+00:00"
    }
}
  • Set the AccessKeyId, SecretAccessKey, and SessionToken values from the output as environment variables as shown below.
PS C:\Users\MuNeNiCK> $Env:AWS_ACCESS_KEY_ID="ASIAXXXXXXXXXXXXXX"
PS C:\Users\MuNeNiCK> $Env:AWS_SECRET_ACCESS_KEY="vFoFKlR+TaFvU3XXXXXXXXXXXXXX"
PS C:\Users\MuNeNiCK> $Env:AWS_SESSION_TOKEN="IQoJb3JpZXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx//////////ARAAGgw2OTQ1NzQyMjc5MjUiDCwKeVHXobfuNVNOkyrMAbzuKEopURC9M9ghYeQH5bstFnfFCmDlrJw9xg4wR4P9ZlwvXt+ckq+A/c7WY7yCvZPIde7VeBDcGFKemyZe24K5JUXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

Verification

Run the following command to confirm that session authentication was successful.

PS C:\Users\MuNeNiCK> aws s3 ls
2023-06-21 13:44:42 XXXXXXXXXXXXXXXXX

Automation using PowerShell scripts

The method above lets you use the AWS CLI with an MFA-enabled IAM user, but the session becomes invalid after 12 hours. Each time it expires, you must run aws sts get-session-token again and set the values as environment variables. To simplify that workflow, I created a PowerShell script that sets the environment variables automatically.

PowerShell script

The PowerShell script is shown below. Lines 9 and 10 are variables, so specify the ARN of your MFA device and your region.

# AWSGetSessionToken.ps1

param (
    [Parameter(Mandatory=$true)]
    [string]$TokenCode
)

# Specify ARN and region
$ARN = "arn:aws:iam::xxxxxxxx:mfa/test"
$Region = "ap-northeast-1"

# Execute AWS CLI command
$OUTPUT = aws sts get-session-token `
  --serial-number $ARN `
  --token-code $TokenCode `
  --profile mfa

# Get values from JSON
$AWS_ACCESS_KEY_ID = ($OUTPUT | ConvertFrom-Json).Credentials.AccessKeyId
$AWS_SECRET_ACCESS_KEY = ($OUTPUT | ConvertFrom-Json).Credentials.SecretAccessKey
$AWS_SESSION_TOKEN = ($OUTPUT | ConvertFrom-Json).Credentials.SessionToken

# Display the obtained values in the terminal
Write-Host "AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID"
Write-Host "AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY"
Write-Host "AWS_SESSION_TOKEN: $AWS_SESSION_TOKEN"

# Set environment variables
$Env:AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID"
$Env:AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY"
$Env:AWS_SESSION_TOKEN="$AWS_SESSION_TOKEN"
$Env:AWS_DEFAULT_REGION="$Region"

How to use

  • Save the above script as AWSGetSessionToken.ps1.

  • Rewrite lines 9 and 10 with the ARN and region of your MFA device.

  • Start PowerShell and run the script with the command below. For -TokenCode, specify the 6-digit MFA code from your authenticator app.

PS C:\Users\MuNeNiCK> .\AWSGetSessionToken.ps1 -TokenCode XXXXXX

If script execution is disabled

PowerShell scripts may not be allowed to run by default. Here are two ways to run the script.

PS C:\Users\MuNeNiCK> .\AWSGetSessionToken.ps1 -TokenCode XXXXXX
AWSGetSessionToken.ps1 : File C:\Users\MuNeNiCK\AWSGetSessionToken.ps1 cannot be loaded because running scripts is disabled on this system.
For more information, see about_Execution_Policies (https://go.microsoft.com/fwlink/?LinkID=135170).
At line:1 char:1
+ C:\Users\MuNeNiCK\AWSGetSessionToken ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : SecurityError: (:) [], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

Temporarily run the script

  • Run the script using the command below.
PS C:\Users\MuNeNiCK> powershell -ExecutionPolicy Bypass -File .\AWSGetSessionToken.ps1 -TokenCode XXXXXX

Allow scripts permanently

  • Start PowerShell with administrator privileges.

  • Execute the command below to allow script execution.

PS C:\Windows\system32> Set-ExecutionPolicy Unrestricted

Change execution policy
Execution policies help protect against untrusted scripts. When you change execution policies, about_Execution_Policies
Help topic (https://go.microsoft.com/fwlink/?LinkID=135170)
You may be exposed to the security risks described in . Do you want to change the execution policy?
[Y] Yes (Y) [A] Continue all (A) [N] No (N) [L] Ignore all (L) [S] Suspend (S) [?] Help (default value is "N"): Y
PS C:\Windows\system32>
  • Please run the script again.
PS C:\Users\MuNeNiCK> .\AWSGetSessionToken.ps1 -TokenCode XXXXXX
  • If you want to return to the original settings, execute the Set-ExecutionPolicy Restricted command.

Verification

Run the following command to confirm that session authentication was successful.

PS C:\Users\MuNeNiCK> aws s3 ls
2023-06-21 13:44:42 XXXXXXXXXXXXXXXXX

Conclusion

This article introduced how to use an MFA-enabled IAM user from the AWS CLI on Windows PowerShell and how to automate the workflow. I have seen examples that automate this with Linux shell scripts, but I had not seen many examples using Windows PowerShell, so I decided to publish this article. I hope it helps.

References