Search code examples
powershellportfirewall

PowerShell find firewall rule by port


What I want to do

I want to list all firewall rules involving some ports and list their display name but the only way I found for now displays only the port part and has no idea what the display name is.

First the basics

If we call Show-NetFirewallRule without argument, it lists all rules and each is formatted like that (notice DisplayName that is on "root" and LocalPort that is under Get-NetFirewallPortFilter):

Name                          : {96022E5F-666B-4E9E-8BD4-040498CEF1F5}
DisplayName                   : Google Chrome (mDNS-In)
Description                   : Inbound rule for Google Chrome to allow mDNS traffic.
DisplayGroup                  : Google Chrome
Group                         : Google Chrome
Enabled                       : True
Profile                       : Any
Platform                      : 
Direction                     : Inbound
Action                        : Allow
EdgeTraversalPolicy           : Block
LooseSourceMapping            : False
LocalOnlyMapping              : False
Owner                         : 
PrimaryStatus                 : OK
Status                        : The rule was parsed successfully from the store. (65536)
EnforcementStatus             : NotApplicable
PolicyStoreSource             : PersistentStore
PolicyStoreSourceType         : Local
RemoteDynamicKeywordAddresses :

$_ | Get-NetFirewallAddressFilter
     LocalAddress             : Any
     RemoteAddress            : Any

$_ | Get-NetFirewallServiceFilter
     Service                  : Any

$_ | Get-NetFirewallApplicationFilter
     Program                  : C:\Program Files\Google\Chrome\Application\chrome.exe
     Package                  :

$_ | Get-NetFirewallInterfaceFilter
     InterfaceAlias           : Any

$_ | Get-NetFirewallInterfaceTypeFilter
     InterfaceType            : Any

$_ | Get-NetFirewallPortFilter
     Protocol                 : UDP
     LocalPort                : 5353
     RemotePort               : Any
     IcmpType                 : Any
     DynamicTarget            : Any

$_ | Get-NetFirewallSecurityFilter
     Authentication           : NotRequired
     Encryption               : NotRequired
     OverrideBlockRules       : False
     LocalUser                : Any
     RemoteUser               : Any
     RemoteMachine            : Any

What I tried

  • The closer, I think, is
Show-NetFirewallRule  | where {$_.LocalPort -eq "5353" -or $_.LocalPort -eq "5354"}

But it returns only Get-NetFirewallPortFilter part as said above:

$_ | Get-NetFirewallPortFilter
     Protocol                 : UDP
     LocalPort                : 5353
     RemotePort               : Any
     IcmpType                 : Any
     DynamicTarget            : Any

$_ | Get-NetFirewallPortFilter
     Protocol                 : UDP
     LocalPort                : 5353
     RemotePort               : Any
     IcmpType                 : Any
     DynamicTarget            : Any

$_ | Get-NetFirewallPortFilter
     Protocol                 : UDP
     LocalPort                : 5353
     RemotePort               : Any
     IcmpType                 : Any
     DynamicTarget            : Any

On same basis I tried:

Get-NetFirewallRule | where { $_.Get-NetFirewallPortFilter.LocalPort -Eq "5353" }

that displays a parse error, and all

Get-NetFirewallRule | where { $_.NetFirewallPortFilter.LocalPort -Eq "5353" }
Get-NetFirewallRule | where { ($_ | Get-NetFirewallAddressFilter).LocalPort -Eq "5353" }
Get-NetFirewallRule | where { ($_ | Get-NetFirewallAddressFilter).$_.LocalPort -Eq "5353" }

That gives no result.

Get-NetFirewallRule  |
     Format-Table -Property Name,
     DisplayName,
     DisplayGroup,
     @{Name='Protocol';Expression={($PSItem | Get-NetFirewallPortFilter).Protocol}},
     @{Name='LocalPort';Expression={($PSItem | Get-NetFirewallPortFilter).LocalPort}},
     @{Name='RemotePort';Expression={($PSItem | Get-NetFirewallPortFilter).RemotePort}},
     @{Name='RemoteAddress';Expression={($PSItem | Get-NetFirewallAddressFilter).RemoteAddress}} | where {$PSItem.LocalPort -eq "5353"}

But it seems doing nothing, and when I call it without the | where ... it is very slow, displaying approximatively 1 line per second. Note I tried also $_.LocalPort -eq "5353" and $_ -like "5353" in where.

  • I also tried
Get-NetFirewallRule | Get-NetFirewallPortFilter | Where-Object -Property { $_.LocalPort -Eq "5353" }

But is returns nothing (and is also very slow).

Workaround

For now I use a dirty "workaround", I call Show-NetFirewallRule > NetFirewallRule.txt and search manually in file, but I would like to have a script that does this automatically for me (and that is not very slow, since some commands that seems close to the answer are very slow).

The question

Anybody knows if/how can I achieve that ? Thanks !


Solution

  • I believe you want to start with Get-NetFirewallPortFIlter, filter the results, and pass them to Get-NetFirewallRule. That should be much faster than looping on all results of Get-NetFirewallRule and testing each yourself.

    Example (indented for readability, but can be a one-liner, of course):

    Get-NetFirewallPortFilter |
        Where-Object { $_.LocalPort -eq 5353 } |
        Get-NetFirewallRule
    

    Searched 717 rules and an equivalent 717 port filters in 1.2 seconds with 6 results.

    If you'd like to show the port information alongside each rule, something like (this may or might not be optimal, but ...):

    Get-NetFirewallPortFilter |
        Where-Object { $_.LocalPort -eq 5353 } |
        ForEach-Object {
            "----"
            "Rule"
            "----"
            $_ | Get-NetFirewallRule
            "-----------"
            "Port Filter"
            "-----------"
            $_
        }
    

    With the above, you'll still be looping over the filtered results rather than the entire set of rules.