PowerShell Script to Check User Status in Microsoft Entra ID

Introduction

As organizations move towards the Microsoft 365 ecosystem, managing user accounts in Microsoft Entra ID (formerly Azure Active Directory) becomes a routine task for system administrators and IT support teams.

One of the critical checks often required is verifying the account status—whether a user is enabled, disabled, or simply doesn’t exist in the tenant. This could be part of a regular audit, license cleanup, or onboarding/offboarding workflow.

Manually checking each user’s status through the Microsoft Entra admin portal is inefficient and time-consuming—especially in large environments.

That’s why I have written this PowerShell script: to automate the process of checking user status from a CSV list using the Microsoft Graph API.

Let’s walk through how it works, what you need, and how to use it in your environment.


💡 What the Script Does

This script performs the following steps:

  1. Connects to Microsoft Graph using delegated permissions.
  2. Reads a CSV file containing user email addresses (UserPrincipalName).
  3. Queries Microsoft Entra ID for each user’s account status.
  4. Builds a report indicating whether the user is:
    • Enabled
    • Disabled
    • Not Found
  5. Displays the report in the PowerShell console.
  6. Exports the report to a timestamped CSV file for record-keeping or further analysis.

📥 Script Download

👉 You can download the full script from my GitHub repo:
🔗 Check-EntraIDUserStatus.ps1 – GitHub


📋 Use Case Scenarios

Here are a few real-world scenarios where this script becomes incredibly useful:

  • Audit and compliance: Validate account status for a list of critical users.
  • 🧹 License cleanup: Check if disabled accounts are still consuming licenses.
  • 👋 Offboarding verification: Ensure accounts of departed users are disabled.
  • 🔍 Troubleshooting: Quickly check if a user experiencing access issues is active or disabled.

⚙️ Prerequisites

To use this script, make sure the following requirements are met:

✅ PowerShell

  • PowerShell 7.0+ is recommended for better performance and compatibility.
    • You can check your version using: $PSVersionTable.PSVersion

✅ Microsoft.Graph Module

  • This script uses the modern Microsoft Graph PowerShell SDK (not the legacy AzureAD module).
    • To install: powershellCopyEditInstall-Module Microsoft.Graph -Scope CurrentUser

✅ Permissions

  • You must log in with an account that has delegated access with the scope:
    • User.Read.All
  • When prompted, you’ll sign in interactively.

✅ Input File Format

  • The input file should be a CSV with a column named UserPrincipalName.

Example:

UserPrincipalName
alice@yourdomain.com
bob@yourdomain.com


🧑‍💻 Script Walkthrough

🔗 Connect to Microsoft Graph

Connect-MgGraph -Scopes "User.Read.All"

This initiates a sign-in to Microsoft Graph with the necessary permissions to read user data.


📂 Define File Paths

$inputPath = "C:\Temp\input\upncheckentraid.csv"
$outputPath = "C:\Temp\output"

These define where the script looks for the CSV and where to save the output. Make sure the folders exist or allow the script to create them.


🕓 Timestamped Output Filename

$timestamp = Get-Date -Format "ddMMyyyy-HHmm"
$outputFileName = "UserStatusReport-$timestamp.csv"
$outputPathFileName = Join-Path -Path $outputPath -ChildPath $outputFileName

This ensures that each output file is uniquely named and doesn’t overwrite previous reports.


📥 Import CSV and Prepare Output

$usersList = Import-Csv -Path $inputPath
$results = @()

if (-not (Test-Path $outputPath)){
New-Item -ItemType Directory -Path $outputPath -Force | Out-Null
}

The script imports the list of users from CSV and ensures the output folder exists.


🔄 Process Each User

foreach ($user in $usersList) {
$upn = $user.UserPrincipalName
try {
$userInfo = Get-MgUser -UserId $upn -Property Id, DisplayName, UserPrincipalName, AccountEnabled -ErrorAction Stop
$status = if ($userInfo.AccountEnabled) { "Enabled" } else { "Disabled" }
$results += [PSCustomObject]@{
UserPrincipalName = $userInfo.UserPrincipalName
DisplayName = $userInfo.DisplayName
Status = $status
}
}
catch {
$results += [PSCustomObject]@{
UserPrincipalName = $upn
DisplayName = "Not Found"
Status = "Not Found in Entra ID"
}
}
}

This is the core loop:

  • For each user:
    • Attempts to fetch data from Entra ID.
    • If successful, checks the AccountEnabled field.
    • If not found, adds a fallback result showing the user is not in the directory.

📊 Display and Export Results

$results | Format-Table -AutoSize
$results | Export-Csv -Path $outputPathFileName -NoTypeInformation
Write-Output "User status report exported to path: $outputPathFileName"

At the end:

  • A neat table is shown in the console.
  • The results are saved as a CSV for later use.

🧪 Sample Output

UserPrincipalNameDisplayNameStatus
alice@yourdomain.comAlice JohnsonEnabled
bob@yourdomain.comBob SmithDisabled
invalid@yourdomain.comNot FoundNot Found in Entra ID

Leave a Reply

Your email address will not be published. Required fields are marked *