Forum Discussion
Bulk Closure of old Incidents via PowerShell
Hi All,
I am trying to close all MS Sentinel incidents via PowerShell using below script.
Get-AzSentinelIncident -WorkspaceName "XXXXXX_XXXXXX" -All | Where-Object {$_.status -eq "New"} | ForEach-Object {update-AzSentinelIncident -WorkspaceName "XXXXXXXXXXXXXXXX" -CaseNumber $_.CaseNumber -Status Closed -CloseReason FalsePositive -ClosedReasonText "Bulk Closure " -Confirm:$false}
This works fine for incidents, triggered in last 48 hr. For older incident (older than 48 hr) it is giving below error.
Update-AzSentinelIncident: Unable to update Incident 7833 with error message Response status code does not indicate success: 500 (Internal Server Error).
Please help me over here, as I need to close over 8k old incidents.
7 Replies
- ITProfessorBrass Contributor
Features
- 🚀 Bulk closure of all open incidents regardless of severity
- ⏱️ Pagination handling for reliable processing of large volumes
- 🔄 Automatic retries for failed operations
- 📊 Detailed reporting with success/failure counts
- ⚙️ Configurable parameters for batch size and delays
<# .SYNOPSIS Bulk closes ALL Microsoft Sentinel incidents (all severities) without manual intervention. .DESCRIPTION Closes all open incidents in batches with automatic retries and proper pagination handling. #> # Configuration $config = @{ ResourceGroupName = "<resource_group_name" WorkspaceName = "<log_analytic_workspace_name>" SubscriptionId = "<subscription_id>" PageSize = 100 # Reduced for better pagination handling RetryAttempts = 2 # Retries per incident DelayBetweenCalls = 2 # Seconds between API calls } # Initialize counters $totalClosed = 0 $failedIncidents = [System.Collections.Generic.List[string]]::new() function Close-AllIncidents { $continue = $true $nextLink = $null while ($continue) { try { # Get incidents with proper pagination handling if ($nextLink) { $incidents = Get-AzSentinelIncident -NextLink $nextLink } else { $incidents = Get-AzSentinelIncident -ResourceGroupName $config.ResourceGroupName ` -WorkspaceName $config.WorkspaceName ` -Filter "properties/status eq 'New'" ` -Top $config.PageSize } if (-not $incidents -or $incidents.Count -eq 0) { $continue = $false break } # Store nextLink for pagination $nextLink = $incidents.NextLink # Process incidents foreach ($incident in $incidents) { $retryCount = 0 $closed = $false while ($retryCount -lt $config.RetryAttempts -and -not $closed) { try { Update-AzSentinelIncident -Id $incident.Name ` -ResourceGroupName $config.ResourceGroupName ` -WorkspaceName $config.WorkspaceName ` -SubscriptionId $config.SubscriptionId ` -Status Closed ` -Confirm:$false ` -Severity $incident.Severity ` -Classification Undetermined ` -Title $incident.Title ` -ErrorAction Stop $script:totalClosed++ $closed = $true Write-Host "Closed incident: $($incident.Name)" -ForegroundColor Green } catch { $retryCount++ if ($retryCount -ge $config.RetryAttempts) { $script:failedIncidents.Add($incident.Name) Write-Host "Failed to close incident: $($incident.Name) - $($_.Exception.Message)" -ForegroundColor Red } Start-Sleep -Milliseconds 500 } } } Write-Host "Processed $($incidents.Count) incidents | Total closed: $totalClosed" # Add delay between API calls Start-Sleep -Seconds $config.DelayBetweenCalls } catch { Write-Host "Error processing batch: $_" -ForegroundColor Red $continue = $false } } } # Main execution Write-Host "Starting bulk incident closure process..." -ForegroundColor Cyan Write-Host "Configuration:" Write-Host "- Page Size: $($config.PageSize)" Write-Host "- Retry Attempts: $($config.RetryAttempts)" Write-Host "- Delay Between Calls: $($config.DelayBetweenCalls)s" Write-Host "" Close-AllIncidents # Results Write-Host @" ============================================ Bulk closure process completed Total incidents closed: $totalClosed Failed to close: $($failedIncidents.Count) ============================================ "@ -ForegroundColor Cyan if ($failedIncidents.Count -gt 0) { Write-Host "Failed incident IDs:" -ForegroundColor Yellow $failedIncidents | ForEach-Object { Write-Host "- $_" } } Write-Host "Process completed at $(Get-Date)" -ForegroundColor Cyan
- Ari_KouhiaCopper Contributor
Hey guys. Thanks pecific147 for your initial starting point and vezgeta for PS frame which I stole with pride.
I took it and polished it and now it takes away, with time, some tens of thousands of alerts.
First, longer has some error maneuvering that is needed if you go beyond 10k.
Latter is to kill just some thousands. Note that you need to change the -Severity Informational to High/Medium/Low/Informational depending which category you are closing.
# Set your parameters once up-front
$rg = "Your_rg_here"
$ws = "Your-workspace-here"
$sub = "yoursubscriptionidgoeshere"Get-AzSentinelIncident -ResourceGroupName "$rg" -WorkspaceName "$ws" |
Where-Object { $_.Status -eq "New" } |
ForEach-Object {
try {
Update-AzSentinelIncident -Id $_.Name -ResourceGroupName "$rg" -WorkspaceName "$ws" -SubscriptionId "$sub" -Status Closed -Confirm:$false -Severity Informational -Classification Undetermined -Title $_.Title
} catch {
Write-Host "Failed to update incident $($_.Name). Skipping." -ForegroundColor Red
}
Start-Sleep -Milliseconds 200
}------------------------------------------------------------
#Get-AzSentinelIncident -ResourceGroupName "$rg" -WorkspaceName "$ws" | Where-Object {$_.Status -eq "New"} | ForEach-Object {Update-AzSentinelIncident -Id $_.Name -ResourceGroupName "$rg" -WorkspaceName "$ws" -SubscriptionId "$sub" -Status Closed -Confirm:$false -Severity Low -Classification Undetermined -Title $_.title}
----------------------------------------------------------------
Even this is late reply I hope this helps someone else.
Gary
- GBusheyIron ContributorLike Rod mentioned, it may be the total amount of rules you are trying to work with that is causing the issue. I have not looked at the code for "Get-AzSentinelIncident" but the REST API only returns 50 items at one time by default. You could call the REST API directly and then use the "nextLink" that gets returned as the "skipToken" for the next call and iterate through your 8K incidents that way. https://learn.microsoft.com/en-us/rest/api/securityinsights/stable/incidents/list?tabs=HTTP
- vezgetaCopper Contributor
GBushey I have closed around 14K of incidents because of misconfigured analytic rule. It took some time and also I have modified the search parametar to close specific incidents with similar name. Just replace YYY with the similar name of incident.
Get-AzSentinelIncident -ResourceGroupName "xxxx" -WorkspaceName "xxxx" | Where-Object {$_.Status -eq "New"} | Where-Object {$_.title -like '*YYY*'} | ForEach-Object {Update-AzSentinelIncident -Id $_.Name -ResourceGroupName "xxxx" -WorkspaceName "xxxx" -SubscriptionId "xxxx" -Status Closed -Confirm:$false -Severity Medium -Classification Undetermined -Title $_.title}
- vezgetaCopper ContributorRun this command to close incidents (replace XXXX with needed information):
Get-AzSentinelIncident -ResourceGroupName "xxxx" -WorkspaceName "xxxx" | Where-Object {$_.Status -eq "New"} | ForEach-Object {Update-AzSentinelIncident -Id $_.Name -ResourceGroupName "xxxx" -WorkspaceName "xxxx" -SubscriptionId "xxxx" -Status Closed -Confirm:$false -Severity Medium -Classification Undetermined -Title $_.title} - Rod_Trent
Microsoft
Hi pecific147
It might be the actual number of Incidents that are the problem versus the time range. Let me do some digging around here to find out.
I understand those Incidents existing in the workspace can be annoying, but they will expire from the workspace based on your retention setting.
- pecific147Copper ContributorHi Rod_Trent,
Did you find anything,?
Workspace retention is 365 days, so waiting for retention to expire won't work.