Public/Get-TCMQuota.ps1

function Get-TCMQuota {
    <#
    .SYNOPSIS
        Show current TCM API quota usage across monitors and snapshots.
    .DESCRIPTION
        Calculates and displays resource usage against TCM limits:
        - 30 monitors max
        - 800 monitored resources/day
        - 20,000 snapshot resources/month
        - 12 visible snapshot jobs
    .PARAMETER PassThru
        Return the quota data as an object (for scripting). Without this, only the dashboard is shown.
    .EXAMPLE
        Get-TCMQuota
    .EXAMPLE
        $quota = Get-TCMQuota -PassThru
    #>

    [CmdletBinding()]
    param(
        [switch]$PassThru
    )

    Write-Host 'Calculating TCM quota usage...' -ForegroundColor Cyan

    # Get monitors
    $monitors = Invoke-TCMGraphRequest -Endpoint 'configurationMonitors' -All
    if (-not $monitors) { $monitors = @() }

    # Calculate daily resource cost from monitors
    # Each monitor runs 4x/day; cost = resources * 4
    $dailyResourceUsage = 0
    $monitorDetails = foreach ($m in $monitors) {
        # Handle both hashtable and PSObject property access
        $monId   = if ($m -is [System.Collections.IDictionary]) { $m['id'] } else { $m.id }
        $monName = if ($m -is [System.Collections.IDictionary]) { $m['displayName'] } else { $m.displayName }
        $monStat = if ($m -is [System.Collections.IDictionary]) { $m['status'] } else { $m.status }

        if (-not $monId) {
            Write-Verbose "Skipping monitor with no ID: $($m | ConvertTo-Json -Depth 2 -Compress)"
            continue
        }

        $baseline = $null
        $resourceCount = 0
        try {
            $baseline = Invoke-TCMGraphRequest -Endpoint "configurationMonitors/$monId/baseline"
            if ($baseline.resources) {
                $resourceCount = ($baseline.resources | Measure-Object).Count
            }
        }
        catch {
            Write-Verbose "Could not retrieve baseline for monitor $monId"
        }

        $dailyCost = $resourceCount * 4
        $dailyResourceUsage += $dailyCost

        [PSCustomObject]@{
            MonitorName    = $monName
            MonitorId      = $monId
            Status         = $monStat
            Resources      = $resourceCount
            DailyQuotaCost = $dailyCost
        }
    }

    # Get snapshot jobs
    $snapshots = Invoke-TCMGraphRequest -Endpoint 'configurationSnapshotJobs' -All
    if (-not $snapshots) { $snapshots = @() }

    $snapshotResourceCount = ($snapshots | ForEach-Object {
        ($_.resources | Measure-Object).Count
    } | Measure-Object -Sum).Sum

    # Output
    Write-Host ''
    Write-Host '=== TCM Quota Dashboard ===' -ForegroundColor Yellow
    Write-Host ''

    # Monitors
    $monitorCount = @($monitors).Count
    $monitorPct = [math]::Round(($monitorCount / 30) * 100, 1)
    $monitorColor = if ($monitorPct -ge 80) { 'Red' } elseif ($monitorPct -ge 50) { 'Yellow' } else { 'Green' }
    Write-Host " Monitors: $monitorCount / 30 ($monitorPct%)" -ForegroundColor $monitorColor

    # Daily resources
    $dailyPct = [math]::Round(($dailyResourceUsage / 800) * 100, 1)
    $dailyColor = if ($dailyPct -ge 80) { 'Red' } elseif ($dailyPct -ge 50) { 'Yellow' } else { 'Green' }
    Write-Host " Daily Resources: $dailyResourceUsage / 800 ($dailyPct%)" -ForegroundColor $dailyColor

    # Snapshot jobs
    $snapJobCount = @($snapshots).Count
    $snapJobPct = [math]::Round(($snapJobCount / 12) * 100, 1)
    $snapJobColor = if ($snapJobPct -ge 80) { 'Red' } elseif ($snapJobPct -ge 50) { 'Yellow' } else { 'Green' }
    Write-Host " Snapshot Jobs: $snapJobCount / 12 ($snapJobPct%)" -ForegroundColor $snapJobColor

    # Monthly snapshot resources (approximate — we can only see current jobs)
    Write-Host " Snapshot Resources: ~$snapshotResourceCount / 20,000 (visible jobs only)" -ForegroundColor DarkGray

    Write-Host ''

    if ($monitorDetails) {
        Write-Host ' Monitor Breakdown:' -ForegroundColor DarkGray
        $monitorDetails | Format-Table -AutoSize | Out-String | Write-Host -ForegroundColor DarkGray
    }

    if ($PassThru) {
        [PSCustomObject]@{
            MonitorCount         = $monitorCount
            MonitorLimit         = 30
            DailyResourceUsage   = $dailyResourceUsage
            DailyResourceLimit   = 800
            SnapshotJobCount     = $snapJobCount
            SnapshotJobLimit     = 12
            SnapshotResources    = $snapshotResourceCount
            MonthlySnapshotLimit = 20000
            Monitors             = $monitorDetails
        }
    }
}