Review Microsoft Entra User Sign-In Activity with PowerShell
Microsoft Entra sign-in activity can help identity administrators find accounts that need an owner or access review. This walkthrough uses Microsoft Graph PowerShell to read user status and successful sign-in metadata, then exports a dated CSV. It does not block, disable, or modify users.
The signInActivity details require an eligible Microsoft Entra ID P1 or P2 license and the AuditLog.Read.All permission. Have an administrator grant consent for the delegated Graph permissions you need. Treat the report as a review aid: a missing or old sign-in value alone is not proof that an account is unused.
Step 1: Install the Graph PowerShell SDK
Install the Microsoft Graph Module
SetupInstall the Microsoft Graph PowerShell SDK for the signed-in user, or use your organization’s managed PowerShell repository. If the module is already deployed, skip installation and import the Users module.
Install-Module Microsoft.Graph -Scope CurrentUserImport-Module Microsoft.Graph.UsersGet-Module Microsoft.Graph.Users -ListAvailable | Select-Object Name, Version❯ View Expected Console Output
Name Version---- -------Microsoft.Graph.Users 2.x.xStep 2: Connect with Read-Only Permissions
Sign In to the Correct Entra Tenant
AuthenticationConnect interactively using the directory read and audit log scopes. Confirm the tenant and signed-in account before querying users. Your organization may require an administrator to consent to these delegated permissions.
Connect-MgGraph -Scopes 'User.Read.All', 'AuditLog.Read.All'Get-MgContext | Select-Object TenantId, Account, Scopes❯ View Expected Console Output
TenantId Account Scopes-------- ------- ------00000000-0000-0000-0000-000000000000 [email protected] {AuditLog.Read.All, User.Read.All}Step 3: Read User and Sign-In Properties
Retrieve a Tenant-Wide User Inventory
InventoryRequest only the fields needed for review. -All follows the paged results across the tenant; in large directories, schedule the export appropriately and follow your organization’s data handling rules. The last successful sign-in fields can be empty for users with no recorded successful sign-in.
$Users = Get-MgUser -All -Property @( 'Id', 'DisplayName', 'UserPrincipalName', 'AccountEnabled', 'UserType', 'SignInActivity')
$Review = $Users | Select-Object Id, DisplayName, UserPrincipalName, AccountEnabled, UserType, @{Name = 'LastSuccessfulSignInUtc'; Expression = { $_.SignInActivity.LastSuccessfulSignInDateTime }}
$Review | Select-Object -First 10 | Format-Table -AutoSize❯ View Expected Console Output
DisplayName UserPrincipalName AccountEnabled UserType LastSuccessfulSignInUtc----------- ----------------- -------------- -------- -----------------------Alex Morgan [email protected] True Member 10/1/2026 8:14:00 AMGuest User guest_example.com#EXT#... True GuestStep 4: Flag Old or Missing Sign-Ins for Review
Build a Review Queue Without Changing Accounts
AnalysisPick a review window that matches your organization’s policy. The sample below flags enabled accounts with no successful sign-in value or a value older than 90 days. Workload identities, emergency accounts, leave, and other approved exceptions need owner context before you decide what to do.
$Cutoff = (Get-Date).ToUniversalTime().AddDays(-90)$Candidates = $Review | Where-Object { $_.AccountEnabled -and ( -not $_.LastSuccessfulSignInUtc -or ([datetime]$_.LastSuccessfulSignInUtc).ToUniversalTime() -lt $Cutoff )}
$Candidates | Select-Object DisplayName, UserPrincipalName, UserType, LastSuccessfulSignInUtc | Format-Table -AutoSize❯ View Expected Console Output
DisplayName UserPrincipalName UserType LastSuccessfulSignInUtc----------- ----------------- -------- -----------------------Guest User [email protected] GuestStep 5: Export the Review and Disconnect
Save the CSV and End the Graph Session
ReportingExport only the fields your reviewers need, store the file in an access-controlled location, and confirm candidates with account owners before any access change. Disconnect when the review is complete to end the current Graph session.
$ReportPath = Join-Path $env:TEMP "entra-user-review-$(Get-Date -Format yyyyMMdd).csv"$Candidates | Export-Csv -Path $ReportPath -NoTypeInformation -Encoding utf8Get-Item $ReportPath | Select-Object FullName, Length, LastWriteTimeDisconnect-MgGraph❯ View Expected Console Output
FullName Length LastWriteTime-------- ------ -------------C:\Users\Admin\AppData\Local\Temp\entra-user-review-20261003.csv 1860 ...See Microsoft’s Graph PowerShell SDK setup guide, Get-MgUser reference, and user list API notes for sign-in activity for permissions and property details.