This post will show:

  • Why MSAL Auth is Necessary Now
  • Why I had to dig on my own: Few docs available on Intune that aren’t using ADAL
  • A workaround to get your ADAL-Authenticated MsGraph Intune app to use MSAL
  • Using that app to Authenticate to Microsoft Graph using the PowerShell SDK
  • Some ways to fetch Intune data

Why MSAL Authentication is Necessary Now

On June 30, 2020, Microsoft announced that they were no longer adding features to the the Azure AD Authentication Library (ADAL) or Azure AD Graph.

Microsoft Graph was created to take the place of Azure AD Graph, and the Microsoft Authentication Library (MSAL) slated to replace ADAL.

Until about a month ago, ADAL and Azure AD Graph was scheduled to be deprecated on June 30, 2022. That has now been moved to “at least” the end of 2022. But it’s coming eventually!

Intune Seems To Have Been Largely Forgotten in This Transition

The Github for Microsoft Intune PowerShell is, even as of June 2022, showing its samples using ADAL and connecting to Azure AD.

The Microsoft ADAL-to-MSAL migration guide doesn’t mention Intune or PowerShell.

There’s even an open ticket by a Microsoft employee asking for guidance for Intune customers on this.

So… I went digging to figure some of this out for myself.

If You Have an MSAL App to Connect to Azure AD Graph, You Can Use That With MSAL Instead

Managing Intune with Graph, PowerShell 7 & MSAL (

The magic that makes this easy: Using the MSAL.PS module, created by Jason Thompson.

MSAL.PS is installed and imported as a module, then used to get an Access Token. That token is then used to Authenticate to Microsoft Graph.

However, without changing the settings on the ADAL-based Intune app, the “interactive” authentication doesn’t work — the creator of that app needs to add in “https://localhost” as a reply URL in the app settings.

There’s a way to get around that requirement: Device Code authentication.

Import-Module MSAL.PS -Scope CurrentUser

$myAccessToken = Get-MsalToken -ClientId $clientID -TenantId $tenantID -DeviceCode
$tokenValue = $myAccessToken.AccessToken

The “ClientID” value here is the Application ID of the Azure AD Enterprise app that you’re using to access Graph.

The well-known standard “Microsoft Graph Powershell” app has a client ID: “14d82eec-204b-4c2f-b7e8-296a70dab67e”. In my testing, we had a custom-created app to access Graph, so my Client ID was different.

When using the Device Code method, you’ll be prompted to go to and enter a code in the textbox.

After that, you’ll select the user account to authenticate with. From there the browser screen will tell you that it’s done, you can close it.

Note that Get-MSALToken returns a token object, but what we need to pass in is the token value — a long string of characters. So there’s an extra line to save the “AccessToken” property to a separate variable.

That token value can then be passed straight into Connect-MgGraph to access Microsoft Graph.

# Pass the token value into Connect-MgGraph
Connect-MgGraph -AccessToken $tokenValue

# Show info about my session after authentication 

Some Intune Cmdlets with the Graph PowerShell SDK

MS Docs: Graph PowerShell SDK Documentation

Click the link above to load the Microsoft Graph PowerShell SDK docs, then click “Reference” in the lower-left to bring up a list of scopes.

Grab Device Info (From Azure AD)

  • Get-MgDevice
  • Get-MgDeviceByID

Grab Device Info (From Intune)

  • Get-MgDeviceManagementManagedDevice

Find Groups That a Device is a Member Of (Example)

  • Get-MgDevice -> To grab Id values for your devices, then:
  • Get-MgDeviceMemberOf -> use device ID to grab associated group IDs, then:
  • Get-MgGroup -> use group ID to get group info, including group’s display name

It can be tricky to find the right cmdlet, because each device has several different IDs, including:

  • Device ID from Azure AD
  • Object ID from Azure AD
  • MDM Device ID from Intune

One of the first scripts I whipped up is one that grabs each ID for a given device, because different Graph functions will require different ID inputs. Something to keep in mind!

It’s Not a Finished Product: The REST API is Better or Required in Some Cases

You may run into info you need that there isn’t a cmdlet for.

Or, as in the case when I searched the GroupPolicy-related cmdlets, they’re listed but come up as “not found” when you try to use them.

Some other cmdlets don’t accept filters for some reason, and they’re not documented.

Many of the cmdlets, I’d say most I’ve looked at, have scant documentation at best.

When it seems like more trouble than it’s worth, you CAN use the same access token from MSAL.PS to send REST API calls to Graph, and just get the data that way.

The cmdlets, are basically wrappers for the REST API calls anyway.

Example Rest API Call To Grab Group Tag Info From AutoPilot

$secureToken = $myAccessToken.AccessToken | ConvertTo-SecureString -AsPlainText -Force 

$params = @{
    Method = 'Get'
    Authentication = "OAuth"
    Token = $secureToken
    ContentType = "application/json"
    Uri = "`$top=25&`$filter=contains(serialNumber,%27MYSERIAL%27)"
$autoPilotInfo = (Invoke-RestMethod @params).Value
$deviceGroupTag = $autoPilotInfo.GroupTag


“$MyAccessToken” is from our earlier example:
Import the MSAL.PS module, and use Get-MSALToken. Save the value of the AccessToken property of that MSAL Token, to a variable (that is $MyAccessToken).

Then the top line makes more sense, to convert it to the required SecureString format for the REST API call.

This example grabs Intune device info for a device matching one serial number, then saves the value of the “GroupTag” property to a variable.

I could’ve combined the last few statements into a one-liner, but while I was teaching myself I liked to keep them separate.

Use Your Browser’s DevTools to Find a URI to Run Against

The Intune UI uses Graph. Yep!

In Chrome, Edge or Firefox, open their DevTools and head to the Network tab.

Then log into the MEM Console, and click on the link that will get you the data you want in Intune.

The Network tab of the browser DevTools will record the call being made to get that data.

It’s also a great way to get hints about where to look for a PowerShell SDK cmdlet to get that info.

Similar Posts