Workloads/Get-UserUsage.ps1

# Get-UserUsage.ps1
# Collects 30-day active/inactive user activity via the Graph Reports API.
# Part of the M365-QuickAssess module -- not exported.

function Get-UserUsage
{
    param
    (
        $Assessment
    )

    Write-Log "Collecting user activity data (30 days)"

    try
    {
        $userActivity = Get-GraphReportCsv `
            -Uri "https://graph.microsoft.com/v1.0/reports/getOffice365ActiveUserDetail(period='D30')" `
            -ErrorAction Stop

        if ( -not $userActivity -or $userActivity.Count -eq 0 )
        {
            Write-Log "User activity report returned no data" "WARN"
            $Assessment.Users.ActiveUserCount   = $null
            $Assessment.Users.InactiveUserCount = $null
            return
        }

        $reportUserCount  = $userActivity.Count

        $activeUserCount  = ( $userActivity | Where-Object {
            $_."Exchange Last Activity Date"   -or
            $_."OneDrive Last Activity Date"   -or
            $_."SharePoint Last Activity Date" -or
            $_."Teams Last Activity Date"
        } ).Count

        $inactiveUserCount = $reportUserCount - $activeUserCount

        $Assessment.Users.ActiveUserCount   = $activeUserCount
        $Assessment.Users.InactiveUserCount = $inactiveUserCount

        Write-Log "User Activity (30 days): Active=$activeUserCount Inactive=$inactiveUserCount"

        # -------------------------------------------------------------------
        # Finding: High inactive user count
        # -------------------------------------------------------------------
        if ( $reportUserCount -gt 0 )
        {
            $inactivePercent = [math]::Round( ( $inactiveUserCount / $reportUserCount ) * 100, 0 )

            if ( $inactivePercent -ge 30 )
            {
                $Assessment.Findings += New-Finding `
                    -Type           "HighInactiveUserCount" `
                    -Summary        "$inactiveUserCount users have had no activity in the last 30 days ($inactivePercent%)" `
                    -Category       "Licensing" `
                    -Severity       "Medium" `
                    -Impact         "A high number of inactive users may indicate stale accounts consuming licenses unnecessarily." `
                    -Recommendation "Review inactive accounts before migration and remove or deprovision as appropriate."
            }
        }
    }
    catch
    {
        Write-Log "User activity collection failed: $( $_.Exception.Message )" "ERROR"
    }
}