PowerShell, CLI-Azure Authentication Methods

Aammir Mirza
Azure Cost Savings
Published in
4 min readSep 3, 2023

Microsoft Azure provides various connection methods to enable interaction and access to resources within the Azure cloud environment. These connection methods are essential for connecting applications, services, and users to Azure resources securely and efficiently.

Warning: Please remember that some Method will not work because of MFA interactions.

What we will be learning here ?

  1. Connect-AzAccount
  2. Connect-AzureAD
  3. Connect-MgGraph
  4. RestfullApi (Graph + Azure)

Lets have a example of each connection method and sample block of code for the same.

Connect-AzAccount

Connection via UserName + Password-

$User = "aammir.mirza@contoso.com"
$Password = ConvertTo-SecureString -String "One2ThrEE4F!ve" -AsPlainText -Force
$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Password
Connect-AzAccount -Credentials $Credentials

Connection via Service Principal + Client Secret

$ApplicationId = '00000000-0000-0000-0000-00000000'
$ClientSecret = 'SuperStrongSecret'
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ApplicationId, $ClientSecret
Connect-AzAccount -ServicePrincipal -TenantId $TenantId -Credential $Credential

Connection via Service Principal + Certificate Thumbprint

$Thumbprint = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
$TenantId = 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyy'
$ApplicationId = '00000000-0000-0000-0000-00000000'
Connect-AzAccount -CertificateThumbprint $Thumbprint -ApplicationId $ApplicationId -Tenant $TenantId -ServicePrincipal

Connect-AzureAD

Connection via UserName + Password

$User = "aammir.mirza@contoso.com"
$Password= ConvertTo-SecureString -String "One2ThrEE4F!ve" -AsPlainText -Force
$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Password
Connect-AzureAD -Credentials $Credentials

Connection via Service Principal + Client Secret

$ApplicationId = '00000000-0000-0000-0000-00000000'
$ClientSecret = 'SuperStrongSecret'
$TenantId = 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyy'

$azurePassword = ConvertTo-SecureString $ClientSecret -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($ApplicationID , $ClientSecret)
Connect-AzAccount -Credential $psCred -TenantId $TenantId -ServicePrincipal
$context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
$aadToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, "https://graph.windows.net").AccessToken
Connect-AzureAD -AadAccessToken $aadToken -AccountId $context.Account.Id -TenantId $context.tenant.id

Connection via Service Principal + Certificate Thumbprint

$Thumbprint = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
$TenantId = 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyy'
$ApplicationId = '00000000-0000-0000-0000-00000000'
Connect-AzureAD -CertificateThumbprint $Thumbprint -ApplicationId $ApplicationId -Tenantid $TenantId

Connect-MgGraph

Connection via UserName + Password

Connect-MGGraph didnt provide a programmable way to insert Credentials, its needable to fetch an AccessToken via Connect-AzAccount

$User = "aammir.mirza@contoso.com"
$PWord = ConvertTo-SecureString -String "One2ThrEE4F!ve" -AsPlainText -Force
$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord
Connect-AzAccount -Credentials $Credentials

$contextForMSGraphToken = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext

