Microsoft Graph: Get an Access Token from a PowerShell Session

Have you ever wanted to inspect an access token used in a PowerShell session you established using Connect-MgGraph? If so, this blog post is for you.

Authentication with the Microsoft Graph PowerShell SDK is pretty easy. All you have to do to establish a session is to run Connect-MgGraph. After that, you can use all Cmdlets for which you’ve installed the necessary modules. It’s no secret that not all Cmdlets are as well documented as the REST API itself and in rare cases, the PowerShell Cmdlets might even have some limitations compared to their REST counterparts. In such cases, you can usually just use the universal Invoke-MgGraphRequest Cmdlet without providing your own access token. This Cmdlet will use the same authentication like any other Mg* Cmdlet.

This is how Microsoft describes the Invoke-MgGraphRequest Cmdlet on Microsoft Learn:

Invoke-MgGraphRequest issues REST API requests to the Graph API. It works for any Graph API if you know the REST URI, method, and optional body parameter. This command is especially useful for accessing APIs for which there isn’t an equivalent cmdlet yet.

Note that there is also an alias called Invoke-GraphRequest for this Cmdlet. A perfect example of where you would need Invoke-MgGraphRequest is uploading a small file to SharePoint. I recently published a script example making use of this method here.

What is MgContext?

By running Get-MgContext you can get some information about the current session. Unfortunately, this doesn’t reveal any kind of tokens used for requests to the Graph API. Then again, this is most likely by design, because tokens should always be handled with care.

Output of Get-MgContext

What if you need a token anyway?

One option is to provide a client Id and a client secret and make a request to https://login.microsoftonline.com/{Your Tenant Name}/oauth2/v2.0/token. If I want to do that, I always come back to this blog post on adamtheautomator.com. But when I do that, I also want to call the REST API directly for all requests that the script I’m working on is doing. In my case, I want to use the SDK and only need to call the API directly for one specific request.

I recently was working on something where neither the Get-Mg* nor the Invoke-MgGraphRequest were working. I wanted to fetch a profile picture of an Entra ID user but wanted to keep the image in memory and not save it to disk. Both the Cmdlets, Get-MgUserPhotoContent and Invoke-MgGraphRequest expected a value for an output file though. I know I could have just used a temporary file but if I had given up this easily, I wouldn’t have discovered how to get an access token from a Microsoft Graph PowerShell session.

When I was testing the Invoke-MgGraphRequest Cmdlet, I noticed that there were different accepted values for the parameter -OutputType. One of the accepted values is HttpResponseMessage and if you select this, Graph will return the access token in the HTTP response.

This is the Graph URI/endpoint that I was using:

1
$mgRequest = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/users/$($userId)/photo/`$value" -ContentType "image/jpeg" -OutputType HttpResponseMessage

Graph access token retrieved using Invoke-MgGraphRequest

To access the token directly, you can use: $mgRequest.RequestMessage.Headers.Authorization.Parameter.

The access token is now stored in a variable

If you want to build your own Authorization header to call the API directly without first requesting a dedicated token from https://login.microsoftonline.com you can use this code:

1
2
3
4
5
$authHeader = @{
    Authorization = "$($mgRequest.RequestMessage.Headers.Authorization.Scheme) $($mgRequest.RequestMessage.Headers.Authorization.Parameter)"
}

$profilePhoto = (Invoke-WebRequest -Uri "https://graph.microsoft.com/v1.0/users/$($userId)/photo/`$value" -Headers $authHeader).Content

This allowed me to retrieve the profile photo as a byte array without saving it to disk first.

Summary

This is a very niche use case but I’m glad that I discovered how to get an access token from an already authenticated Microsoft Graph PowerShell session. I’m sure that this will come in handy again some day and I hope that it will come in handy for you some day as well. I also published the entire example script including helpful comments in one of my GitHub repositories.

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Hosted on GitHub Pages
Built with Hugo
Theme Stack designed by Jimmy