Skip to main content

Migrating from AzureAD Authentication for Graph API

· loading ·
Microsoft Intune Administration Authentication Graph API PowerShell
Author
Nick Benton
Principal Cloud Endpoint Consultant | Intune Blogger
Table of Contents

With the impending retirement of the Azure AD Graph API and ADAL authentication methods, and by impending, I mean the end of 2022, we should probably look at how we move away from the existing authentication methods I’ve been using in all of my scripts and into the new realms of MSAL (Microsoft Authentication Library).

Hold tight, this will be quick.

Background
#

The driver for this move away from the now deemed legacy ADAL (Azure Active Directory Authentication Library) authentication method, is Microsoft’s aim to move everyone and everything to PowerShell 7 core and allow for full cross-platform compatibility for PowerShell.

The issue with PowerShell 7 however, is that it doesn’t natively support the ‘old’ ADAL authentication libraries only with the use of -UseWindowsPowerShell compatibility flag, hence the need to move to an alternative authentication method.

MSAL PowerShell Module
#

Save reinventing the wheel, we can use the MSAL.PS module written by Jason Thompson to achieve authentication to Graph API without the reliance on PowerShell 5 and the AzureAD or ADAL PowerShell modules.

This module has been designed to utilise PowerShell core and subsequently be operating system agnostic, with a new device code authentication workflow for devices that have constraints around input.

Install-Module MSAL.PS -Scope CurrentUser

So we can now use the well used Microsoft Intune PowerShell App Id, and our tenant information to authenticate using the MSAL.PS module using ths new -DeviceCode option for authentication, generating a code that we can use on any device to authenticate on behalf of our initial request:

Get-MsalToken -ClientId 'd1ddf0e4-d672-4dae-b554-9d5bdfd93547' -TenantId 'ennbee.uk' -DeviceCode
  • Opening up the presented URL https://microsoft.com/devicelogin prompts us to enter in the code we received:

    Device Code
    Screenshot of the Device Code Entra authentication prompt.

  • From here we can sign in with the required User Account:

    User Account
    Screenshot of the sign-in prompt for Entra authentication.

  • Confirm the Application we are signing into:

    Sign in
    Screenshot of the enterprise app sign-in confirmation.

  • Finally receiving confirmation of the sign in and a prompt to close the window:

    PowerShell Device Code
    Screenshot of the authentication confirmation.

Once the Window is closed, we now have an authentication token in the shell to use to our heart’s content.

The New World
#

With a new way to acquire our Graph API token, we should look at updating the tried and tested Authentication Methods kindly provided by Microsoft in the powershell-intune-samples repo that we have been relying on to authenticate to Graph API.

An Updated Function
#

We need to update the Get-AuthToken function, and sensibly rename it, to do the following:

  • Detect the new MSAL.PS PowerShell module and prompt if it’s not installed
  • Import the MSAL.PS PowerShell module
  • Strip out the unneeded variables
  • Remove any and all reference to the ADAL DLL libraries
  • Get a new authentication token
