问题
I need to remove a lot of metro app related firewall rules in Windows 10 with powershell. It seems very slow compared to netsh or regedit. Anyway to speed it up?
# clean firewall rules, deleting profile doesn't get rid of them
# string (sid) 45 in length, no existing profiles
# 9000 rules take about 90 minutes to delete
$profiles = get-wmiobject -class win32_userprofile
# I'm only dumping to a file to convert pscustomobject to string for sort
get-netfirewallrule -all | select-object -property owner > out
$list = get-content out | sort-object | get-unique | where-object { $_.trim().length -eq 45 -and $profiles.sid -notcontains $_ }
foreach($i in $list) {$i
remove-netfirewallrule -owner $i}
# about 65 rules per user here
echo ConfigurableServiceStore
get-netfirewallrule -all -policystore configurableservicestore | select-object -property owner > out
$list = get-content out | sort-object | get-unique | where-object { $_.trim().length -eq 45 -and $profiles.sid -notcontains $_ }
foreach($i in $list) {$i
remove-netfirewallrule -policystore configurableservicestore -owner $i}
回答1:
EDIT: I've updated Select-Object -Property Owner
to Select-Object -ExpandProperty Owner
this way $_
contains only the Owner property:
$SID = (get-wmiobject -class win32_userprofile).SID
Write-Host "Getting Firewall Rules"
$Rules = Get-NetFirewallRule -All | Select-Object -ExpandProperty Owner -Unique | Where-Object { $SID -notcontains $_ }
Write-Host "Getting Firewall Rules from ConfigurableServiceStore Store"
$ConfigurableServiceStore = Get-NetFirewallRule -All -PolicyStore ConfigurableServiceStore | Select-Object -ExpandProperty Owner -Unique | Where-Object { $SID -notcontains $_ }
Write-Host "Deleting Firewall Rules:" -ForegroundColor Green
foreach($Owner in $Rules) {
Write-Host "Deleting Rules with Owner: $Owner"
Remove-NetFirewallRule -Owner $Owner
}
Write-Host "Deleting Firewall Rules from ConfigurableServiceStore Store:" -ForegroundColor Green
foreach($Rule in $ConfigurableServiceStore) {
Write-Host "Deleting Rules with Owner: $Owner"
Remove-NetFirewallRule -PolicyStore ConfigurableServiceStore -Owner $Owner
}
回答2:
Thanks for your help. But remove-netfirewallrule is just impractical (slowww) in this case. To me the only solution is to use remove-itemproperty (registry) instead. Here's the current script I'm using. I went a little crazy with the progress bar. The difference is one hour vs days. I could be deleting 10,000 - 100,000 firewall rules!
EDIT: In newest versions of Windows 10 "HKLM:\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\Configurable\System" has been changed to: "HKLM:\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\AppIso\FirewallRules" and cannot be retrieved by get-netfirewallrule.
EDIT2: If that AppIso registry entry gets too big, the search and start menu break.
$profiles = get-wmiobject -class win32_userprofile
Write-Host "Getting Firewall Rules"
# deleting rules with no owner would be disastrous
$Rules = Get-NetFirewallRule -All |
Where-Object {$profiles.sid -notcontains $_.owner -and $_.owner }
Write-Host "Getting Firewall Rules from ConfigurableServiceStore Store"
$rules2 = Get-NetFirewallRule -All -PolicyStore ConfigurableServiceStore |
Where-Object { $profiles.sid -notcontains $_.owner -and $_.owner }
$total = $rules.count + $rules2.count
Write-Host "Deleting" $total "Firewall Rules:" -ForegroundColor Green
$result = measure-command {
# tracking
$start = Get-Date; $i = 0.0 ;
# $total = $rules.Count
foreach($rule in $rules){
# action
remove-itemproperty -path "HKLM:\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules" -name $rule.name
# progress
$i = $i + 1.0
$prct = $i / $total * 100.0
$elapsed = (Get-Date) - $start;
$totaltime = ($elapsed.TotalSeconds) / ($prct / 100.0)
$remain = $totaltime - $elapsed.TotalSeconds
$eta = (Get-Date).AddSeconds($remain)
# display
$prctnice = [math]::round($prct,2)
$elapsednice = $([string]::Format("{0:d2}:{1:d2}:{2:d2}", $elapsed.hours, $elapsed.minutes, $elapsed.seconds))
$speed = $i/$elapsed.totalminutes
$speednice = [math]::round($speed,2)
Write-Progress -Activity "Deleting rules ETA $eta elapsed $elapsednice loops/min $speednice" -Status "$prctnice" -PercentComplete $prct -secondsremaining $remain
}
# tracking
# $start = Get-Date; $i = 0 ; $total = $rules2.Count
foreach($rule2 in $rules2) {
# action
remove-itemproperty -path "HKLM:\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\Configurable\System" -name $rule2.name
# progress
$i = $i + 1.0
$prct = $i / $total * 100.0
$elapse = (Get-Date) - $start;
$totaltime = ($elapsed.TotalSeconds) / ($prct / 100.0)
$remain = $totaltime - $elapsed.TotalSeconds
$eta = (Get-Date).AddSeconds($remain)
# display
$prctnice = [math]::round($prct,2)
$elapsednice = $([string]::Format("{0:d2}:{1:d2}:{2:d2}", $elapsed.hours, $elapsed.minutes, $elapsed.seconds))
$speed = $i/$elapsed.totalminutes
$speednice = [math]::round($speed,2)
Write-Progress -Activity "Deleting rules2 ETA $eta elapsed $elapsednice loops/min $speednice" -Status "$prctnice" -PercentComplete $prct -secondsremaining $remain
}
}
$end = get-date
write-host end $end
write-host eta $eta
write-host $result.minutes min $result.seconds sec
回答3:
If there are too many firewall rules for rule#2 to take care of, you get out of storage errors on server 2016.
Deleting the registry keys first and using this script for maintenance after the fact would fix it.
来源:https://stackoverflow.com/questions/40620634/speed-up-powershells-remove-netfirewallrule