functions/Get-XdrVulnerabilityManagementRemediationTasks.ps1

function Get-XdrVulnerabilityManagementRemediationTasks {
    <#
    .SYNOPSIS
        Retrieves remediation tasks from Vulnerability Management.

    .DESCRIPTION
        Gets remediation task information from the Threat and Vulnerability Management (TVM) in Microsoft Defender XDR.
        This includes remediation tasks, exceptions, and blocked applications.
        This function includes caching support with a 30-minute TTL to reduce API calls.

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

    .PARAMETER PreRemediation
        Retrieves pre-remediation information. This is a POST endpoint.

    .PARAMETER RecommendationExceptions
        Retrieves recommendation exceptions.

    .PARAMETER AllExceptions
        Retrieves all exceptions (non-aggregated).

    .PARAMETER AllExceptionsAggregated
        Retrieves aggregated exceptions data.

    .PARAMETER BlockedApplications
        Retrieves blocked applications list.

    .PARAMETER BlockedApplicationsCount
        Retrieves count of blocked applications.

    .PARAMETER BaselineExceptions
        Retrieves baseline exceptions from organization settings.

    .PARAMETER Body
        Request body for PreRemediation endpoint (POST request).

    .EXAMPLE
        Get-XdrVulnerabilityManagementRemediationTasks
        Retrieves all remediation tasks using cached data if available.

    .EXAMPLE
        Get-XdrVulnerabilityManagementRemediationTasks -Force
        Forces a fresh retrieval of remediation tasks, bypassing the cache.

    .EXAMPLE
        Get-XdrVulnerabilityManagementRemediationTasks -AllExceptionsAggregated
        Retrieves aggregated exceptions data.

    .EXAMPLE
        Get-XdrVulnerabilityManagementRemediationTasks -BlockedApplications
        Retrieves list of blocked applications.

    .EXAMPLE
        $body = @{
            groups = @()
            modelName = "PreRemediationRequestBodyModel"
            preRemediationArgs = @{
                category = "SecurityConfiguration"
                modelName = "PreRemediationArgsModel"
                preRemediationSecurityConfigurationArgs = @{
                    modelName = "PreRemediationSecurityConfigurationArgsModel"
                    scid = "scid-79"
                    taskType = "ConfigurationChange"
                }
            }
            relatedComponent = "deviceMisconfiguration"
        }
        Get-XdrVulnerabilityManagementRemediationTasks -PreRemediation -Body $body
        Submits a pre-remediation request with the specified body.

    .OUTPUTS
        System.Object[]
        Returns an array of remediation task objects from TVM.

    .OUTPUTS
        System.Int64
        When -BlockedApplicationsCount is specified, returns the count as an integer.

    .OUTPUTS
        System.Management.Automation.PSCustomObject
        For certain endpoints, returns a summary object.
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'RemediationTasks matches the API endpoint naming convention')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Switch parameters are used via $PSCmdlet.ParameterSetName')]
    [CmdletBinding(DefaultParameterSetName = 'Default')]
    [OutputType([System.Object[]])]
    [OutputType([System.Int64], ParameterSetName = 'BlockedApplicationsCount')]
    [OutputType([System.Management.Automation.PSCustomObject], ParameterSetName = 'PreRemediation')]
    [OutputType([System.Management.Automation.PSCustomObject], ParameterSetName = 'AllExceptionsAggregated')]
    param (
        [Parameter()]
        [switch]$Force,

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

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

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

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

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

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

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

        [Parameter(ParameterSetName = 'PreRemediation', Mandatory = $true)]
        [object]$Body
    )

    begin {
        Update-XdrConnectionSettings

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

    process {
        # Configuration for each parameter set
        $config = switch ($PSCmdlet.ParameterSetName) {
            'PreRemediation' {
                @{
                    CacheKey    = "XdrVulnerabilityManagementRemediationTasks_PreRemediation"
                    Endpoint    = "/apiproxy/mtp/tvm/remediation-tasks/remediationTasks/preRemediation"
                    DisplayName = "pre-remediation data"
                    Method      = "Post"
                }
            }
            'RecommendationExceptions' {
                @{
                    CacheKey    = "XdrVulnerabilityManagementRemediationTasks_RecommendationExceptions"
                    Endpoint    = "/apiproxy/mtp/tvm/remediation-tasks/recommendationExceptions"
                    DisplayName = "recommendation exceptions"
                    Method      = "Get"
                }
            }
            'AllExceptions' {
                @{
                    CacheKey    = "XdrVulnerabilityManagementRemediationTasks_AllExceptions"
                    Endpoint    = "/apiproxy/mtp/tvm/remediation-tasks/allExceptions"
                    DisplayName = "all exceptions"
                    Method      = "Get"
                }
            }
            'AllExceptionsAggregated' {
                @{
                    CacheKey    = "XdrVulnerabilityManagementRemediationTasks_AllExceptionsAggregated"
                    Endpoint    = "/apiproxy/mtp/tvm/remediation-tasks/allExceptions/aggregated"
                    DisplayName = "aggregated exceptions"
                    Method      = "Get"
                }
            }
            'BlockedApplications' {
                @{
                    CacheKey    = "XdrVulnerabilityManagementRemediationTasks_BlockedApplications"
                    Endpoint    = "/apiproxy/mtp/tvm/remediation-tasks/blockedApplications"
                    DisplayName = "blocked applications"
                    Method      = "Get"
                }
            }
            'BlockedApplicationsCount' {
                @{
                    CacheKey    = "XdrVulnerabilityManagementRemediationTasks_BlockedApplicationsCount"
                    Endpoint    = "/apiproxy/mtp/tvm/remediation-tasks/blockedApplications/count"
                    DisplayName = "blocked applications count"
                    Method      = "Get"
                }
            }
            'BaselineExceptions' {
                @{
                    CacheKey    = "XdrVulnerabilityManagementRemediationTasks_BaselineExceptions"
                    Endpoint    = "/apiproxy/mtp/tvm/remediation-tasks/baselineExceptions/getOrgExceptions"
                    DisplayName = "baseline exceptions"
                    Method      = "Get"
                }
            }
            default {
                @{
                    CacheKey    = "XdrVulnerabilityManagementRemediationTasks"
                    Endpoint    = "/apiproxy/mtp/tvm/remediation-tasks/remediationTasks"
                    DisplayName = "remediation tasks"
                    Method      = "Get"
                }
            }
        }

        # Check cache
        $currentCacheValue = Get-XdrCache -CacheKey $config.CacheKey -ErrorAction SilentlyContinue
        if (-not $Force -and $currentCacheValue.NotValidAfter -gt (Get-Date)) {
            Write-Verbose "Using cached $($config.DisplayName)"
            return $currentCacheValue.Value
        } elseif ($Force) {
            Write-Verbose "Force parameter specified, bypassing cache"
            Clear-XdrCache -CacheKey $config.CacheKey
        }

        $Uri = "https://security.microsoft.com$($config.Endpoint)"
        Write-Verbose "Retrieving $($config.DisplayName) from $Uri"

        try {
            if ($config.Method -eq "Post") {
                $result = Invoke-RestMethod -Uri $Uri -Method Post -ContentType "application/json" -Body ($Body | ConvertTo-Json -Depth 10) -WebSession $script:session -Headers $tvmHeaders
            } else {
                $result = Invoke-RestMethod -Uri $Uri -Method Get -ContentType "application/json" -WebSession $script:session -Headers $tvmHeaders
            }

            # Handle null or empty results gracefully
            if ($null -eq $result -or ($result -is [array] -and $result.Count -eq 0)) {
                Write-Verbose "No $($config.DisplayName) found"
                return
            }

            Set-XdrCache -CacheKey $config.CacheKey -Value $result -TTLMinutes 30
            return $result
        } catch {
            Write-Error "Failed to retrieve $($config.DisplayName): $_"
        }
    }

    end {

    }
}