Search code examples
powershellenumeratewindows-firewall

Why is firewall rule enumeration slow in PowerShell?


I'd like to enumerate my Windows firewall rules, but the run through takes a while...

Measure-Command {

  $FirewallRules = Get-NetFirewallRule |
    where {
      $_.Enabled -eq $true -and
      $_.Direction -eq 'Inbound'
    } | Get-NetFirewallPortFilter

}

TotalSeconds      : 6,3937642

Without getting the actual port filters (Get-NetFirewallPortFilter), the enumeration is only

TotalSeconds      : 0,3220308

Is there a faster way to accomplish this?

Edit: I would prefer if any alternate code works with plain user accounts.


Solution

  • The slowdown is caused by the fact that Get-NetFirewallPortFilter performs a relatively expensive ASSOCIATORS OF WMI query for each firewall rule you pipe to it.

    For any more than a handful of rules you can get a significant performance improvement by simply fetching all port filters up front and then doing the correlation yourself:

    # index all port filters
    $portFilterIndex = @{}
    Get-NetFirewallPortFilter -All |ForEach-Object {
      $portFilterIndex[$_.InstanceID] = $_
    }
    
    # get relevant rules, grab port filter from index
    Get-NetFirewallRule -Direction Inbound |Where-Object Enabled |Select-Object *,@{Name='PortFilter'; Expression = {$portFilterIndex[$_.ID]}}