๐Ÿ’ณ Recipe ยท Licensing & Cost Optimization

List Microsoft 365 E5 Users with Last Sign-In Time

Generate an audit-ready report of every E5-licensed user, their UPN, and their last interactive and non-interactive sign-in timestamps.

Complexity

Intermediate

Impact

licensing + cost-optimization + governance + audit + reporting

Context

Why This Matters

Microsoft 365 E5 is typically the most expensive SKU in a tenant. Unused or rarely used E5 licenses are a common source of license waste, and stale privileged accounts holding E5 can also represent a security risk (Defender, Purview, and AAD P2 features attached to dormant identities).

This recipe produces a complete inventory of E5-assigned users along with their lastSignInDateTime and lastNonInteractiveSignInDateTime, sorted by recency. It is the starting point for:

  • License rightsizing (E5 โ†’ E3 downgrade candidates)
  • Quarterly access reviews of premium licenses
  • Identifying abandoned or service accounts still consuming premium SKUs
  • Feeding a finance/procurement true-up conversation with concrete data

Run it ad-hoc before renewal, or on a monthly schedule as part of a broader license governance cadence.

Expected Outcomes

What you will have when finished

  • The exact skuId and skuPartNumber for Microsoft 365 E5 in your tenant (commonly SPE_E5)
  • A count of consumed E5 licenses and the full list of assigned users
  • Per-user: UPN, display name, last interactive sign-in, last non-interactive sign-in
  • A CSV report suitable for sharing with security, finance, or auditors
  • A clearly identified list of users who have never signed in or who have been inactive beyond your threshold (e.g. 30/60/90 days)

Risks & Considerations

Warnings & considerations

  • signInActivity requires AuditLog.Read.All plus a tenant with Azure AD Premium P1 or P2. Free-tier tenants will receive null for all sign-in fields.
  • signInActivity cannot be combined with $filter on assignedLicenses in a single Graph call โ€” Graph returns HTTP 400. Always fetch users + sign-in activity, then filter client-side.
  • Do not assume a null value means the account is unused. Sign-in logs are retained for 30 days (P1) or 30 days rolling. A null can mean "never signed in in the retention window".
  • Non-interactive sign-ins (tokens, service principals, mail clients) can be high even when the human has left โ€” always check both fields before reclaiming a license.
  • Service accounts, shared mailboxes, and break-glass accounts may legitimately hold E5 with rare interactive logins. Whitelist these before any automated reclamation.
  • The report contains PII (UPN, display name, activity data). Store it in a controlled location and delete when no longer needed.

Required Permissions

PermissionWhy It's Needed
Organization.Read.AllRequired to enumerate subscribedSkus and identify the E5 SKU ID in your tenant.
User.Read.AllRequired to list users and read their assignedLicenses property.
AuditLog.Read.AllRequired to read the signInActivity property (lastSignInDateTime / lastNonInteractiveSignInDateTime) on user objects.
Directory.Read.AllFallback directory read permission for license-detail and user enumeration scenarios.

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 Microsoft 365 E5 licensed user in our tenant with their UPN, display name, last interactive sign-in, and last non-interactive sign-in. Sort by most recent sign-in and produce a downloadable CSV. Flag any users inactive more than {inactive_days} days and any that have never signed in.
Try in Dex CoAdmin