0

Hi I need to query FW GPO ports within multiple remote servers. At the first step I build this query which should retrieve the information locally and I plan to add it as a .PS script inside ScriptBlock. I built a query that integrates results from two different queries. On the first query, I put the filters I need without any issues however on the second query I had issues.

This is the script:

Get-NetFirewallRule -Action Allow -Enabled True -Direction Inbound | Select-Object -Unique | Where-Object {$_.LocalPort -eq 7680}|
Format-Table -Property Profile,
Enabled,
Direction,
@{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}},
Profile

I have a couple of questions:

  1. Can someone advise how to filter local ports and also a range of ports in this query? I tried many times without success (how do we use Where-Object to query such as that @{Name='Protocol';Expression={($PSItem | Get-NetFirewallPortFilter).Protocol}})
  2. Will use netsh instead will it be preferable?
  3. How do we customize the results and present the results in AsBuiltReport framework?

Thanks Shai

I tried to modify the where-object with no success. It should bring back the rows where

Action=Allow,
Enabled=True 
Direction=Inbound
and
($_.LocalPort -match '80|135|139|445|5985|5986' -or $_.LocalPort -ge 49152 -or $_.LocalPort -le 65535)
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • "I tried to modify the where-object with no success" - you forgot to post your attempt :) – Mathias R. Jessen Nov 10 '22 at 17:33
  • @{Name='LocalPort';Expression={($PSItem | Get-NetFirewallPortFilter).LocalPort}}, inside – user1568050 Nov 10 '22 at 17:44
  • @{Name='LocalPort';Expression={($PSItem | Get-NetFirewallPortFilter).LocalPort}} different places: after the Get- command with | after the last brackets try only with one value. The issue is that I don't know if I can use it there and couldn't find yet answer.. – user1568050 Nov 10 '22 at 17:51

1 Answers1

1

It looks like you need to modify your Where-Object call to perform more fine-grained filtering, based on the expression you already have, with some corrections:

Get-NetFirewallRule -Action Allow -Enabled True -Direction Inbound | 
  Where-Object { 
    $portFilter = $PSItem | Get-NetFirewallPortFilter
    $portFilter.LocalPort -match '^(80|135|139|445|5985|5986)$' -or 
      ($portFilter.LocalPort -ge 49152 -and $portFilter.LocalPort -le 65535)
  } |
  Format-Table Profile,
               Enabled,
               Direction,
               @{ Name='Protocol'; Expression={ $portFilter.Protocol } },
               @{ Name='LocalPort'; Expression={ $portFilter.LocalPort } },
               @{ Name='RemotePort'; Expression={ $portFilter.RemotePort } },
               @{ Name='RemoteAddress'; Expression={ ($PSItem | Get-NetFirewallAddressFilter).RemoteAddress } }

Note:

  • -match '80|135|139|445|5985|5986' was changed to -match '^(80|135|139|445|5985|5986)$' to ensure that port numbers only match in full, to rule out false positives.

  • $_.LocalPort -ge 49152 -or $_.LocalPort -le 65535 was changed to ($portFilter.LocalPort -ge 49152 -and $portFilter.LocalPort -le 65535) (from -or to -and), as I presume you want to match ports between those two numbers.

  • Since variable $portFilter is defined in the second Where-Object call, your Format-Table can then use $portFilter in lieu of $PSItem | Get-NetFirewallPortFilter in its calculated properties.

    • As an aside: In your original Format-Table call, you're repeating a ($PSItem | Get-NetFirewallPortFilter) call in each calculated property's expression, which is inefficient; even if you had no preexisting variable, you could assign the result to a variable in the first such property, and then use the variable in the remaining ones.
  • As always, Format-* cmdlets should only ever be used to produce for-display output; if you need to programmatically process the output later, use Select-Object instead.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • @user1568050, OK, I've remove the first `Where-Object` from the answer too. Please see my update, which spells out the `Format-Table` call. – mklement0 Nov 10 '22 at 18:45
  • It's getting better but after implementing the query there are unexpected results such as 546,5355,5357,5358,6004. I also want to see only unique ports but in some cases, such as 5353,5355 it repeats... Profile Enabled Direction Action Protocol LocalPort RemotePort RemoteAddress ------- ------- --------- ------ -------- --------- ---------- ------------- Any True Inbound Allow UDP 546 547 Any Private True Inbound Allow UDP 5355 Any LocalSubnet Private True Inbound Allow TCP 5358 Any LocalSubnet – user1568050 Nov 10 '22 at 21:57
  • Just for clarification, I need that the values within the -match '^(80|135|139|445|5985|5986)$' will be the exact values meaning 80 or 135 or 139 etc.. – user1568050 Nov 10 '22 at 22:04
  • @user1568050, it sounds like `$PSItem | Get-NetFirewallPortFilter` can return _multiple_ objects, so that `$portFilter.LocalPort` then returns an _array_ of port values. Yes, the `-match` operation matches only _exact_ values (though with an _array_ as the LHS, _multiple_ exact values may be returned). `$portFilter.LocalPost | Select-Object -Unique` would give you only unique port numbers. – mklement0 Nov 10 '22 at 22:14
  • Thank you. So in which area I should drop the | Select-Object -Unique and also what can I add to show only the filtered ports since it's not retrieving the only expected results? How do I add the computer name/IP to the query? Another question is if that can work on Linux if I do it remotely from additional windows/linux – user1568050 Nov 10 '22 at 22:23
  • @user1568050, replace `@{ Name='LocalPort'; Expression={ $portFilter.LocalPort } }` with `@{ Name='LocalPort'; Expression={ $portFilter.LocalPort | Select-Object -Unique } }`. As for not retrieving the expected results: It's not clear to me in what way it is _not_ doing that. As for Linux: the cmdlets you're using are only available on Windows. At this point I suggest you create _new_ question post(s), focused on any _follow-up_ questions you may have. – mklement0 Nov 10 '22 at 22:33
  • As for not retrieving the expected results: It's not clear to me in what way it is not doing that Hi, thanks but it still repeat rows not sure why... It retries values not only from the filter but also ports which I don't interest. For example: LocalPort 546,5355,5357,5358,5445,554,5000-5020,6004. How can we filter those out? – user1568050 Nov 10 '22 at 22:45
  • Just to share the link to your follow-up question here: https://stackoverflow.com/q/74405014/45375 – mklement0 Nov 11 '22 at 16:24