Function Get-AuthTokenMSAL {

    <#
    .SYNOPSIS
    This function is used to authenticate with the Graph API REST interface
    .DESCRIPTION
    The function authenticate with the Graph API Interface with the tenant name
    .EXAMPLE
    Get-AuthTokenMSAL
    Authenticates you with the Graph API interface using MSAL.PS module
    .NOTES
    NAME: Get-AuthTokenMSAL
    #>

    [cmdletbinding()]

    param
    (
        [Parameter(Mandatory = $true)]
        $User
    )

    $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User
    if ($userUpn.Host -like '*onmicrosoft.com*') {
        $tenant = Read-Host -Prompt 'Please specify your Tenant name i.e. company.com'
        Write-Host
    }
    else {
        $tenant = $userUpn.Host
    }

    Write-Host 'Checking for MSAL.PS module...'
    $MSALModule = Get-Module -Name 'MSAL.PS' -ListAvailable
    if ($null -eq $MSALModule) {
        Write-Host
        Write-Host 'MSAL.PS Powershell module not installed...' -f Red
        Write-Host "Install by running 'Install-Module MSAL.PS -Scope CurrentUser' from an elevated PowerShell prompt" -f Yellow
        Write-Host "Script can't continue..." -f Red
        Write-Host
        exit
    }
    if ($MSALModule.count -gt 1) {
        $Latest_Version = ($MSALModule | Select-Object version | Sort-Object)[-1]
        $MSALModule = $MSALModule | Where-Object { $_.version -eq $Latest_Version.version }
        # Checking if there are multiple versions of the same module found
        if ($MSALModule.count -gt 1) {
            $MSALModule = $MSALModule | Select-Object -Unique
        }
    }

    $ClientId = 'd1ddf0e4-d672-4dae-b554-9d5bdfd93547'
    $RedirectUri = 'urn:ietf:wg:oauth:2.0:oob'
    $Authority = "https://login.microsoftonline.com/$Tenant"

    try {
        Import-Module $MSALModule.Name
        if ($PSVersionTable.PSVersion.Major -ne 7) {
            $authResult = Get-MsalToken -ClientId $ClientId -Interactive -RedirectUri $RedirectUri -Authority $Authority
        }
        else {
            $authResult = Get-MsalToken -ClientId $ClientId -Interactive -RedirectUri $RedirectUri -Authority $Authority -DeviceCode
        }
        # If the accesstoken is valid then create the authentication header
        if ($authResult.AccessToken) {
            # Creating header for Authorization token
            $authHeader = @{
                'Content-Type'  = 'application/json'
                'Authorization' = 'Bearer ' + $authResult.AccessToken
                'ExpiresOn'     = $authResult.ExpiresOn
            }
            return $authHeader
        }
        else {
            Write-Host
            Write-Host 'Authorization Access Token is null, please re-run authentication...' -ForegroundColor Red
            Write-Host
            break
        }
    }
    catch {
        Write-Host $_.Exception.Message -f Red
        Write-Host $_.Exception.ItemName -f Red
        Write-Host
        break
    }
}

Updating Authentication Method
#

With the new Get-AuthTokenMSAL function in our arsenal, we can quickly update the authentication method to call this function.

if ($global:authToken) {
    $DateTime = (Get-Date).ToUniversalTime()
    $TokenExpires = ($authToken.ExpiresOn.datetime - $DateTime).Minutes

    if ($TokenExpires -le 0) {
        Write-Host 'Authentication Token expired' $TokenExpires 'minutes ago' -ForegroundColor Yellow
        if ($null -eq $User -or $User -eq '') {
            $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication'
        }
        $global:authToken = Get-AuthTokenMSAL -User $User
        Write-Host 'Connected to Graph API' -ForegroundColor Green

    }
    Else {
        Write-Host 'Connected to Graph API' -ForegroundColor Green
    }
}
else {

    if ($null -eq $User -or $User -eq '') {
        $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication'
    }
    $global:authToken = Get-AuthTokenMSAL -User $User
    Write-Host 'Connected to Graph API' -ForegroundColor Green
}

Running both the function and authentication code gives us something like the below:

PowerShell
Screenshot of PowerShell Graph authentication notification.

And once you’ve run through the Device Code authentication method show earlier, it will give you the token you need in the $authToken variable to use across all the existing scripts in the powershell-intune-samples

Token
Screenshot of PowerShell Graph authentication token.

Summary
#

With the MSAL based authentication in place, and updating scripts to use the new function and associated code, we can lean back and relax a little when Microsoft depreciates and ends the use of ADAL based authentication methods.

If you’d like a more detailed understanding of MSAL and how to move away from ADAL, I’d recommend having a glance over the following:

I won’t be, I’ll be tirelessly updating all my scripts to use the new authentication method. This is what happens when Microsoft extends their deadlines and gives you more time to use old technologies.

Related

Updating Enrolled Device Ownership Status
· loading
Microsoft Intune Enrolment Administration Graph API PowerShell
Bulk Adding Device Notes to Enrolled Devices
· loading
Microsoft Intune Administration PowerShell Graph API Enrolment
Updating Defender Antivirus Compliance Settings
· loading
Microsoft Intune Windows 10 and later Microsoft Defender Security Compliance Updates Antivirus Graph API PowerShell