๐Ÿ‘ฅ Recipe ยท User & Group Management

List All Users in a Microsoft 365 Tenant with Name and Email

Export every user's first name, last name, and email address from Entra ID using the admin center, Microsoft Graph, or PowerShell

Complexity

Beginner

Impact

reporting + user-management + audit + low-risk + read-only

Context

Why This Matters

Getting a complete, accurate list of every user in your Microsoft 365 tenant is one of the most common admin tasks. Whether you're preparing a license audit, building a distribution list, handing a roster to HR, or validating that directory sync is producing the right set of accounts, you need a clean export of first name, last name, and email address.

The M365 admin center exposes this information in the Active users blade, but it caps the export at a fixed schema and doesn't always surface every user type (e.g., guest accounts, unlicensed service accounts). Microsoft Graph and the Microsoft.Graph PowerShell module give you full control over the fields returned, pagination, and filtering โ€” which is what you want for any list larger than a few hundred users.

Run this recipe whenever you need a point-in-time snapshot of your directory for reporting, migration planning, or compliance evidence.

Expected Outcomes

After completing this recipe you will have:

  • A CSV or on-screen list of every user in the tenant showing givenName, surname, and mail (falling back to userPrincipalName when no primary SMTP is set).
  • A repeatable method โ€” manual, API, or scripted โ€” that correctly paginates through tenants with more than 100 users.
  • A baseline you can diff against future exports to track joiners, leavers, and account changes.

Risks & Considerations

Watch out for

  • Guest vs. member accounts. The default /users endpoint returns both. If you only want employees, filter with $filter=userType eq 'Member'.
  • Missing mail values. Cloud-only accounts and unlicensed users often have mail set to null. Always fall back to userPrincipalName so no row is blank.
  • Pagination. Graph returns at most 999 users per page. Always follow @odata.nextLink until it's absent โ€” otherwise your export is silently truncated.
  • PII handling. The exported CSV contains personal data. Store it on an encrypted share, limit who can read it, and delete it when the task is complete. Don't email it unencrypted.
  • Throttling. On very large tenants (50k+), issue requests sequentially and respect Retry-After headers. Parallelizing the paged calls is not supported because each page depends on the previous nextLink.

Required Permissions

PermissionWhy It's Needed
User.Read.AllMinimum scope required to enumerate all users and read basic profile properties (givenName, surname, mail, userPrincipalName).
Directory.Read.AllAlternative broader scope if you also need to read related directory objects (groups, roles) in the same workflow.
Global Reader (role)For interactive admin-center or PowerShell-with-delegated-auth usage, Global Reader is sufficient and avoids granting write privileges.

The fastest way to get this done โ€” just ask Dex. Copy the prompt below and paste it into your Dex conversation.

For IT Admins

Paste into Dex CoAdmin

List every user in our Microsoft 365 tenant with first name, last name, and email address. Export the full list to CSV and flag any accounts missing a primary email so I can review them.
Try in Dex CoAdmin