Microsoft 365 license management automation uses the Microsoft Graph API to programmatically assign, remove, and reclaim licenses across an organization, replacing the manual process of clicking through the Microsoft 365 admin center for each user. At scale, automated license management prevents over-provisioning, recovers orphaned licenses, and can save organizations $70,000–$120,000 per year per 1,000 users.
Microsoft 365 licensing is one of those problems that starts small and gets expensive fast. When you have 50 users, you can manage licenses in the admin center with a spreadsheet on the side. When you have 500 or 5,000, manual license management becomes a full-time job — and an error-prone one. The average mid-size organization overspends on M365 licenses by 15–25%, mostly because nobody has time to track who is actually using what.
This article covers the real cost of manual license management, the most common mistakes, and how to use the Microsoft Graph API to automate assignment, removal, and reclamation at scale.
License costs are easy to see on your Microsoft invoice. What most teams miss is the operational cost layered on top. Consider a typical 1,000-user organization:
Add it up and a 1,000-user org is losing $70,000–$120,000 per year on license mismanagement. For a 5,000-user enterprise, that number can exceed $500,000.
The path of least resistance is to give every new hire the same license tier. When the standard is E5 at $57/user/month instead of E3 at $36/user/month, you are paying an extra $252/year per user who does not need the advanced compliance, analytics, or phone system features. Over 200 over-provisioned users, that is $50,400 annually.
When an employee leaves, their license should be reclaimed within 24–48 hours. In practice, offboarding processes are inconsistent. HR notifies IT late, the account gets disabled but the license stays assigned, or the offboarding ticket sits in the queue for a week. Every month those licenses stay assigned is money burned.
A user can have a Visio Plan 2 license ($15/month) and never open Visio. Without usage reports, you have no way to know. Microsoft provides usage data through the admin center and Graph API, but most teams never set up automated monitoring.
When a user needs a license, they submit a ticket. An admin opens the M365 admin center, finds the user, assigns the license, confirms it, and closes the ticket. Fifteen minutes per ticket, 80 times a month. This is the exact kind of repetitive, low-risk work that should never require a human.
The Microsoft Graph API provides full programmatic control over license operations. Every action you can perform in the M365 admin center can be done through Graph, which means you can script it, schedule it, and integrate it with your ITSM platform.
Before assigning a license, check what is available in your tenant:
GET https://graph.microsoft.com/v1.0/subscribedSkus
Authorization: Bearer {access_token}
// Response includes:
// skuPartNumber: "ENTERPRISEPACK" (E3), "SPE_E5" (E5)
// prepaidUnits.enabled: total purchased
// consumedUnits: currently assigned
// Available = enabled - consumedPOST https://graph.microsoft.com/v1.0/users/{userId}/assignLicense
Content-Type: application/json
Authorization: Bearer {access_token}
{
"addLicenses": [
{
"skuId": "6fd2c87f-b296-42f0-b197-1e91e994b900",
"disabledPlans": []
}
],
"removeLicenses": []
}POST https://graph.microsoft.com/v1.0/users/{userId}/assignLicense
Content-Type: application/json
Authorization: Bearer {access_token}
{
"addLicenses": [],
"removeLicenses": ["6fd2c87f-b296-42f0-b197-1e91e994b900"]
}The skuId is not the same as the SKU part number. Use the /subscribedSkus endpoint to map friendly names like "ENTERPRISEPACK" to the GUID that assignLicense requires. This mapping is tenant-specific for add-on SKUs.
When you need to reassign licenses in bulk — migrating users from E3 to E5, reclaiming unused add-ons, or provisioning a new department — Graph API supports batching up to 20 requests in a single HTTP call:
POST https://graph.microsoft.com/v1.0/$batch
Content-Type: application/json
{
"requests": [
{
"id": "1",
"method": "POST",
"url": "/users/user1@contoso.com/assignLicense",
"body": { "addLicenses": [{"skuId": "..."}], "removeLicenses": [] },
"headers": { "Content-Type": "application/json" }
},
{
"id": "2",
"method": "POST",
"url": "/users/user2@contoso.com/assignLicense",
"body": { "addLicenses": [{"skuId": "..."}], "removeLicenses": [] },
"headers": { "Content-Type": "application/json" }
}
]
}Each request in the batch gets its own response with a status code, so you can handle partial failures. For operations larger than 20 users, loop through batches with a brief delay to stay within Graph API throttling limits (10,000 requests per 10 minutes for most tenants).
Reclamation is where the real savings live. A good reclamation workflow runs on a schedule — weekly or monthly — and flags licenses that should be removed or downgraded. Here is a practical approach:
Never automate license removal without a review step. Removing a license can delete data — for example, removing an Exchange Online license will mark the mailbox for deletion after 30 days. Always flag for review first, then execute after approval.
The highest-impact integration connects license operations to your ITSM workflow. When a ServiceNow ticket requests a license assignment, the automation should check availability, assign the license, confirm success, and close the ticket — all without an admin touching the M365 portal.
Building this in ServiceNow Flow Designer requires a REST integration with Graph API, OAuth token management, error handling for insufficient licenses, and logic to map ServiceNow catalog items to M365 SKU IDs. It works, but maintaining it across multiple license types and handling edge cases (user already has the license, user in a different tenant, license requires a prerequisite SKU) adds complexity quickly.
Support Team handles this out of the box. It reads license request tickets from ServiceNow, understands the request regardless of how it is worded, checks availability, assigns the license through Graph API, and updates the ticket — including handling edge cases like prerequisite SKUs and duplicate assignments. The reclamation workflow runs on a schedule and surfaces savings opportunities to your team.
Yes. Combine Microsoft Graph API license assignment with your HR onboarding workflow. When a new user is created in Azure AD (via HR sync or manual provisioning), trigger a Graph API call to assign the appropriate license SKU based on department or role. This eliminates the delay between account creation and license availability.
Use the Graph API signInActivity endpoint to find users who haven't signed in for 90+ days, then cross-reference with assigned licenses. Users with expensive SKUs (E5, Visio, Project) who haven't signed in are candidates for license removal. Always notify the user before reclaiming.
Group-based licensing (assigning licenses via Azure AD group membership) and direct API assignment are complementary. Use group-based licensing for role-based defaults and API calls for exceptions, temporary assignments, and reclamation workflows.
Support Team automates license assignment, removal, and reclamation across your Microsoft 365 tenant. It connects to ServiceNow, resolves license tickets automatically, and identifies unused licenses you can reclaim — saving mid-size orgs $50K+ per year.
See How It Works