functions/Get-XdrVulnerabilityManagementDashboard.ps1

function Get-XdrVulnerabilityManagementDashboard {
    <#
    .SYNOPSIS
        Retrieves Microsoft Defender Vulnerability Management dashboard analytics data.

    .DESCRIPTION
        Retrieves various analytics data displayed on the TVM dashboard including risk scores,
        secure scores, asset exposure levels, change events, and notification rules.
        This function includes caching support with a 30-minute TTL to reduce API calls.

    .PARAMETER VulnerabilityNotificationRules
        Retrieves metadata for vulnerability notification rules configuration.

    .PARAMETER SecureScoreCategories
        Retrieves secure score breakdown by categories.

    .PARAMETER SecureScoreTotal
        Retrieves the total secure score for the organization.

    .PARAMETER RiskScore
        Retrieves the organization's risk score from TVM analytics.

    .PARAMETER AssetsCountByExposureLevel
        Retrieves count of assets grouped by their exposure level.

    .PARAMETER AssetsTopVulnerable
        Retrieves the top most vulnerable assets in the environment.

    .PARAMETER ChangeEventsVaTopPerDay
        Retrieves top vulnerability assessment (VA) change events per day.

    .PARAMETER ChangeEventsScaTopPerDay
        Retrieves top software composition analysis (SCA) change events per day.

    .PARAMETER Force
        Bypasses the cache and forces a fresh retrieval from the API.

    .EXAMPLE
        Get-XdrVulnerabilityManagementDashboard -RiskScore
        Retrieves the organization's current risk score.

    .EXAMPLE
        Get-XdrVulnerabilityManagementDashboard -SecureScoreTotal
        Retrieves the organization's total secure score.

    .EXAMPLE
        Get-XdrVulnerabilityManagementDashboard -SecureScoreCategories
        Retrieves secure score broken down by security categories.

    .EXAMPLE
        Get-XdrVulnerabilityManagementDashboard -AssetsCountByExposureLevel
        Retrieves count of assets at each exposure level (None, Low, Medium, High, Critical).

    .EXAMPLE
        Get-XdrVulnerabilityManagementDashboard -AssetsTopVulnerable
        Retrieves the most vulnerable assets in your environment.

    .EXAMPLE
        Get-XdrVulnerabilityManagementDashboard -ChangeEventsVaTopPerDay
        Retrieves top vulnerability changes per day (new vulnerabilities discovered).

    .EXAMPLE
        Get-XdrVulnerabilityManagementDashboard -VulnerabilityNotificationRules
        Retrieves vulnerability notification rules metadata.

    .OUTPUTS
        System.Management.Automation.PSCustomObject
        Returns dashboard analytics data. Output structure varies based on the parameter used.

    .OUTPUTS
        System.Object[]
        For parameters returning collections (e.g., -SecureScoreCategories, -AssetsTopVulnerable).
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Switch parameters are used via $PSCmdlet.ParameterSetName')]
    [CmdletBinding(DefaultParameterSetName = 'RiskScore')]
    [OutputType([System.Management.Automation.PSCustomObject])]
    [OutputType([System.Object[]])]
    param (
        [Parameter(ParameterSetName = 'VulnerabilityNotificationRules')]
        [switch]$VulnerabilityNotificationRules,

        [Parameter(ParameterSetName = 'SecureScoreCategories')]
        [switch]$SecureScoreCategories,

        [Parameter(ParameterSetName = 'SecureScoreTotal')]
        [switch]$SecureScoreTotal,

        [Parameter(ParameterSetName = 'RiskScore')]
        [switch]$RiskScore,

        [Parameter(ParameterSetName = 'AssetsCountByExposureLevel')]
        [switch]$AssetsCountByExposureLevel,

        [Parameter(ParameterSetName = 'AssetsTopVulnerable')]
        [switch]$AssetsTopVulnerable,

        [Parameter(ParameterSetName = 'ChangeEventsVaTopPerDay')]
        [switch]$ChangeEventsVaTopPerDay,

        [Parameter(ParameterSetName = 'ChangeEventsScaTopPerDay')]
        [switch]$ChangeEventsScaTopPerDay,

        [Parameter()]
        [switch]$Force
    )

    begin {
        Update-XdrConnectionSettings

        # Prepare TVM headers
        $tvmHeaders = $script:headers.Clone()
        $tvmHeaders["api-version"] = "1.0"
    }

    process {
        # Define endpoint configuration based on parameter set
        $config = switch ($PSCmdlet.ParameterSetName) {
            'VulnerabilityNotificationRules' {
                @{
                    CacheKey = "XdrVulnerabilityManagementDashboard_VulnerabilityNotificationRules"
                    Endpoint = "https://security.microsoft.com/apiproxy/mtp/tvm/orgsettings/vulnerability-notification-rules/metadata"
                }
            }
            'SecureScoreCategories' {
                @{
                    CacheKey = "XdrVulnerabilityManagementDashboard_SecureScoreCategories"
                    Endpoint = "https://security.microsoft.com/apiproxy/mtp/tvm/analytics/configurations/securescore/categories"
                }
            }
            'SecureScoreTotal' {
                @{
                    CacheKey = "XdrVulnerabilityManagementDashboard_SecureScoreTotal"
                    Endpoint = "https://security.microsoft.com/apiproxy/mtp/tvm/analytics/configurations/securescore/total"
                }
            }
            'RiskScore' {
                @{
                    CacheKey = "XdrVulnerabilityManagementDashboard_RiskScore"
                    Endpoint = "https://security.microsoft.com/apiproxy/mtp/tvm/analytics/riskscore"
                }
            }
            'AssetsCountByExposureLevel' {
                @{
                    CacheKey = "XdrVulnerabilityManagementDashboard_AssetsCountByExposureLevel"
                    Endpoint = "https://security.microsoft.com/apiproxy/mtp/tvm/analytics/assets/countByExposureLevel"
                }
            }
            'AssetsTopVulnerable' {
                @{
                    CacheKey = "XdrVulnerabilityManagementDashboard_AssetsTopVulnerable"
                    Endpoint = "https://security.microsoft.com/apiproxy/mtp/tvm/analytics/assets/topVulnerable"
                }
            }
            'ChangeEventsVaTopPerDay' {
                $daysAgo = (Get-Date).AddDays(-30).ToString("yyyy-MM-ddT00:00:00.000Z")
                @{
                    CacheKey = "XdrVulnerabilityManagementDashboard_ChangeEventsVaTopPerDay"
                    Endpoint = "https://security.microsoft.com/apiproxy/mtp/tvm/analytics/changeEvents/va/topPerDay?`$filter=(date+ge+$daysAgo)"
                }
            }
            'ChangeEventsScaTopPerDay' {
                $daysAgo = (Get-Date).AddDays(-30).ToString("yyyy-MM-ddT00:00:00.000Z")
                @{
                    CacheKey = "XdrVulnerabilityManagementDashboard_ChangeEventsScaTopPerDay"
                    Endpoint = "https://security.microsoft.com/apiproxy/mtp/tvm/analytics/changeEvents/sca/topPerDay?`$filter=(date+ge+$daysAgo)"
                }
            }
        }

        # Check cache
        $currentCacheValue = Get-XdrCache -CacheKey $config.CacheKey -ErrorAction SilentlyContinue
        if (-not $Force -and $currentCacheValue.NotValidAfter -gt (Get-Date)) {
            Write-Verbose "Using cached $($PSCmdlet.ParameterSetName) data"
            return $currentCacheValue.Value
        }

        if ($Force) {
            Write-Verbose "Force parameter specified, bypassing cache"
            Clear-XdrCache -CacheKey $config.CacheKey
        } else {
            Write-Verbose "Cache for $($PSCmdlet.ParameterSetName) is missing or expired"
        }

        try {
            Write-Verbose "Retrieving $($PSCmdlet.ParameterSetName) data from: $($config.Endpoint)"
            $result = Invoke-RestMethod -Uri $config.Endpoint -Method Get -ContentType "application/json" -WebSession $script:session -Headers $tvmHeaders

            # Handle null/empty results gracefully
            if ($null -eq $result) { $result = @{} }
            Set-XdrCache -CacheKey $config.CacheKey -Value $result -TTLMinutes 30
            return $result
        } catch {
            Write-Error "Failed to retrieve dashboard data: $_"
        }
    }

    end {
    }
}