Back to script library
Entra / Microsoft 365 · Users & guests

Report last successful sign in

Demo script to show the use of the new (from 1-Dec-2023) lastSuccessfulSignInDateTime property currently available in beta.

Connect & set up

Run these once per session. All scopes are read-only unless the script makes changes.

Connect-MgGraph -NoWelcome -Scopes AuditLog.Read.All, Directory.Read.All

Run it

The main script. Copy it, or download the .ps1 and run it from your console.

Connect-MgGraph -NoWelcome -Scopes AuditLog.Read.All, Directory.Read.All
# Find licensed user accounts
$Headers = @{ConsistencyLevel="Eventual"}
$Uri = "https://graph.microsoft.com/beta/users?`$count=true&`$filter=(assignedLicenses/`$count ne 0 and userType eq 'Member')&$`top=999&`$select=id, displayName, usertype, signInActivity"
[array]$Data = Invoke-MgGraphRequest -Uri $Uri -Headers $Headers
[array]$Users = $Data.Value
If (!($Users)) {
Write-Host "Can't find any users... exiting!" ; break
}
# Paginate until we have all the user accounts
While ($Null -ne $Data.'@odata.nextLink') {
Write-Host ("Fetching more user accounts - currently at {0}" -f $Users.count)
$Uri = $Data.'@odata.nextLink'
[array]$Data = Invoke-MgGraphRequest -Uri $Uri -Headers $Headers
$Users = $Users + $Data.Value
}
Write-Host ("All available user accounts fetched ({0}) - now processing sign in report" -f $Users.count)
# And report what we've found
$Report = [System.Collections.Generic.List[Object]]::new()
ForEach ($User in $Users) {
$DaysSinceLastSignIn = $Null; $DaysSinceLastSuccessfulSignIn = $Null
$DaysSinceLastSignIn = "N/A"; $DaysSinceLastSuccessfulSignIn = "N/A"
$LastSuccessfulSignIn = $User.signInActivity.lastSuccessfulSignInDateTime
$LastSignIn = $User.signInActivity.lastSignInDateTime
If (!([string]::IsNullOrWhiteSpace($LastSuccessfulSignIn))) {
$DaysSinceLastSuccessfulSignIn = (New-TimeSpan $LastSuccessfulSignIn).Days
}
If (!([string]::IsNullOrWhiteSpace($LastSignIn))) {
$DaysSinceLastSignIn = (New-TimeSpan $LastSignIn).Days
}
$DataLine = [PSCustomObject][Ordered]@{
User = $User.displayName
UserId = $User.ID
'Last successful sign in' = $LastSuccessfulSignIn
'Last sign in' = $LastSignIn
'Days since successful sign in' = $DaysSinceLastSuccessfulSignIn
'Days since sign in' = $DaysSinceLastSignIn
}
$Report.Add($DataLine)
}
$Report | Sort-Object 'Days since sign in' | Out-GridView
Attribution