Microsoft Graph using MSAL with PowerShell

Microsoft Authentication Libraries (MSAL) became Generally Available in May 2019 after a very long preview cycle whilst the libraries evolved to reach parity with its predecessor the Azure Active Directory Authentication Libraries (ADAL). I’ve previously used and written posts on leveraging ADAL libraries with PowerShell for Azure AD/Microsoft Graph integration using PowerShell. With some upcoming projects it’s time for me to start integrating with Microsoft Graph using MSAL with PowerShell. This post details how I transitioned from ADAL to MSAL and reduced my scripts by 60-300 lines depending on the integration.

Sneak peak: Providing just an Azure AD Application Client ID, Client Secret and an Azure AD Tenant ID and leveraging the MSAL.PS PowerShell Module provides Authentication orchestration and returns an Access Token. My JWTDetails module then shows the Access Token properties.

AuthN to Microsoft Graph using MSAL with PowerShell

MSAL with PowerShell

Having previously written scripts to perform the oAuth AuthN dance with ADAL I figured as part of the transition it would be best to write a a few helper functions and compose a PowerShell Module to simplify the process with MSAL. Before I did however I made a few searches to make sure I wasn’t reinventing the wheel. Bingo. An MSAL PowerShell Module produced by Jason Thompson a Microsoft employee. Whilst not officially supported by Microsoft, Jason has just updated the module for MSAL 4.5.1.1.

As shown in the intro above the minimum you need to provide to the Get-MsalToken cmdlet is Client ID, Client Secret and Tenant ID and leveraging the defaults from the cmdlet you will receive and Access Token. Looking into the Get-MsalToken cmdlet the default scopes are retrieved from your registered application.
If you haven’t registered an Application before follow this guide.

Get-MsalToken -clientID $clientID -clientSecret $clientSecret -tenantID $tenantID

Access Token via MSAL and PowerShell

Install the MSAL.PS Module from an administrative PowerShell session using:

install-module -name MSAL.PS

Using my JWTDetails module we can decode the Access Token and look at the details along with getting useful information such as how long until the Access Token expires.

$accessToken = Get-MsalToken -clientID $clientID -clientSecret $clientSecret -tenantID $tenantID | Select-Object -Property AccessToken
$accessToken.AccessToken | Get-JWTDetails

Access Token via decode in PowerShell with JWTDetails

Install my JWTDetails module from an administrative PowerShell session using;

install-module -name JWTDetails

Get-MsalToken Usage Notes

Having used this module now for a short time and understanding its function I can see that it is using the Token Cache nicely. If you call Get-MsalToken and the existing token in the token cache is still valid then the Access Token from the token cache is returned. If it has expired a new Access Token will be obtained.

If you want to force the cmdlet to get a new Access Token, you can by using the Clear-MsalCache cmdlet from the MSAL.PS module or using the -ForceRefresh switch as shown below.

Clear-MsalCache

Clear-MsalCache 
$myToken = Get-MsalToken -clientID $clientID -clientSecret $clientSecret -tenantID $tenantID 

Force-Refresh

$myToken = Get-MsalToken -clientID $clientID -clientSecret $clientSecret -tenantID $tenantID -ForceRefresh

Other Functions

The MSAL.PS module also supports additional functions such as obtaining an Access Token using a Client Certificate, leveraging a different Authority, Login Hints and Interactive modes. Some of these I’ll expand on further in future posts as I start leveraging this module further.

Using the Access Token

Let’s call the Microsoft Graph and retrieve Users.

$users = Invoke-RestMethod -Headers @{Authorization = "Bearer $($myToken.AccessToken)" } `
    -Uri  'https://graph.microsoft.com/v1.0/users' `
    -Method Get

Microsoft Graph Users REST call using MSAL Access Token

Summary

The oAuth Authentication dance in PowerShell just became super simple. Oh and it is also PowerShell Core compatible (as is my JWTDetails module).

Hint: Azure Functions

MSAL with PowerShell Core