Why doesn't Get-NetFirewallRule show all information of the firewall rule? (like netsh)
Asked Answered
H

5

5

I'm trying to find if a firewall rule already existing, with the same name, same configuration, like: localport.

So I use Get-NetFirewallRule to list all rules, but the rules returned do not contain the information of port, also some other information are missing. where can I find all the config of a rule. Below is the attributess returned:

Name
DisplayName
Description
DisplayGroup
Group
Enabled
Profile
Platform
Direction
Action
EdgeTraversalPolicy
LooseSourceMapping
LocalOnlyMapping
Owner
PrimaryStatus
Status
EnforcementStatus
PolicyStoreSource
PolicyStoreSourceType
Haberdasher answered 8/2, 2017 at 10:25 Comment(0)
V
9

What I don't think is understood by many, including me recently, is that the Get-NetFirewall*Filter commands provide a speedy shortcut to searching the firewall rules, like the -filter option does in other commands. If I were to do this, it would take a very long time:

Get-NetFirewallRule | Get-NetFirewallPortFilter | 
  Where LocalPort -eq 3389

While this is almost instant:

Get-NetFirewallPortFilter | Where LocalPort -eq 3389

And Get-NetFirewallPortFilter actually returns the name of the firewall rule in the InstanceID property, which isn't shown by default. That's why you can pipe Get-NetFirewallPortFilter back into Get-NetFirewallRule.

Get-NetFirewallPortFilter | Where LocalPort -eq 3389 |
  Get-NetFirewallRule

Here's a function that gives netsh-like verbose output, with the ports, addresses, and applications:

function mynetsh {
  param($displayname)

  # in case there's more than one with wildcards
  get-netfirewallrule -displayname $displayname | foreach {
    $rule = $_

    $address = $rule | Get-NetFirewallAddressFilter
    $port = $rule | Get-NetFirewallPortFilter
    $application = $rule | Get-NetFirewallApplicationFilter
    [pscustomobject]@{
      DisplayName = $rule.DisplayName
      Description = $rule.Description  
      Enabled = $rule.Enabled
      Direction = $rule.Direction
      Profile = $rule.Profile
      DisplayGroup = $rule.DisplayGroup
      LocalAddress = $address.LocalAddress
      RemoteAddress = $address.RemoteAddress
      Protocol = $port.Protocol
      LocalPort = $port.LocalPort
      RemotePort = $port.RemotePort
      EdgeTraversalPolicy = $rule.EdgeTraversalPolicy
      Program = $application.Program 
      Action = $rule.Action
    }
  }  # end foreach
} # end function

mynetsh 'Remote Desktop - User Mode (TCP-In)'

DisplayName         : Remote Desktop - User Mode (TCP-In)
Description         : Inbound rule for the Remote Desktop service to allow RDP traffic. [TCP 3389]
Enabled             : False
Direction           : Inbound
Profile             : Any
DisplayGroup        : Remote Desktop
LocalAddress        : Any
RemoteAddress       : Any
Protocol            : TCP
LocalPort           : 3389
RemotePort          : Any
EdgeTraversalPolicy : Block
Program             : %SystemRoot%\system32\svchost.exe
Action              : Allow
Vandiver answered 27/9, 2019 at 16:38 Comment(1)
Wish I could upvote this more than once. Thank you for the clear information, code examples, and coverage of the topic. Excellent post.Catamenia
O
4

In order to find the port numbers that are already in the firewall rules, you can use a different cmdlet Get-NetFirewallPortFilter.

(Info)

Use Get-NetFirewallRule to filter which subset of rules you want to look at and pipe it to the above cmdlet. eg.:

Get-NetFirewallRule -DisplayName "SQL Broker Service" | Get-NetFirewallPortFilter

Sounds like the property you are after is localport.

Oyer answered 6/11, 2017 at 3:40 Comment(0)
C
2

Use the below command to list all.

Get-NetFirewallRule| Where { $_.Enabled -eq $True } |
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}},
Enabled,
Profile,
Direction,
Action

The output is shown below enter image description here

Crissman answered 30/1, 2020 at 5:9 Comment(2)
I just wanted to edit out the ">> " stuff. But weirdly, sometimes 'True' doesn't work and $True does. Sometimes Enabled is an interger, and sometimes it's an Enum.Vandiver
This looks to be the source of the above answer: itluke.online/2018/11/27/…Petterson
A
0

Use the Select-Object Cmdlet to Display all Properties

This will Display only the First one so you dont get flooded with text, feel free to delete the "-First 1" as needed

Get-NetFirewallRule | select -First 1 -Property *

However investigating that it does not seem like there is Information about the port, looking further into it - you would probably need to use Get-NetFirewallPortFilter and match them up by instanceid. If you need help with that I'll need a little more Information on what you are trying to accomplish.

Abortionist answered 8/2, 2017 at 12:25 Comment(1)
Great, Fabian ! Actrually I am using powershell add a firewall rule like this: netsh advfirewall firewall add rule name="MyService" protocol=TCP dir=in localport=8009 action=allow. So I need to check if there is already a rule named "MyService" existing. And you know in the firewall rules there may be duplicated name rules. So I need to check the specific configuration, like port. To make sure I add a different rule.Haberdasher
O
0

If you use only the firewall cmdlets to get a list of object that include ports, programs etc., it's not an easy task, and it's very slow! Why not try the old school way, the netsh advfirewall firewall command suite. Below is my trying to get a list of objects that include all rule information.

$output = (netsh advfirewall firewall show rule name=all verbose | Out-String).Trim() -split '\r?\n\s*\r?\n'
$propertyNames = [System.Collections.Generic.List[string]]::new()

$objects = @( $(foreach($section in $output ) {
    $obj = @{}
    foreach( $line in ($section -split '\r?\n') ) {
        if( $line -match '^\-+$' ) { continue }
        $name, $value = $line -split ':\s*', 2
        $name = $name -replace " ", ""
        
        $obj.$name  = $value
        if($propertyNames -notcontains $name) {
            $propertyNames.Add( $name )
        }
    }
    $obj
}) | % {
    foreach( $prop in $propertyNames ) {
        if( $_.Keys -notcontains $prop ) {
            $_.$prop = $null
        }
    }
    [PSCustomObject]$_
})
Oliviaolivie answered 30/8, 2021 at 1:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.