Source profileQuality 94/100

WYRE-AI/msp-claude-plugins/msp-claude-plugins/m365/m365/skills/licensing/SKILL.md

Microsoft 365 Licensing

The M365 subscription → SKU → service-plan model, seat availability versus consumption, assigning and removing licenses through Graph, the audit workflow for finding unused or misallocated seats, common SKU GUIDs, and licensing error causes.

Source repository stars
42
Declared platforms
0
Static risk flags
0
Last source update
2026-08-28
Source checked
2026-08-28

Decision brief

What it does: where it fits

The M365 subscription → SKU → service-plan model, seat availability versus consumption, assigning and removing licenses through Graph, the audit workflow for finding unused or misallocated seats, common SKU GUIDs, and licensing error causes.

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/WYRE-AI/msp-claude-plugins --skill "msp-claude-plugins/m365/m365/skills/licensing"
    Safe inspection promptEditorial

    Inspect the Agent Skill "Microsoft 365 Licensing" from https://github.com/WYRE-AI/msp-claude-plugins/blob/5005f73ba2f52cd299f58aa6bb79f4e70ae87103/msp-claude-plugins/m365/m365/skills/licensing/SKILL.md at commit 5005f73ba2f52cd299f58aa6bb79f4e70ae87103. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      License Audit Workflow

      Pull subscribedSkus and calculate: - Total purchased per SKU - Consumed seats - Available seats - SKUs in warning state (near renewal, overallocated)

      Total purchased per SKUConsumed seatsAvailable seats
    2. 02

      Step 1: Inventory Available SKUs

      Pull subscribedSkus and calculate: - Total purchased per SKU - Consumed seats - Available seats - SKUs in warning state (near renewal, overallocated)

      Total purchased per SKUConsumed seatsAvailable seats
    3. 03

      Step 2: Cross-Reference With Active Users

      Find licenses assigned to disabled accounts — these are reclaim candidates:

      Find licenses assigned to disabled accounts — these are reclaim candidates:
    4. 04

      Step 3: Find Inactive Licensed Users

      Users licensed but not signing in (90+ days):

      Users licensed but not signing in (90+ days):Filter results where signInActivity.lastSignInDateTime < (today - 90 days).
    5. 05

      Step 4: Produce Optimization Report

      Review the “Step 4: Produce Optimization Report” section in the pinned source before continuing.

      Review and apply the “Step 4: Produce Optimization Report” source section.

    Permission review

    Static risk signals and limitations

    No configured static risk pattern was detected

    This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score94/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars42SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    WYRE-AI/msp-claude-plugins
    Skill path
    msp-claude-plugins/m365/m365/skills/licensing/SKILL.md
    Commit
    5005f73ba2f52cd299f58aa6bb79f4e70ae87103
    License
    Apache-2.0
    Collected
    2026-08-28
    Default branch
    main
    View the original SKILL.md

    Microsoft 365 Licensing

    Overview

    M365 licensing is a top billing concern for MSPs. Licenses are purchased as SKU subscriptions, each containing bundles of service plans (Exchange, Teams, SharePoint, etc.). Efficient license management — finding unused seats, rightsizing SKUs, ensuring all users have what they need — directly impacts both the MSP's margin and the customer's costs.

    Anti-triggers

    Assigning a seat and buying a seat are different systems, and the word "license" covers both:

    • Buying, cancelling, or repricing subscriptions — changing what the tenant owns happens at the distributor, not in Graph. subscribedSkus only reports what was already purchased. Use pax8 (pax8-subscriptions), sherweb, or cipp for CSP licences.
    • License cost, margin, or invoice reconciliation — commercial data lives with the distributor and in the PSA contract, not in Entra; use pax8 (pax8-invoices) or the finance-pack.
    • A licence audit across every customer tenant — use the cipp plugin (cipp-licenses).
    • Reading seat utilisation without changing assignments — the vetted query catalogue answers this without composing a $filter; use the microsoft-graph plugin's microsoft-graph-querying skill.

    Core Concepts

    Subscription → SKU → Service Plans

    M365 Business Premium (subscription)
      └── GUID: cbdc14ab-d96c-4c30-b9f4-6ada7cdc1d46
           ├── Exchange Online (service plan)
           ├── Microsoft Teams (service plan)
           ├── SharePoint Online (service plan)
           ├── Intune (service plan)
           └── Entra ID P1 (service plan)
    

    License States

    StateMeaning
    EnabledService plan is active and usable
    DisabledPlan is turned off for this user (license still assigned)
    ErrorAssignment failed — usually missing usageLocation
    LockedOutTenant billing issue
    PendingInputWaiting for additional configuration

    Graph API Patterns

    Get All SKUs Available in Tenant

    GET /v1.0/subscribedSkus?$select=skuPartNumber,skuId,consumedUnits,prepaidUnits,servicePlans
    

    Response:

    {
      "value": [
        {
          "skuPartNumber": "SPE_E3",
          "skuId": "05e9a617-0261-4cee-bb44-138d3ef5d965",
          "consumedUnits": 42,
          "prepaidUnits": {
            "enabled": 50,
            "suspended": 0,
            "warning": 0
          },
          "servicePlans": [...]
        }
      ]
    }
    

    Available seats = prepaidUnits.enabled - consumedUnits

    Get All Users With Their Assigned Licenses

    GET /v1.0/users?$select=id,displayName,userPrincipalName,accountEnabled,assignedLicenses,usageLocation&$top=999
    

    Find Users With a Specific License

    Filter by SKU GUID:

    GET /v1.0/users?$filter=assignedLicenses/any(x:x/skuId eq cbdc14ab-d96c-4c30-b9f4-6ada7cdc1d46)&$select=id,displayName,userPrincipalName,accountEnabled
    

    Find Unlicensed Users

    GET /v1.0/users?$filter=assignedLicenses/$count eq 0&$count=true&$select=id,displayName,userPrincipalName,accountEnabled
    

    Requires ConsistencyLevel: eventual header and $count=true

    Assign a License to a User

    POST /v1.0/users/{userId}/assignLicense
    Content-Type: application/json
    
    {
      "addLicenses": [
        {
          "skuId": "cbdc14ab-d96c-4c30-b9f4-6ada7cdc1d46",
          "disabledPlans": []
        }
      ],
      "removeLicenses": []
    }
    

    usageLocation must be set on the user before assigning. Use PATCH /v1.0/users/{id} with "usageLocation": "US" first.

    Remove a License from a User

    POST /v1.0/users/{userId}/assignLicense
    Content-Type: application/json
    
    {
      "addLicenses": [],
      "removeLicenses": ["cbdc14ab-d96c-4c30-b9f4-6ada7cdc1d46"]
    }
    

    Disable Specific Service Plans (Partial License)

    Assign a license but disable specific plans (e.g., give E3 without Teams):

    POST /v1.0/users/{userId}/assignLicense
    Content-Type: application/json
    
    {
      "addLicenses": [
        {
          "skuId": "05e9a617-0261-4cee-bb44-138d3ef5d965",
          "disabledPlans": ["57ff2da0-773e-42df-b2af-ffb7a2317929"]
        }
      ],
      "removeLicenses": []
    }
    

    License Audit Workflow

    Step 1: Inventory Available SKUs

    Pull subscribedSkus and calculate:

    • Total purchased per SKU
    • Consumed seats
    • Available seats
    • SKUs in warning state (near renewal, overallocated)

    Step 2: Cross-Reference With Active Users

    Find licenses assigned to disabled accounts — these are reclaim candidates:

    GET /v1.0/users?$filter=accountEnabled eq false and assignedLicenses/$count ne 0&$count=true&$select=id,displayName,userPrincipalName,assignedLicenses
    

    Step 3: Find Inactive Licensed Users

    Users licensed but not signing in (90+ days):

    GET /v1.0/users?$filter=accountEnabled eq true&$select=id,displayName,userPrincipalName,assignedLicenses,signInActivity
    

    Filter results where signInActivity.lastSignInDateTime < (today - 90 days).

    Step 4: Produce Optimization Report

    OptimizationEstimated Saving
    Remove licenses from disabled accounts# disabled × monthly seat cost
    Downgrade inactive users to lighter SKUSKU price delta × count
    Recover unused purchased seats(purchased - consumed) seats available

    Common SKU GUIDs Reference

    SKU Part NumberGUIDNotes
    SPE_E305e9a617-0261-4cee-bb44-138d3ef5d965M365 E3
    SPE_E506ebc4ee-1bb5-47dd-8120-11324bc54e06M365 E5
    O365_BUSINESS_PREMIUMcbdc14ab-d96c-4c30-b9f4-6ada7cdc1d46M365 Business Premium
    ENTERPRISEPACK6fd2c87f-b296-42f0-b197-1e91e994b900Office 365 E3
    AAD_PREMIUM078d2b04-f1bd-4111-bbd4-b4b1b354cef4Entra ID P1
    AAD_PREMIUM_P284a661c4-e949-4bd2-a560-ed7766fcaf2bEntra ID P2
    EMSefccb6f7-5641-4e0e-bd10-b4976e1bf68eEMS E3

    Error Handling

    ErrorCauseResolution
    LicenseAssignmentErrorNo usageLocation on userSet usageLocation first
    MutuallyExclusiveLicensesTwo conflicting SKUsRemove old SKU before assigning new
    Request_ResourceNotFoundInvalid SKU GUIDVerify GUID against subscribedSkus
    Authorization_RequestDeniedMissing Directory.ReadWrite.AllGrant admin consent

    Permissions Required

    TaskMicrosoft Graph Permission
    View subscribed SKUsDirectory.Read.All
    View user licensesUser.Read.All
    Assign/remove licensesUser.ReadWrite.All or Directory.ReadWrite.All
    Sign-in activityAuditLog.Read.All

    Related Skills

    Frequently asked questions

    What to verify before installation and use

    What does the Microsoft 365 Licensing source document cover?

    The M365 subscription → SKU → service-plan model, seat availability versus consumption, assigning and removing licenses through Graph, the audit workflow for finding unused or misallocated seats, common SKU GUIDs, and licensing error causes.

    How do I install Microsoft 365 Licensing?

    The source record exposes this install command: npx skills add https://github.com/WYRE-AI/msp-claude-plugins --skill "msp-claude-plugins/m365/m365/skills/licensing". Inspect the command and pinned source before running it.

    Alternatives

    Compare before choosing

    Computed 10025,136

    alirezarezvani/claude-skills

    app-store-optimization

    App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist

    Computed 9967

    brucesongs/kali-claw

    insecure-design

    Insecure Design (OWASP A06:2025) focuses on security flaws in system architecture and design phases, rather than code implementation-level bugs.

    Computed 9916

    NintendaDev/unikit-ai

    unikit-docs

    Generate and maintain the project's TECHNICAL documentation from its codebase — scans the project structure, tech stack, and module boundaries, then writes a lean README landing page plus detailed topic pages (architecture, modules, setup, build, APIs), only the docs that are relevant. Use whenever the user wants to create, update, or validate documentation of the CODE or the project itself, e.g. "generate documentation", "create docs", "write the README", "update the project docs", "document th

    Computed 9836,049

    K-Dense-AI/scientific-agent-skills

    dask

    Distributed computing for larger-than-RAM pandas/NumPy workflows. Use when you need to scale existing pandas/NumPy code beyond memory or across clusters. Best for parallel file processing, distributed ML, integration with existing pandas code. For out-of-core analytics on single machine use vaex; for in-memory speed use polars.