All scripts
Microsoft 365 168

Get-M365LicenseUsageReport

Pulls every license SKU in the tenant and shows assigned versus available seats, so you can spot licenses worth reclaiming before the next renewal.

Get-M365LicenseUsageReport.ps1
<#
.SYNOPSIS
    Get-M365LicenseUsageReport.ps1 - Reports assigned vs. available Microsoft 365 licenses.

.DESCRIPTION
    Pulls every license SKU in the tenant via Microsoft Graph and shows how many
    seats are consumed versus purchased, so you can spot SKUs worth reclaiming
    before the next renewal. Requires Graph scope: Organization.Read.All

.AUTHOR
    Shehryar Hassan

.EXAMPLE
    .\Get-M365LicenseUsageReport.ps1 -OutputPath ".\LicenseReport.csv"
#>

param(
    [Parameter(Mandatory=$false)]
    [string]$OutputPath = ".\LicenseReport.csv"
)

Write-Host "=============================================" -ForegroundColor Cyan
Write-Host "  Microsoft 365 License Usage Report" -ForegroundColor Cyan
Write-Host "=============================================" -ForegroundColor Cyan

if (-not (Get-MgContext)) {
    Write-Host "[INFO] Connecting to Microsoft Graph..." -ForegroundColor Yellow
    Connect-MgGraph -Scopes "Organization.Read.All"
}

$skus = Get-MgSubscribedSku -All

$report = foreach ($sku in $skus) {
    $total = $sku.PrepaidUnits.Enabled
    $used = $sku.ConsumedUnits
    $free = $total - $used
    $percentUsed = if ($total -gt 0) { [math]::Round(($used / $total) * 100, 1) } else { 0 }

    [PSCustomObject]@{
        SkuPartNumber = $sku.SkuPartNumber
        Total         = $total
        Consumed      = $used
        Available     = $free
        PercentUsed   = $percentUsed
    }
}

$report | Sort-Object PercentUsed | Export-Csv -Path $OutputPath -NoTypeInformation

Write-Host "[SUCCESS] Report exported to: $OutputPath" -ForegroundColor Green
$underused = $report | Where-Object { $_.Total -gt 0 -and $_.PercentUsed -lt 50 }
if ($underused) {
    Write-Host "[INFO] SKUs under 50% utilization, worth a second look before renewal:" -ForegroundColor Yellow
    $underused | Format-Table SkuPartNumber, Total, Consumed, PercentUsed -AutoSize
}

Read it before you run it, and test in a safe tenant first.