$newBearerAccessTokenRequest = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($contextForMSGraphToken.Account, $contextForMSGraphToken.Environment, $contextForMSGraphToken.Tenant.id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, https://graph.microsoft.com)

$AccessToken = $newBearerAccessTokenRequest.AccessToken

Connect-MGGraph -AccessToken $AccessToken

Connection via Service Principal + Client Secret

$TenantId = 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyy'
$ApplicationId = '00000000-0000-0000-0000-00000000'
$ClientSecret = 'SuperStrongSecret'

$body = @{
Grant_Type = "client_credentials"
Scope = "https://graph.microsoft.com/.default"
Client_Id = $ApplicationId
Client_Secret = $ClientSecret
}

$connection = Invoke-RestMethod `
-Uri https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token `
-Method POST `
-Body $body

$token = $connection.access_token

Connect-MgGraph -AccessToken $token

Connection via Service Principal + Certificate Thumbprint

$Thumbprint = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
$TenantId = 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyy'
$ApplicationId = '00000000-0000-0000-0000-00000000'

Connect-MgGraph -ClientID $ApplicationId -TenantId $TenantId -CertificateThumbprint $Thumbprint

RestfullApi (Graph + Azure)

As an Example connecting to Graph an GET my profile information.

Connection via UserName + Password

$Url = 'https://graph.microsoft.com/beta/me'

$User = "aammir.mirza@contoso.com"
$PWord = ConvertTo-SecureString -String "One2ThrEE4F!ve" -AsPlainText -Force
$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord
Connect-AzAccount -Credentials $Credentials

$contextForMSGraphToken = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext

$newBearerAccessTokenRequest = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($contextForMSGraphToken.Account, $contextForMSGraphToken.Environment, $contextForMSGraphToken.Tenant.id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, https://graph.microsoft.com)

$AccessToken = $newBearerAccessTokenRequest.AccessToken
$meProfile = Invoke-RestMethod -Headers @{Authorization = "Bearer $AccessToken"} -Uri $apiUrl -Method Get

Connection via Service Principal + Client Secret

$Url = 'https://graph.microsoft.com/beta/me'

$body = @{
Grant_Type = "client_credentials"
Scope = "https://graph.microsoft.com/.default"
Client_Id = $ApplicationId
Client_Secret = $ClientSecret
}

$connection = Invoke-RestMethod `
-Uri https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token `
-Method POST `
-Body $body
$AccessToken = $connection.access_token

$meProfile = Invoke-RestMethod -Headers @{Authorization = "Bearer $AccessToken"} -Uri $apiUrl -Method Get

Connection via Service Principal + Certificate Thumbprint

$Url = 'https://graph.microsoft.com/beta/me'

$Thumbprint = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
$TenantId = 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyy'
$ApplicationId = '00000000-0000-0000-0000-00000000'
Connect-AzAccount -CertificateThumbprint $Thumbprint -ApplicationId $ApplicationId -Tenant $TenantId -ServicePrincipal

$contextForMSGraphToken = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext

$newBearerAccessTokenRequest = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($contextForMSGraphToken.Account, $contextForMSGraphToken.Environment, $contextForMSGraphToken.Tenant.id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, https://graph.microsoft.com)

$AccessToken = $newBearerAccessTokenRequest.AccessToken

$meProfile = Invoke-RestMethod -Headers @{Authorization = "Bearer $AccessToken"} -Uri $apiUrl -Method Get

Bonus for reading article

Accessing Microsoft Graph API with a managed identity

Using managed identities with the connect-azaccount cmdlet is very easy. simply add this line to your runbook:

Connect-AzAccount -Identity

I prefer the PowerShell SDK when working with the Microsoft Graph API in a Runbook since it will make it much leaner and less prone to errors than invoking web requests. Still, as mentioned earlier, support for managed identity is missing at the time of writing this.

The PowerShell module does, however, support the use of an access token. So we can simply call on the system assigned managed identity, to generate an access token that is valid for the Microsoft Graph API endpoint (Beta or v1.0). It is not as simple as the Connect-AzAccount cmdlet, but pretty close. Take a look at this code:

#Obtain AccessToken for Microsoft Graph via the managed identity
$resourceURL = "https://graph.microsoft.com/"
$response = [System.Text.Encoding]::Default.GetString((Invoke-WebRequest -UseBasicParsing -Uri "$($env:IDENTITY_ENDPOINT)?resource=$resourceURL" -Method 'GET' -Headers @{'X-IDENTITY-HEADER' = "$env:IDENTITY_HEADER"; 'Metadata' = 'True'}).RawContentStream.ToArray()) | ConvertFrom-Json
$accessToken = $response.access_token

#Define the desired graph endpoint
$graphApiVersion = 'beta'
Select-MgProfile -Name $graphApiVersion

#Connect to the Microsoft Graph using the aquired AccessToken
Connect-Graph -AccessToken $accessToken

Thanks to Tim S — Reference Link

--

--

Azure Cost Savings
Azure Cost Savings

Published in Azure Cost Savings

Publication deals with the Azure Cost Optimization and other security best practices for MS Azure

Aammir Mirza
Aammir Mirza

Written by Aammir Mirza

Cloud Architect with 12 years of experience in managing cloud infrastructure and automation, integrating Azure cloud-based infra components

No responses yet