AWSMFAProfile.psm1

function Set-AWSMFAProfile {

<#
.SYNOPSIS

Performs AWS STS authentication with MFA token for cross account.

.DESCRIPTION

The Set-AWSMFAProfile updates the local AWS crendential for cross account
by using the STS.

.PARAMETER ParentProfile
Specifies the central/master account that login to the AWS. Set the Default
profile with Access key/Secret key or set desired profile name and ensure that the desired profile
name is provided when using the ParentProfile parameter.

.PARAMETER DeviceARN
Specifies the MFA device ARN.
The ARN is located in IAM > My security credentials > Assigned MFA device.

.PARAMETER SessionName
Specifies the name when calling the STS authentication API.

.PARAMETER StoreAs
Specifies the target AWS account to assume as cross account.

.PARAMETER RoleARN
Specifies the assumed role ARN which has authorize to the target AWS account.

.PARAMETER MFAToken
Specifies the one-time 6 digits code generated by the MFA device/authenticator.

.PARAMETER Duration
Specifies the expiration time in seconds where the STS token can last.
Default is 4 hours but can be set longer duration depends on the IAM policy.

.INPUTS

None. You cannot pipe objects to Set-AWSMFAProfile.ps1.

.OUTPUTS

Set-AWSMFAProfile.ps1 output if the authentication is successed.

.EXAMPLE

PS> Set-AWSCredential -AccessKey <YOURACCESSKEY> -SecretKey <YOURSECRETKEY>

PS> Set-AWSMFAProfile -DeviceARN "arn:aws:iam::123456789123:mfa/johndoe@contoso.com" -SessionName "john" -StoreAs "NorthWindTraders" -RoleARN "arn:aws:iam::9876543219876:role/CrossAccountRole" -MFAToken 123456

PS> Get-EC2Instance -ProfileName "NorthWindTraders" -Region "ap-southeast-2"

1. The defualt credential is defined.
2. Cross account access to "NorthWindTraders (9876543219876)" with "CrossAccountRole" assumed role and stored under "NorthWindTraders" profile name.
3. Retrieve EC2 instances from "NorthWindTraders" account.

.EXAMPLE

PS> Set-AWSCredential -AccessKey <YOURACCESSKEY> -SecretKey <YOURSECRETKEY> -StoreAs "Contoso"

PS> Set-AWSMFAProfile -DeviceARN "arn:aws:iam::123456789123:mfa/johndoe@contoso.com" -SessionName "john" -StoreAs "NorthWindTraders" -RoleARN "arn:aws:iam::9876543219876:role/CrossAccountRole" -ParentProfile "Contoso" -Duration 25200 -MFAToken 123456

PS> Get-EC2Instance -ProfileName "NorthWindTraders" -Region "ap-southeast-2"

1. Set "Contoso" profile name as parent/master account which used to login to AWS.
2. Cross account access to "NorthWindTraders (9876543219876)" with "CrossAccountRole" assumed role and stored under "NorthWindTraders" profile name by using "Contoso" as parent/master profile where the session is expired after 7 hours.
3. Retrieve EC2 instances from "NorthWindTraders" account.
#>


    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Medium')]
    param (
        [Parameter(Mandatory = $True)]
        [string]$DeviceARN,
        [Parameter(Mandatory = $True)]
        [string]$SessionName,
        [Parameter(Mandatory = $True)]
        [string]$StoreAs,
        [Parameter(Mandatory = $True)]
        [string]$RoleARN,
        [Parameter(Mandatory = $True)]
        [string]$MFAToken,
        $ParentProfile = "default",
        [int]$Duration = 14400
    )
    begin {
        try {
            # Importing necessory modules
            Import-Module -Name "AWSPowerShell" -ErrorAction SilentlyContinue
            Import-Module -Name "AWS.Tools.Common" -ErrorAction SilentlyContinue
            Import-Module -Name "AWS.Tools.SecurityToken" -ErrorAction SilentlyContinue

            # Double check if the required commands are present
            Get-Command -Name Use-STSRole | Out-Null
            Get-Command -Name Set-AWSCredential | Out-Null
        }
        catch {
            Write-Error $PSItem.ToString()
            break
        }
    }
    process {

        # Beginning of the process
        if ($PSCmdlet.ShouldProcess("Updates the '$StoreAs' profile with new temporary STS token credential")) {
            try {
                # Cleanup STSCred variable and ensure it is not set
                Clear-Variable -Name STSCred -ErrorAction SilentlyContinue

                # Getting the temporary STS token
                $STSCred = Use-STSRole `
                    -SerialNumber $DeviceARN `
                    -RoleArn $RoleARN `
                    -RoleSessionName $SessionName `
                    -DurationInSeconds $Duration `
                    -ProfileName $ParentProfile `
                    -TokenCode $MFAToken
                Write-Output "Temporary session token for '$StoreAs' is generated successfully."

                # If the temprary token is able generated, proceed
                if ($STSCred) {
                    # Update/Overwirte the profile session in local AWS credential file
                    Set-AWSCredential `
                        -StoreAs $StoreAs `
                        -AccessKey $STSCred.Credentials.AccessKeyId `
                        -SecretKey $STSCred.Credentials.SecretAccessKey `
                        -SessionToken $STSCred.Credentials.SessionToken
                    Write-Output "Profile '$StoreAs' is successfully updated in local AWS credential."
                }
                else {
                    Write-Output "Temporary session token for '$StoreAs'is failed to generated."
                }
            }
            catch {
                Write-Error $PSItem.ToString()
                break
            }
        }
    }
    end {
    }
}

Export-ModuleMember -Function Set-AWSMFAProfile