Let’s start with an uncomfortable question for IT administrators: How many user accounts in your Microsoft Entra ID tenant are actually being used? Not how many exist, but how many are truly active. In most organizations, inactive user accounts build up over time with little oversight. They’re rarely reviewed, often forgotten, and quietly increase risk in the background.
Fortunately, Microsoft Entra ID captures detailed sign-in activity for every user. The challenge lies not in data availability, but in knowing where to access it and how to interpret it accurately. This guide walks you through identifying inactive user accounts using last sign-in data, helping you regain visibility and control over your tenant.
Sign-in Types in Microsoft Entra ID
Before diving into the methods, it’s crucial to understand the difference between the two types of sign-in activities that Microsoft Entra ID tracks:
Interactive sign-in: An Interactive sign-in occurs when a user deliberately authenticates to a service. This means the user is actively involved in the process, entering credentials, approving MFA, or completing an authentication prompt.
Non-interactive sign-in: A non-interactive sign-in happens without the user actively participating. These sign-ins are triggered automatically by applications or services that already have valid authentication tokens.
Why This Matters: A user might have a recent non-interactive sign-in timestamp due to background app activity, but their last interactive sign-in could be months old, indicating they haven’t actually logged in personally for an extended period. Understanding both timestamps gives you a complete picture of actual user activity.
How to Identify Inactive User Accounts in Microsoft Entra ID
Here are the few ways to list inactive user accounts based on ‘Last Successful Sign-in Date and Time’ property.
Find Last Successful Sign-In for an Inactive User in Entra Admin Center
To check when a user last accessed their account:
- Sign in to the Microsoft Entra admin center.
- Navigate to Identity > Users > All users. Select the specific user you want to investigate
- In the user’s profile, locate the My Feed section. Under Sign-ins, you’ll see two key timestamps: Last interactive sign-in time and Last non-interactive sign-in time.
This approach is well-suited when you need to investigate one specific user account.
Viewing Sign-In Activity for Multiple Users in Entra Admin Center
When you need to review sign-in activity across multiple users simultaneously, the admin center provides a filtered list view.
-
- In the Microsoft Entra admin center, navigate to Identity > Users > All users.
-
- Click the Add filter button at the top of the user list.
-
- In the Add filter dialog:
-
- Filter: Select either “Last interactive sign-in time” or “Last non-interactive sign-in time”.
-
- Operator: Choose your comparison operator:
-
- >= (greater than or equal to) – for users who signed in after a certain date
-
- <= (less than or equal to) – for users who last signed in before a certain date.
-
- Value: Click the calendar icon and select your target date.
- Click Apply to filter the user list.
Once you’ve applied the filter, the results will display in pages showing 100 users at a time. You can navigate through all pages using the pagination controls at the bottom, and you can customize the sign-in fields you want to see.
⚠️ Limitation to keep in mind:
The biggest drawback is flexibility. Sign-in filters can’t be combined with other useful attributes like department, account status, or user type. You’re limited to one filter at a time, which makes deeper analysis or targeted reviews more manual than ideal.
See below how to work around this using EasyEntra.
Export Inactive Users in Microsoft 365 Using PowerShell
For administrators who need a complete, exportable view of inactive users, PowerShell offers far more flexibility than the Microsoft Entra admin center. Using Microsoft Graph PowerShell, you can retrieve both interactive and non-interactive sign-in activity for every user and export the results.
The script below connects to Microsoft Graph and generates a full user activity report along with a separate high-risk report for users inactive for over 90 days.
# ============================================================================
# Script: Get-InactiveUsers-ComprehensiveReport.ps1
# Description: Categorizes users by inactivity period and generates detailed reports
# Requirements: Microsoft.Graph PowerShell module, Entra ID Premium P1/P2 license
# ============================================================================
# Connect to Microsoft Graph with required permissions
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Cyan
Connect-MgGraph -Scopes "User.Read.All", "AuditLog.Read.All"
Write-Host "Retrieving all users from Microsoft Entra ID..." -ForegroundColor Cyan
# Get all users with required properties
$users = Get-MgUser -All -Property DisplayName,UserPrincipalName,AccountEnabled,CreatedDateTime,SignInActivity
Write-Host "Processing $($users.Count) users..." -ForegroundColor Cyan
# Process and categorize users
$report = $users | ForEach-Object {
$lastInteractive = $_.SignInActivity.LastSignInDateTime
$lastNonInteractive = $_.SignInActivity.LastNonInteractiveSignInDateTime
# Determine most recent sign-in
$mostRecentSignIn = @($lastInteractive, $lastNonInteractive) |
Where-Object {$_ -ne $null} |
Measure-Object -Maximum |
Select-Object -ExpandProperty Maximum
# Calculate days inactive (from last sign-in to current date)
if ($mostRecentSignIn) {
$daysInactive = [math]::Round((New-TimeSpan -Start $mostRecentSignIn -End (Get-Date)).TotalDays)
} else {
$daysInactive = $null
}
# Categorize based on inactivity period
$category = switch ($daysInactive) {
{$_ -eq $null} { "Never Signed In" }
{$_ -le 30} { "Active (0-30 days)" }
{$_ -le 60} { "Moderately Inactive (31-60 days)" }
{$_ -le 90} { "Inactive (61-90 days)" }
default { "Highly Inactive (90+ days)" }
}
# Create custom object for reporting
[PSCustomObject]@{
DisplayName = $_.DisplayName
UserPrincipalName = $_.UserPrincipalName
AccountEnabled = $_.AccountEnabled
CreatedDateTime = $_.CreatedDateTime
LastInteractiveSignIn = $lastInteractive
LastNonInteractiveSignIn = $lastNonInteractive
MostRecentSignIn = $mostRecentSignIn
DaysInactive = $daysInactive
InactivityCategory = $category
}
}
Write-Host "`nExporting reports..." -ForegroundColor Cyan
# Export full report
$fullReportPath = "UserActivity_FullReport_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$report | Export-Csv -Path $fullReportPath -NoTypeInformation
Write-Host "Full report exported to: $fullReportPath" -ForegroundColor Green
# Generate summary statistics
$summary = $report | Group-Object InactivityCategory |
Select-Object Name, Count |
Sort-Object Count -Descending
Write-Host "`n========================================" -ForegroundColor Yellow
Write-Host "User Activity Summary" -ForegroundColor Yellow
Write-Host "========================================" -ForegroundColor Yellow
$summary | Format-Table -AutoSize
# Export highly inactive users separately
$highlyInactive = $report | Where-Object {
$_.InactivityCategory -eq "Highly Inactive (90+ days)" -or
$_.InactivityCategory -eq "Never Signed In"
}
$highRiskReportPath = "HighRisk_InactiveUsers_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$highlyInactive | Export-Csv -Path $highRiskReportPath -NoTypeInformation
Write-Host "`nHigh-risk inactive users exported to: $highRiskReportPath" -ForegroundColor Green
Write-Host "`n========================================" -ForegroundColor Yellow
Write-Host "Summary" -ForegroundColor Yellow
Write-Host "========================================" -ForegroundColor Yellow
Write-Host "Total Users Processed: $($users.Count)" -ForegroundColor White
Write-Host "High-Risk Inactive Users: $($highlyInactive.Count)" -ForegroundColor Red
Write-Host "`nReports Generated:" -ForegroundColor White
Write-Host " 1. $fullReportPath (all users)" -ForegroundColor White
Write-Host " 2. $highRiskReportPath (90+ days or never signed in)" -ForegroundColor White
Write-Host "`nScript completed successfully!" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Yellow
# Disconnect from Microsoft Graph
Disconnect-MgGraph | Out-Null
Write-Host "`nDisconnected from Microsoft Graph." -ForegroundColor Cyan PowerShell is powerful, but it adds overhead to everyday administration. It requires scripting skills and Microsoft Graph permissions, which not every admin is comfortable with. Analysis typically happens after export in tools like Excel, making quick investigations and frequent bulk actions less efficient.
A More Practical Way to Review Inactive Users
If your goal is to identify inactive users quickly, filter by Last Active in real time, and take action immediately, scripting doesn’t have to be your default tool. Traditional approaches often require exporting sign-in data, comparing interactive and non-interactive timestamps manually, and running repeated PowerShell queries just to validate inactivity. For ongoing tenant hygiene, that process quickly becomes inefficient.
EasyEntra simplifies this workflow by introducing a consolidated Last Activity column, which automatically reflects the latest time stamp found in the last sign-in and last non interactive sign-in.
With EasyEntra’s Full-Loading-Mode, you can:
- Instantly sort and filter all users by Last Activity.
- Combine inactivity data with other attributes such as account status, user type, department, or detailed license assignments.
- Customize the interface through flexible column management to focus only on the data relevant to your investigation.
- Access detailed user properties directly from search results.
- Apply compound filters in real time.
- Perform bulk actions without exporting data or writing scripts.
- Export data to .csv and .tsv format, including detailed licensing information.
For example, identifying users in a specific department who hold premium licenses but have not signed in for over 90 days becomes a simple filtering exercise. Results can be reviewed immediately and exported in .csv or .tsv format if needed for stakeholder validation or license optimization discussions.
This approach removes the friction of PowerShell while still giving you full visibility and control over inactive accounts, making it ideal for ongoing tenant hygiene, not just audits.
Learn how to enable Full-Loading-Mode in EasyEntra:
https://easyentra.com/knowledge-base/how-to/how-to-enable-full-loading-mode