Skip to content

Instantly share code, notes, and snippets.

@nero-dv
Created November 6, 2025 10:46
Show Gist options
  • Save nero-dv/6318339ad4621a63de8234a1bec90005 to your computer and use it in GitHub Desktop.
Save nero-dv/6318339ad4621a63de8234a1bec90005 to your computer and use it in GitHub Desktop.
Remove duplicate firewall rules - Windows 10 or higher
Clear-Host
Write-Host "================================================================================================" -ForegroundColor Green
write-Host "`tDuplicate Firewall Rule Remover" -ForegroundColor Green
Write-Host "================================================================================================ `n`n`n" -ForegroundColor Green
Start-Process wf.msc
Start-Sleep -Milliseconds 800
Write-Host "Please export the policy, then close the Windows Firewall management console to continue." -ForegroundColor Red
while (Get-Process -Name "mmc" -ErrorAction SilentlyContinue) {
Start-Sleep -Milliseconds 500
}
clear-host
Write-Host "Continuing script..."
Start-Sleep -Milliseconds 800
clear-host
# Grab all rules via netsh (much faster than Get-NetFirewallRule)
$raw = netsh advfirewall firewall show rule name=all verbose | Out-String
$sections = ($raw -split '(?m)^\s*$') -ne '' # split on blank lines
$rules = foreach ($section in $sections) {
$pairs = [ordered]@{}
foreach ($line in $section -split '\r?\n') {
if ($line -match '^-+$') { continue }
if ($line -match '^(?<key>[^:]+):\s*(?<val>.*)$') {
$key = ($matches['key'] -replace '\s+', '') # normalize key
$val = $matches['val'].Trim()
$pairs[$key] = $val
}
}
[PSCustomObject]$pairs
}
# Hash each rule based on key properties
$keys = 'RuleName', 'Program', 'Action', 'Profiles', 'RemoteIP', 'RemotePort', 'LocalIP', 'LocalPort', 'Enabled', 'Protocol', 'Direction'
$hashTable = @{}
$dupes = @()
foreach ($rule in $rules) {
$keyString = ($keys | ForEach-Object { $rule.$_ }) -join '|'
if ($hashTable.ContainsKey($keyString)) {
$dupes += $rule
}
else {
$hashTable[$keyString] = $true
}
}
# Delete duplicates safely using PowerShell cmdlet (since netsh deletes all with same name)
foreach ($dup in $dupes | Group-Object RuleName) {
$name = $dup.Name
Write-Host "Removing duplicate rules for '$name'..." -ForegroundColor Yellow
Get-NetFirewallRule -DisplayName $name -ErrorAction SilentlyContinue |
Select-Object -Skip 1 |
Remove-NetFirewallRule -ErrorAction SilentlyContinue
}
if ($dupes.Count -eq 0) {
Write-Host "No duplicate firewall rules found." -ForegroundColor Green
}
else {
Write-Host "Removed $($dupes.Count) duplicate firewall rules." -ForegroundColor Green
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment