๐ณ Recipe ยท Licensing & Cost Optimization
Analyze E5 License Usage to Identify Downgrade Candidates to E3
Cross-reference E5-exclusive service usage with assigned licenses to find safe downgrade candidates and reduce licensing spend
Complexity
Advanced
Impact
cost-savings + licensing + reporting + governance + optimization
Context
Why This Matters
Microsoft 365 E5 licenses cost roughly 2x the price of E3, with the premium justified by exclusive workloads: Power BI Pro, Audio Conferencing, Phone System, Advanced eDiscovery, Microsoft Defender for Office 365 Plan 2, Defender for Endpoint Plan 2, Microsoft Purview (advanced), and Customer Lockbox. In most tenants, a meaningful percentage of E5 seats are assigned to users who never touch any of these E5-exclusive features โ pure license waste.
This recipe helps you systematically identify those users so Finance and IT can confidently downgrade them to E3 (or E3 + targeted add-ons) without breaking workflows or losing data. It is typically run:
- During annual or quarterly true-up / renewal cycles
- Before a Microsoft Enterprise Agreement renegotiation
- As part of a cost-optimization initiative
- After M&A activity when license inventories merge
The core technique is to cross-reference the list of E5 license holders against activity data from the Microsoft Graph usage reports (Power BI, Teams PSTN, Defender, Purview) over a 90-day window.
Expected Outcomes
You will produce:
- A complete inventory of users assigned an E5 SKU in your tenant
- A per-user utilization matrix showing which E5-exclusive services each user has actually used in the last 90 days
- A downgrade candidate list โ users with zero E5-exclusive activity who can safely move to E3
- A keep-as-E5 list โ users actively using at least one E5-exclusive feature
- An estimated annual cost savings figure based on candidate count
- A CSV export suitable for review by Finance, Security, and department managers before action
Typical savings
Organizations commonly find 20โ40% of their E5 seats are downgrade candidates, translating to tens of thousands of dollars in annual savings per 1,000 seats.
Risks & Considerations
โ ๏ธ Do not downgrade blindly
- Data loss risk: Downgrading removes access to E5-only features. Power BI Pro content a user owns (workspaces, reports) may become inaccessible if no other Pro user inherits ownership. Always reassign ownership first.
- Defender coverage gap: Removing Defender for Office 365 Plan 2 strips Safe Attachments/Safe Links advanced policies, Attack Simulator, and automated investigation from that user. Ensure tenant-wide Defender coverage or licensing gaps do not expose executives or high-value targets.
- PSTN / phone numbers: If the user has a phone number assigned via Phone System (included in E5), downgrading strips calling. Numbers must be reassigned or the user moved to E3 + Teams Phone add-on.
- Compliance obligations: Users under legal hold, advanced eDiscovery custodianship, or with Customer Key/Customer Lockbox requirements may legally require E5. Confirm with Legal/Compliance before acting.
- Usage reports lag: Graph usage reports have a 24โ48 hour lag and a maximum 90-day window. A user who used Power BI once 100 days ago will not appear as active. Consider pulling multiple 90-day snapshots or combining with Power BI admin portal export.
- Anonymized reports: If
displayConcealedNamesistruein report settings, UPNs will be redacted. You must toggle this off (tenant admin action, audit-logged) to attribute usage to individuals. - Pilot first: Always trial the downgrade on 5โ10 users for 2 weeks before bulk action.
Required Permissions
| Permission | Why It's Needed |
|---|---|
| Organization.Read.All | Enumerate subscribed SKUs and identify E5 vs E3 SKU IDs and service plans |
| User.Read.All | List users and their assigned license details to find E5 holders |
| Reports.Read.All | Read Office 365, Teams, Power BI, and Yammer activity reports to determine feature usage |
| Directory.Read.All | Supporting directory lookups for user attributes (department, manager) used in the candidate report |
| ReportSettings.ReadWrite.All | Temporarily disable report anonymization so usage can be attributed to named users |
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 Pro
Manual walkthrough via Microsoft 365 Admin Center
The portal does not provide a single consolidated E5-vs-E3 utilization report, so the manual path combines multiple admin views. Expect this to take 2โ4 hours for a mid-size tenant.
Step 1 โ Confirm SKU inventory
- Sign in to Microsoft 365 Admin Center as a Global Reader or Global Admin.
- Navigate to .
- Identify your E5 SKU (
SPE_E5,ENTERPRISEPREMIUM, or similar) and E3 SKU (SPE_E3,ENTERPRISEPACK). Note the assigned vs. available counts.
Step 2 โ Export E5 license holders
- Go to , click your E5 product.
- Click Assigned users โ Export to download a CSV of current E5 assignees.
Step 3 โ Disable report anonymization (required for named attribution)
- Navigate to .
- Uncheck Display concealed user, group, and site names in all reports.
- Click Save. This change is audit-logged.
Step 4 โ Gather usage data per E5-exclusive service
- Power BI Pro usage: Go to the Power BI Admin Portal โ Usage metrics, or export the Activity Log () for the last 90 days. Extract unique
UserIds. - Teams Audio Conferencing / PSTN: . Export the last 90 days.
- Defender for Endpoint: โ identify which users' devices are onboarded.
- Advanced eDiscovery / Purview: โ list custodians on active cases.
Step 5 โ Cross-reference and build the candidate list
- In Excel, combine the E5 holder list with the four usage lists using VLOOKUP/XLOOKUP on UPN.
- Any E5 user NOT appearing in any of the four usage lists is a downgrade candidate.
- Validate with the user's manager before action.
Step 6 โ (Optional) Re-enable anonymization
Return to and re-enable concealed names if your policy requires it.
Microsoft Graph API approach
The API approach automates the full cross-reference. All endpoints are v1.0 unless noted.
Step 1 โ Identify the E5 and E3 SKU IDs in your tenant
GET https://graph.microsoft.com/v1.0/subscribedSkus?$select=skuId,skuPartNumber,servicePlansLook for skuPartNumber values such as:
SPE_E5โ Microsoft 365 E5ENTERPRISEPREMIUMโ Office 365 E5SPE_E3โ Microsoft 365 E3ENTERPRISEPACKโ Office 365 E3
Note the skuId GUID for the E5 SKU โ you'll filter users against it.
Step 2 โ List all users assigned the E5 SKU
GET https://graph.microsoft.com/v1.0/users?$filter=assignedLicenses/any(x:x/skuId eq {E5_SKU_ID})&$select=id,displayName,userPrincipalName,accountEnabled,department,assignedLicenses&$count=true
ConsistencyLevel: eventualPaginate with @odata.nextLink. Store the UPNs in a set called e5Users.
Step 3 โ Ensure usage reports show real UPNs
GET https://graph.microsoft.com/v1.0/admin/reportSettings
// If displayConcealedNames = true, patch it:
PATCH https://graph.microsoft.com/v1.0/admin/reportSettings
Content-Type: application/json
{ "displayConcealedNames": false }Step 4 โ Pull E5-exclusive feature usage (90-day window)
Each of these returns CSV. Parse and extract the User Principal Name column for users with non-zero activity.
// Teams PSTN / Audio Conferencing
GET /v1.0/reports/getPstnCalls(fromDateTime=2024-01-01,toDateTime=2024-03-31)
// Power BI activity (via Office 365 activations / Yammer not reliable โ prefer Power BI admin API)
GET https://api.powerbi.com/v1.0/myorg/admin/activityevents?startDateTime='2024-01-01T00:00:00'&endDateTime='2024-01-01T23:59:59'
// Office 365 Active Users (to see per-service activity flags)
GET /v1.0/reports/getOffice365ActiveUserDetail(period='D90')Step 5 โ Check each user's licenseDetails for dependency signals
GET /v1.0/users/{user_id}/licenseDetailsReturns the service plans enabled for the user โ confirms whether Power BI Pro, MCAS, Defender P2, etc. are actually provisioned (not just disabled).
Step 6 โ Compute the candidate set
Pseudo-logic:
candidates = e5Users
- powerBiActiveUsers
- pstnActiveUsers
- defenderP2ActiveUsers
- advancedEDiscoveryCustodiansAny user remaining is a downgrade candidate. Export to CSV with columns: UPN, Display Name, Department, Account Enabled, Last Sign-in, Recommended Action.
PowerShell automation with Microsoft.Graph
The script below uses the Microsoft.Graph PowerShell SDK to fully automate the analysis and produce a candidate CSV in one run.
Prerequisites
- PowerShell 7+
Install-Module Microsoft.Graph -Scope CurrentUser- An admin account with the permissions listed above (or consent on first run)
How it works
- Connects to Graph with the required delegated scopes.
- Discovers the E5 SKU automatically by matching
skuPartNumberagainst known E5 identifiers. - Enumerates all E5 license holders with paging.
- Temporarily ensures report names are visible (optionally restores the prior setting on exit).
- Pulls three 90-day usage reports: PSTN calls, Office 365 active users, and Teams device usage.
- Checks each user's licenseDetails for active E5 service plans.
- Produces two CSV files:
E5-Downgrade-Candidates.csvandE5-Keep.csv. - Prints a summary with estimated annual savings.
Usage
.\Analyze-E5Usage.ps1 -OutputPath C:\Reports -AnnualE5Cost 57 -AnnualE3Cost 36Review the output CSVs with Finance and department managers before executing any license changes.
Next steps