How Microsoft Graph PowerShell SDK Access Tokens Work
Automatic Management of Access Tokens
Some years ago, I wrote about the access (bearer) tokens used by Entra ID. At the time, I focused on the access tokens obtained by apps from https://login.microsoftonline.com rather than those used by the Microsoft Graph PowerShell SDK.
One of the big advantages of using the Microsoft Graph PowerShell SDK is that developers don’t need to manage token renewal. When a script or app runs the Connect-MgGraph cmdlet to authenticate, an access token is obtained to allow cmdlets to run. When that access token approaches its expiration time, the Graph SDK requests a new token automatically.
Unless you knew that automatic renewal happens, you probably won’t realize how the Graph PowerShell SDK acquires and manages access tokens because details of the access token aren’t surfaced by a cmdlet like Get-MgContext. Although Get-MgContext reveals details of the current authentication context such as whether delegated or app-only authentication was used and the scopes (permissions) available to the session, there’s no trace of the access token.
Finding the Access Token Used by a Microsoft Graph PowerShell SDK Interactive Session
Some might be surprised that it’s not easier to find what access token is being used during a Graph PowerShell SDK session. However, automatic token management means that knowing what an access token is and when the token will expire is not information that’s necessary for a session to function, so it’s reasonable to keep the data hidden behind the scenes.
To find the access token, it’s necessary to make a special form of request to any Graph API. The request can be made in an interactive session or an app-only session. This example uses a request against the drives endpoint to retrieve retention label information for a file, but any request will work:
$Uri = ("https://graph.microsoft.com/v1.0/drives/{0}/items/{1}/retentionLabel" -f $OneDriveInfo.Id, $File.Id) $Data = Invoke-MgGraphRequest -Uri $Uri -Method Get -OutputType HttpResponseMessage
The key point here is that the Invoke-MgGraphRequest cmdlet specifies that it should receive a HTTP response rather than data. The request specified in the URI is simply a way to ask the Graph for the HTTP response. The response contains several interesting components:
Version : 2.0 Content : System.Net.Http.DecompressionHandler+GZipDecompressedContent StatusCode : OK ReasonPhrase : OK Headers : {[Cache-Control, System.String[]], [Vary, System.String[]], [Strict-Transport-Security, System.String[]], [request-id, System.String[]]…} TrailingHeaders : {} RequestMessage : Method: GET, RequestUri: 'https://graph.microsoft.com/v1.0/drives/b!_xwZzApnQEeEWOYGdTfHR_FlEFWmBHl JixksigwWMZ_hpEW05Pd_R7OzPT4YdqXq/items/01R343MZ43HNLCSCCT3ZBLLUIJGB3GJ5B3/retentionLabel', Version: 2.0, Content: <null>, Headers: { User-Agent: Mozilla/5.0 User-Agent: (Windows NT 10.0; Microsoft Windows 10.0.26100; en-IE) User-Agent: PowerShell/7.5.2 User-Agent: Invoke-MgGraphRequest FeatureFlag: 00000003 Cache-Control: no-store, no-cache Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6IlZrTmh0QjdFajZpSUhRVkRwdmZYeVVldUEyeFFBbFhyR1M
The access token is at the bottom of the output and can be retrieved with:
$Data.RequestMessage.Headers.Authorization.Parameter
Decrypting an Access Token
Isolating the access token makes it easier to copy and input into the jwt.io token decoder. Figure 1 shows the raw JSON output; selecting the claims table tab presents the information in a more easily understood fashion (this reference page also helps).

The decoded token reveals details like the app in use (Microsoft Graph Command Line Tools), its identifier, the user, and the available permissions
"app_displayname": "Microsoft Graph Command Line Tools", "appid": "14d82eec-204b-4c2f-b7e8-296a70dab67e", "family_name": "Redmond", "given_name": "Tony", "idtyp": "user", "ipaddr": "109.78.233.203", "name": "Tony Redmond", "oid": "eff4cd58-1bb8-4899-94de-795f656b4a18", "scp": "AccessReview.Read.All Agreement.Read.All Analytics.Read APIConnectors.Read.All Application.Read.All Application.ReadWrite.All AppRoleAssignment.ReadWrite.All AuditLog.Read.All AuditLogsQuery.Read.All ...
The token also contain timestamps in UNIX epoch format for when the token was issued and when it will expire. The claims table output shows the date in local time. You can also convert these dates with PowerShell:
$UnixEpochValue = 1752763429 $Date = [DateTimeOffset]::FromUnixTimeSeconds($UnixEpochValue).ToLocalTime().DateTime Write-Host "UNIX epoch $UnixEpochValue is" $(Get-Date $Date -format 'dd-MMM-yyyy HH:mm') UNIX epoch 1752763429 is 17-Jul-2025 15:43
Down further in the token you’ll find the wids array, which holds the identifiers for the Entra ID roles held by the user. Remember, during an interactive Graph SDK session the available permissions are the intersection between delegated permissions and administrative roles. In other words, if access to data isn’t available through a permission, it might be through a role.
Reusing a Graph Access Token
You can take the access token used by the Graph interactive session and use it to retrieve information without using a Graph SDK cmdlet. In this code snippet, we prepare a hash table containing the access token formatted in the way that Graph requests expect the data to be presented and use the token with the Invoke-RestMethod cmdlet to find the details of the signed-in user.
$Headers = @{} $Headers.Add("Authorization", ("{0} {1}" -f $Data.RequestMessage.Headers.Authorization.Scheme, $Data.RequestMessage.Headers.Authorization.Parameter)) $Me = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/me" -Headers $Headers $Me.displayName Tony Redmond
Interesting But Not Very Useful Information
All of this is firmly in the interesting but not very useful category. If an app wants to make Graph API requests without using the Microsoft Graph PowerShell SDK, it will do the norm and obtain an access token programmatically before running any requests. The permissions available to the app are the set of delegated and application permissions held by the app’s service principal. If the app runs for over an hour, it will need to renew the access token.
Apart from testing code to write this article, I don’t think I have ever looked at the access token in a Microsoft Graph PowerShell SDK session. I might in the future, but right now I can’t think of a good reason why I should.
Need some assistance to write and manage PowerShell scripts for Microsoft 365? Get a copy of the Automating Microsoft 365 with PowerShell eBook, available standalone or as part of the Office 365 for IT Pros eBook bundle.