Script to request and get access token from Azure Microsoft graph API

A.Elrayes 186 Reputation points
2023-01-16T14:54:32.3133333+00:00

I'm using the following script to get inactive sign in from azure:

$AppClientId="" 
$Secret = ""

$uri = "https://login.microsoft.com/a1a5384f-f0fc-4df9-9f37-caf775af43c1/oauth2/token"

$body = @{

   grant_type = "client_credentials"
   client_id = $AppClientId
   client_secret = $Secret
   resource = "https://graph.microsoft.com"

   }

   $resp = Invoke-RestMethod -Method Post -Uri $uri -Body $body -ContentType "application/x-www-form-urlencoded"

   Write-Host  $resp.access_token




#Provide your access token. 
#$AccessToken="" 
 
#Form request headers with the acquired $AccessToken
$headers = @{'Content-Type'="application\json";'Authorization'="Bearer $AccessToken"}
 
#This request get users list with signInActivity.
$ApiUrl = "https://graph.microsoft.com/beta/users?`$select=displayName,userPrincipalName,signInActivity,userType,assignedLicenses&`$top=999"
 
$Result = @()
While ($ApiUrl -ne $Null) #Perform pagination if next page link (odata.nextlink) returned.
{
$Response =  Invoke-RestMethod -Method GET -Uri $ApiUrl -ContentType "application\json" -Headers $headers
if($Response.value)
{
$Users = $Response.value
ForEach($User in $Users)
{
 
$Result += New-Object PSObject -property $([ordered]@{ 
DisplayName = $User.displayName
UserPrincipalName = $User.userPrincipalName
LastSignInDateTime = if($User.signInActivity.lastSignInDateTime) { [DateTime]$User.signInActivity.lastSignInDateTime } Else {$null}
LastNonInteractiveSignInDateTime = if($User.signInActivity.lastNonInteractiveSignInDateTime) { [DateTime]$User.signInActivity.lastNonInteractiveSignInDateTime } Else { $null }
IsLicensed  = if ($User.assignedLicenses.Count -ne 0) { $true } else { $false }
IsGuestUser  = if ($User.userType -eq 'Guest') { $true } else { $false }
})
}
 
}
$ApiUrl=$Response.'@odata.nextlink'
}
$Result | Export-CSV "C:\LastLoginDateReport.CSV" -NoTypeInformation -Encoding UTF8

It gives the following output:

Invoke-RestMethod : The remote server returned an error: (401) Unauthorized. At D:\Work Data\Get Inactive Users from Azure AD.ps1:34 char:14

  • ... Response = Invoke-RestMethod -Method GET -Uri $ApiUrl -ContentType " ...
     + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    
    • FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

I tried to get the access token by Postman and import it manual to the variable and the connection is success but the problem is the token has a limited time.
So, I need to do that through the script.

Thanks

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
12,343 questions
{count} votes

Accepted answer
  1. Vasil Michev 108.6K Reputation points MVP
    2023-01-16T15:40:44.31+00:00

    You have almost everything already, just need to parse the $body response variable. Here's an example from one of my scripts:

    #region Authentication
    #We use the client credentials flow as an example. For production use, REPLACE the code below with your preferred auth method. NEVER STORE CREDENTIALS IN PLAIN TEXT!!!
    
    #Variables to configure
    $tenantID = "tenant.onmicrosoft.com" #your tenantID or tenant root domain
    $appID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" #the GUID of your app.
    $client_secret = "verylongsecurestring" #client secret for the app
    
    #Prepare token request
    $url = 'https://login.microsoftonline.com/' + $tenantId + '/oauth2/v2.0/token'
    
    $body = @{
        grant_type = "client_credentials"
        client_id = $appID
        client_secret = $client_secret
        scope = "https://graph.microsoft.com/.default"
    }
    
    #Obtain the token
    Write-Verbose "Authenticating..."
    try { $tokenRequest = Invoke-WebRequest -Method Post -Uri $url -ContentType "application/x-www-form-urlencoded" -Body $body -UseBasicParsing -ErrorAction Stop }
    catch { Write-Host "Unable to obtain access token, aborting..."; return }
    
    $token = ($tokenRequest.Content | ConvertFrom-Json).access_token
    
    $authHeader = @{
       'Content-Type'='application\json'
       'Authorization'="Bearer $token"
    }
    #endregion Authentication
    
    

    Also, you can take a look at the MSAL.PS module.

    2 people found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.