Workloads/Get-LicenseData.ps1

# Get-LicenseData.ps1
# Collects SKU summary and licensed/unlicensed user counts.
# Part of the M365-QuickAssess module -- not exported.

function Get-LicenseData
{
    param
    (
        $Assessment
    )

    Write-Log "Collecting license data"

    try
    {
        $skus = Get-MgSubscribedSku -All -ErrorAction Stop

        # -------------------------------------------------------------------
        # SKUs to ignore -- free / viral / noise licenses
        # -------------------------------------------------------------------
        $skusToIgnore = @(
            "FLOW_FREE",
            "WINDOWS_STORE",
            "POWER_BI_STANDARD",
            "POWERAPPS_VIRAL",
            "Power_Pages_vTrial_for_Makers",
            "STREAM",
            "POWERAPPS_DEV",
            "CCIBOTS_PRIVPREV_VIRAL"
        )

        $skuSummary = @()

        foreach ( $sku in $skus | Where-Object { $_.SkuPartNumber -notin $skusToIgnore } )
        {
            $enabled   = $sku.PrepaidUnits.Enabled
            $consumed  = $sku.ConsumedUnits
            $available = $enabled - $consumed

            $skuSummary += @{
                SkuPartNumber = $sku.SkuPartNumber
                SkuId         = $sku.SkuId
                Enabled       = $enabled
                Consumed      = $consumed
                Available     = $available
            }
        }

        # -------------------------------------------------------------------
        # Licensed vs Unlicensed Users
        # -------------------------------------------------------------------
        $users           = Get-MgUser -All -Property AssignedLicenses -ErrorAction Stop
        $licensedUsers   = ( $users | Where-Object { $_.AssignedLicenses.Count -gt 0 } ).Count
        $unlicensedUsers = ( $users | Where-Object { $_.AssignedLicenses.Count -eq 0 } ).Count

        # -------------------------------------------------------------------
        # Populate Schema
        # -------------------------------------------------------------------
        $Assessment.Licensing.SkuSummary         = $skuSummary
        $Assessment.Licensing.TotalLicensedUsers = $licensedUsers
        $Assessment.Licensing.UnlicensedUsers    = $unlicensedUsers

        Write-Log "Licensing: SKUs=$( $skuSummary.Count ) Licensed=$licensedUsers Unlicensed=$unlicensedUsers"

        # -------------------------------------------------------------------
        # Finding: High unlicensed user count
        # -------------------------------------------------------------------
        if ( $unlicensedUsers -gt 0 )
        {
            $totalUsers = $licensedUsers + $unlicensedUsers
            $percent    = [math]::Round( ( $unlicensedUsers / $totalUsers ) * 100, 0 )

            if ( $percent -ge 20 )
            {
                $Assessment.Findings += New-Finding `
                    -Type           "HighUnlicensedUserCount" `
                    -Summary        "$unlicensedUsers unlicensed users detected ($percent% of tenant)" `
                    -Category       "Licensing" `
                    -Severity       "Medium" `
                    -Impact         "Unlicensed users may indicate stale accounts that should be reviewed before migration." `
                    -Recommendation "Review unlicensed accounts and remove or assign licenses as appropriate."
            }
        }
    }
    catch
    {
        Write-Log "License data collection failed: $( $_.Exception.Message )" "ERROR"
    }
}