Automating login to AzureRM for multiple contexts

If you work with AzureRM module and have to frequently switch context, it’s worth automating the process since standard authentication through pop up dialog can become tedious at some point. Steps below will use your credentials directly without a need to go through pop up dialog prompt. Credentials are saved securely in credentials manager (https://docs.microsoft.com/en-us/windows/desktop/secauthn/credentials-management)

Below is modified script by Willem Kasdorp (https://blogs.technet.microsoft.com/389thoughts/2018/02/11/logging-on-to-azure-for-your-everyday-job/) to accommodate for non interactive login.

  1. Create following script somewhere on file system. This script will be dot sourced from your profile script to automate login to multiple Azure accounts. In my case I called it login.ps1
#Requires -Module CredentialManager
function profile_logon_azure { 
    param (
        [Parameter(mandatory = $true)]
        [string]$parentfolder,
        [Parameter(mandatory = $true)]
        [string] $accountname
    )

    $validlogon = $false
    $contextfile = Join-Path $parentfolder "$accountname.json"
    if (-not (Test-Path $contextfile)) {
        Write-Host "No existing Azure Context file in '$parentfolder', please log on now for account '$accountname'." -ForegroundColor Yellow
    }
    else {
        $context = Import-AzureRmContext $contextfile -ErrorAction stop
        #
        # check for token expiration by executing an Azure RM command that should always succeed.
        #
        Write-Host "Imported AzureRM context for account '$accountname', now checking for validity of the token." -ForegroundColor Yellow
        $validlogon = (Get-AzureRmSubscription -SubscriptionName $context.Context.Subscription.Name -ErrorAction SilentlyContinue) -ne $null
        if ($validlogon) {
            Write-Host "Imported AzureRM context '$contextfile', current subscription is: $($context.Context.Subscription.Name)" -ForegroundColor Yellow
        }
        else {
            Write-Host "Logon for account '$accountname' has expired, please log on again." -ForegroundColor Yellow
        }
    }
    if (-not $validlogon) {

        $credential = (Get-StoredCredential -Target $accountName -AsCredentialObject)
        if ($null -eq $credential) {
            Write-Host "No stored credentials exists for $accountname, create one" -ForegroundColor Yellow
            exit     
        }
    
        $account = $null
        $password = ConvertTo-SecureString -String $credential.Password -AsPlainText -Force
        $account = Add-AzureRmAccount -Credential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $credential.UserName, $password)
        if ($account) {
            Save-AzureRmContext -Path $contextfile -Force
            Write-Host "logged on successfully, context saved to $contextfile." -ForegroundColor Yellow
        }
        else {
            Write-Host "log on to AzureRM for account '$accountname' failed, please retry." -ForegroundColor Yellow
        }
    }
}

2. Edit your profile script to dotsource script above and add Function names to login to your Azure environments. Pass name of credential object and where to save context file to be used between sessions.

code $profile.CurrentUserAllHost

My profile script is below to login to Customer1 and Customer2

Write-Host "Loading profile script" -ForegroundColor Yellow
. C:\gd\Documents\profile\login.ps1
function Login-Customer1 {
    profile_logon_azure -parentfolder C:\gd\Documents\profile\ -accountname "customer1"
}
function Login-Customer2 {
    profile_logon_azure -parentfolder C:\gd\Documents\profile\ -accountname "customer2"
}

3. Add generic credential to your credential manager for both `customer 1` and `customer2`

4. Restart your powershell session and you shall be able to login to any of your contexts by just executing Login-Customer1 or Login-Customer2