Public/Remove-CustomDetection.ps1
|
function Remove-CustomDetection { <# .SYNOPSIS Deletes a custom detection rule from Microsoft Defender XDR. .DESCRIPTION Removes a detection rule via the Microsoft Graph API. The rule can be identified by its detection rule Id, by the guid from the source file (matched against the rule Id and then the description tag), or by the DescriptionTag UUID that was appended to the alert description during deployment. Only one identification method may be used per call (parameter sets). .PARAMETER Id The detection rule ID as returned by the Graph API. .PARAMETER DetectorId The guid from the source file. Resolved to the rule ID via Get-CustomDetectionIdByDetectorId, which matches the rule ID with or without the rule prefix, the detector ID the API assigned and then the description tag. When the list does not carry the rule or does not answer, the client id rule-<guid> is asked for directly. .PARAMETER DescriptionTag The UUID tag embedded in the alert description. Resolved to the rule ID via Get-CustomDetectionIdByDescriptionTag. .EXAMPLE Remove-CustomDetection -Id "12345" Deletes the detection rule with the specified ID. .EXAMPLE Remove-CustomDetection -DetectorId "81fb771a-c57e-41b8-9905-63dbf267c13f" Looks up and deletes the detection rule the guid names. .EXAMPLE Remove-CustomDetection -DescriptionTag "81fb771a-c57e-41b8-9905-63dbf267c13f" Looks up and deletes the detection rule whose description contains the specified UUID tag. .NOTES Requires the Microsoft.Graph.Authentication module and an active Graph API session. Use Connect-MgGraph before calling this function. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ById')] [ValidateNotNullOrEmpty()] [string]$Id, [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByDetectorId')] [ValidateNotNullOrEmpty()] [string]$DetectorId, [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByDescriptionTag')] [ValidateNotNullOrEmpty()] [string]$DescriptionTag ) begin { Assert-MgGraphConnection $baseUri = 'https://graph.microsoft.com/beta/security/rules/detectionRules' } process { try { #region Resolve the detection rule ID $ruleId = $null switch ($PSCmdlet.ParameterSetName) { 'ById' { $ruleId = $Id } 'ByDetectorId' { # The list can omit a rule for a long time after a delete and recreate, and it holds off after a timeout. The client id answers in both cases try { $ruleId = Get-CustomDetectionIdByDetectorId -DetectorId $DetectorId -ErrorAction SilentlyContinue } catch { if (-not (Test-CustomDetectionListFailure -ErrorRecord $_)) { throw } Write-Warning "The rule list did not answer. The rule is looked up by its client id only." } if (-not $ruleId) { $ruleId = (Get-CustomDetectionByClientId -Guid $DetectorId).id } if (-not $ruleId) { Write-Error "No detection rule found with DetectorId: $DetectorId" return } } 'ByDescriptionTag' { try { $ruleId = Get-CustomDetectionIdByDescriptionTag -DescriptionTag $DescriptionTag -ErrorAction SilentlyContinue } catch { if (-not (Test-CustomDetectionListFailure -ErrorRecord $_)) { throw } Write-Warning "The rule list did not answer. The rule is looked up by its client id only." } if (-not $ruleId) { $ruleId = (Get-CustomDetectionByClientId -Guid $DescriptionTag).id } if (-not $ruleId) { Write-Error "No detection rule found with DescriptionTag: $DescriptionTag" return } } } #endregion #region Fetch the rule to get its display name for confirmation $rule = Get-CustomDetection -DetectionId $ruleId if (-not $rule) { Write-Error "Detection rule with Id '$ruleId' not found." return } $ruleName = $rule.displayName #endregion #region Delete the rule if ($PSCmdlet.ShouldProcess("Rule '$ruleName' (Id: $ruleId)", 'Delete detection rule')) { $uri = "$baseUri/$ruleId" Invoke-MgGraphRequestWithRetry -Method DELETE -Uri $uri | Out-Null Clear-CustomDetectionIdsCacheEntry -Id $ruleId Write-Verbose "Deleted rule '$ruleName' (Id: $ruleId)." [PSCustomObject]@{ Action = 'Deleted' RuleName = $ruleName RuleId = $ruleId } } #endregion } catch { Write-Error "Error deleting detection rule: $($_.Exception.Message)" throw } } } |