List users via Microsoft Graph API

User case

Is it possible to create a list of licensed users who have not or never logged in in the past 90 days?

First step – Create an app registration

Go to the Azure Portal > App registrations and create an app registration with the following permissions:

App_reg_msgraph

Copy the following values and paste them in the Powershell Script.

  • ApplicationID –> $ApplicationID
  • Directory (tenant) ID –> $TenantDomainName

Create a secret key, copy the value and paste it into the script:

  • $AccessSecret
$ApplicationID = "-----"
$TenantDomainName = ""
$AccessSecret ="-----"
$Body = @{
Grant_Type = "client_credentials"
Scope = "https://graph.microsoft.com/.default"
client_Id = $ApplicationID
Client_Secret = $AccessSecret
}
$ConnectGraph = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantDomainName/oauth2/v2.0/token" -Method POST -Body $Body
$AccessToken = $ConnectGraph.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,onPremisesSamAccountName,Mail,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
onPremisesSamAccountName = $User.onPremisesSamAccountName
UserPrincipalName = $User.userPrincipalName
Email = $User.Mail
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'
}

$DaysInactive = 90
$dateTime = (Get-Date).Adddays(-($DaysInactive))
$Result |
Where-Object { $_.LastSignInDateTime -eq $Null -OR $_.LastSignInDateTime -le $dateTime } |
Where-Object { $_.IsLicensed -eq $true } |
#Where-Object { $_.LastSignInDateTime -ne $null } |
#Where-Object { ($_.UserPrincipalName -notlike "*adm*") -or ($_.UserPrincipalName -notlike "*svc*")} #-or ($_.UserPrincipalName -notlike "*test*") -or ($_.UserPrincipalName -notlike "*sync*") } |
Export-CSV "C:\Temp\LastLoginDateReport.CSV" -NoTypeInformation -Encoding UTF8

Write-host "Create CSV file"
Start-Sleep -Seconds 5