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
#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

    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.

  •