๐Ÿ‘ฅ Recipe ยท User & Group Management

Audit 90-Day Inactive M365 Users and Build a Safe Deprovisioning Plan

Identify stale accounts with real activity data from Exchange, SharePoint, OneDrive, and Teams โ€” then phase deprovisioning with manager notification

Complexity

Intermediate

Impact

cost-savings + security + governance + compliance + license-optimization

Context

Why This Matters

Inactive user accounts are one of the highest-leverage cleanup targets in a Microsoft 365 tenant. Every stale account typically carries a paid license (often E3 or E5), a live mailbox, OneDrive storage, and potentially SharePoint site ownership. Beyond cost, they're a security liability: dormant accounts are prime targets for password spray and phishing-based takeover.

Running a 90-day inactivity audit is a standard governance control recommended by CIS, NIST, and Microsoft Secure Score. This recipe walks through the right way to build that audit โ€” not just by looking at Entra sign-in logs (which miss service-specific activity), but by cross-referencing the getOffice365ActiveUserDetail usage report that includes Exchange, SharePoint, OneDrive, and Teams last-activity dates.

The output is not just a list โ€” it's a phased deprovisioning plan with manager notifications, license removal recommendations, and safeguards against accidentally disabling executive or service accounts.

Expected Outcomes

After completing this recipe you will have:

  • A CSV report of all users inactive for 90+ days with per-service last-activity dates (Exchange, SharePoint, OneDrive, Teams)
  • License assignment details for each inactive user (critical for cost recovery)
  • Manager name and email for each inactive user (for the notification workflow)
  • A recommended action per user (review for license removal vs. account disable)
  • A phased 4-week deprovisioning plan (notify โ†’ review โ†’ disable โ†’ delicense)
  • A flag for high-risk accounts (executives, service accounts, shared mailboxes) that need HR/manual review

Risks & Considerations

Watch out for these pitfalls:

  • Anonymized reports: By default M365 usage reports show concealed names like 5C0DBAโ€ฆ. You must temporarily set displayConcealedNames: false via PATCH /admin/reportSettings to get real UPNs. Always re-enable anonymization after the audit to stay aligned with your privacy posture.
  • Don't rely on signInActivity alone: It only tracks Entra interactive/non-interactive sign-ins. A user may be inactive in Entra logs but still have Exchange mail flow or OneDrive sync activity. Use the usage report for a true picture.
  • Service accounts and shared mailboxes will appear as inactive โ€” they're designed to never sign in interactively. Tag and exclude them before any disable action.
  • Executive accounts (C-suite, board members) often show low activity but should never be auto-deprovisioned. Always escalate these to HR.
  • Don't delete accounts directly. The safe sequence is: notify manager โ†’ remove licenses โ†’ disable sign-in โ†’ convert mailbox to shared โ†’ wait 30 days โ†’ delete. Skipping the shared-mailbox step loses mail data permanently.
  • Licensed but never signed in: These are often onboarding mistakes (license assigned before user started) or offboarding failures. Investigate before revoking.
  • B2B guest users have different activity patterns and may not appear correctly in the usage report. Handle them in a separate audit.

Required Permissions

PermissionWhy It's Needed
Reports.Read.AllRequired to call getOffice365ActiveUserDetail and related usage reports that provide per-service activity data
ReportSettings.ReadWrite.AllRequired to temporarily disable report anonymization (displayConcealedNames) so actual UPNs and display names appear in reports
User.Read.AllRequired to fetch per-user license assignments, accountEnabled status, department, and job title
Directory.Read.AllRequired to read each user's manager relationship for the notification workflow
Organization.Read.AllOptional โ€” needed if you want to map license SKU GUIDs to friendly product names for the report

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

Audit our M365 tenant for users inactive {days} days (default 90). Pull activity across Exchange, SharePoint, OneDrive, and Teams โ€” not just Entra sign-ins. For each inactive user, report license count, manager, and department. Flag executives and service-account candidates separately. Output a phased deprovisioning plan with manager notifications and a CSV I can action on.
Try in Dex CoAdmin