Skip to content

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

01

Install the Microsoft Graph Module

Setup

Install 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.

Terminal window
Install-Module Microsoft.Graph -Scope CurrentUser
Import-Module Microsoft.Graph.Users
Get-Module Microsoft.Graph.Users -ListAvailable |
Select-Object Name, Version
❯ View Expected Console Output
Name Version
---- -------
Microsoft.Graph.Users 2.x.x

Step 2: Connect with Read-Only Permissions

02

Sign In to the Correct Entra Tenant

Authentication

Connect 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.

Terminal window
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

03

Retrieve a Tenant-Wide User Inventory

Inventory

Request 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.

Terminal window
$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 AM
Guest User guest_example.com#EXT#... True Guest

Step 4: Flag Old or Missing Sign-Ins for Review

04

Build a Review Queue Without Changing Accounts

Analysis

Pick 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.

Terminal window
$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] Guest

Step 5: Export the Review and Disconnect

05

Save the CSV and End the Graph Session

Reporting

Export 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.

Terminal window
$ReportPath = Join-Path $env:TEMP "entra-user-review-$(Get-Date -Format yyyyMMdd).csv"
$Candidates | Export-Csv -Path $ReportPath -NoTypeInformation -Encoding utf8
Get-Item $ReportPath | Select-Object FullName, Length, LastWriteTime
Disconnect-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.

Comments