EASYENTRA Blog

News & Updates

Find Inactive User Accounts in Microsoft Entra Based on Last Sign-in Activity 

How to find inactive users with PowerShell or EasyEntra

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: 

  1. Sign in to the Microsoft Entra admin center. 
  1. Navigate to Identity > Users > All users. Select the specific user you want to investigate 
  1. 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 

                  Free 30-minute demo

                  try 30 days for free

                  GET EASYENTRA NEWS

                  Opt out at any time

                  “One of the best products I've used.”
                  Gary Shurland
                  Chief Information Officer, Mirick, United States
                  “This tool has been invaluable in streamlining our IT processes.”
                  Tyson Mckay
                  Chief Information Officer, Southwest Network, United States
                  “This product has been a miracle for our Help Desk. EasyEntra has completely transformed how we handle Microsoft 365 administration.”
                  Doug Sanders
                  Manager of Technical Customer Support, Junior Achievement USA, United States
                  “Your product is such a time saver. I love it!”
                  Scott Fehr
                  IT Infrastructure, MEC Aerial Work Platforms, United States
                  “It's a good product and saves us lots of time for these ongoing quick admin tasks.” 
                  Chris McFerran
                  Managing Director, CTech IT Solutions Ltd, United Kingdom
                  “EasyEntra has significantly streamlined our workflow, simplifying everything. It feels almost like a revolution.”
                  Johan Sadelius
                  IT-chef, Arjeplog Kommun, Sweden
                  I greatly appreciate your assistance and willingness to enhance the already outstanding product.”
                  Michael I. Wilson
                  Executive Director of Information Technology, Archdiocese Of Washington, United States
                  “It's great not having to switch back and forth between the O365 admin center and the Teams admin center to assign groups. I am sold!”
                  Thomas Madden
                  Director Information Technology, AutoPayPlus, United States
                  “I would highly recommend organizations use the solution as it greatly simplifies various tasks.”
                  S. Roger Singh
                  Chief Technology Officer, Prasad & Company LLP, Canada
                  “EasyEntra is time-saving. Love the copy/paste for user/computer groups and the copy to new user.”
                  Damian Nita
                  Associate Network Administrator, Shenandoah Valley Westminster-Canterbury, United States
                  “EasyEntra has transformed our daily IT operations by simplifying user management, reducing errors, and enhancing overall efficiency.”
                  Henrik Nefling
                  IT- and Digitalization Manager, Animal Protection Denmark, Denmark