M365-001 · Script
Directory and User Reports
Exports Microsoft 365 users with status, licenses, admin roles and last sign-in, and flags risky accounts.
What it does
Read-only. Saves two dated CSV files in the Reports folder:
- Users: name, UPN, enabled, member or guest, created date, department, title,
licenses, admin roles, synced from on-premises, last sign-in, days since sign-in, flags
- AdminRoles: one row per admin role assignment
Flags: Inactive (no sign-in for -InactiveDays), Never signed in, Admin inactive, Enabled but unlicensed member, Guest inactive. Optionally lists each user's group memberships (slower on large tenants). Sign-in dates need Microsoft Entra ID P1 or higher; without it, the report still runs and the sign-in columns are left blank.
Requirements
Microsoft Graph PowerShell SDK, installed by you from the PowerShell Gallery (not included). Graph application permissions: User.Read.All, Directory.Read.All, AuditLog.Read.All Windows PowerShell 5.1 or PowerShell 7.
How to run it
- Run from: an admin workstation or scheduled task with the Microsoft modules installed and app sign-in configured
- This is an admin script for your Microsoft 365 tenant, not a per-device endpoint script
- User interaction: none with app-only sign-in
- Schedule: run on demand, or weekly for reports
Settings
| Name | What it does | Options | Default |
|---|---|---|---|
| InactiveDays | Days without sign-in before an account is flagged Inactive. Default: 90. | 90 | |
| IncludeGroups | Add a Groups column with each user's group names. | False | |
| AlertOnInactiveAdmins | Exit 1 when any enabled admin account is inactive or has never signed in. | False | |
| TenantId | Directory (tenant) ID, for unattended app-only sign-in. | ||
| ClientId | Application (client) ID of your app registration. | ||
| CertificateThumbprint | Thumbprint of the certificate uploaded to the app registration. | ||
| UseExistingSession | Use a Microsoft Graph session you already opened with Connect-MgGraph. | False |
Exit codes
- 0 = Completed
- 1 = Inactive admin accounts found (only with -AlertOnInactiveAdmins)
- 2 = Script error (see log)
Testing steps
- Run it on one test tenant or small OU and check the output and log.
- Check the exit code: 0 = OK, 1 = needs attention, 2 = error (see log), 9 = this copy is past its Valid until date.
- Roll out to a small group next, then everyone.
Rollback steps
Report only. It saves a CSV and changes nothing else.
Version and change log
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | November 2026 | First release. |