speed up powershell's remove-netfirewallrule

巧了我就是萌 提交于 2021-02-07 10:30:58

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!