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 { } } |