With APIs, you always hope that Get
and Set
methods mirror each other. More often than not, they don’t.
Take for instance these two:
- [Wayback/Archive.is]
Get-NetFirewallRule
(NetSecurity) | Microsoft Docs - [Wayback/Archive.is]
Set-NetFirewallRule
(NetSecurity) | Microsoft Docs
They are far from symmetric: [Wayback/Archive] Get-NetFirewallRule
shows far less than [Wayback/Archive] Set-NetFirewallRule
allows you to set (first and foremost the various port related properties). It can be worked around though.
There are a few posts discussing this, of which I think these two are the most important:
- [Wayback/Archive] How to display firewall rule ports numbers with PowerShell
- [Wayback/Archive] powershell – Why doesn’t Get-NetFirewallRule show all information of the firewall rule? – Stack Overflow (thanks [Wayback/Archive] dave zhou and and [Wayback/Archive] js2010)
Both above posts via [Wayback/Archive] “Get-NetFirewallRule” “LocalPort” – Google Search.
This is what I was after:
PowerShell "Get-NetFirewallRule -Name 'RemoteDesktop-UserMode-In-TCP' | Select-Object Name,DisplayName,Enabled,Direction,@{Name='Protocol';Expression={($PSItem | Get-NetFirewallPortFilter).Protocol}},Action,@{Name='LocalPort';Expression={($PSItem | Get-NetFirewallPortFilter).LocalPort}}"
Or actually:
PowerShell "Get-NetFirewallRule -Name 'RemoteDesktop-UserMode-In-TCP' -ErrorAction SilentlyContinue | Select-Object Name,DisplayName,Enabled,Direction,@{Name='Protocol';Expression={($PSItem | Get-NetFirewallPortFilter).Protocol}},Action,@{Name='LocalPort';Expression={($PSItem | Get-NetFirewallPortFilter).LocalPort}}"
Let me explain this:
Get-NetFirewallRule
gets a firewall rule with a specific name, but can only get you a few properties that can be set throughSet-NetFirewallRule
.Name,DisplayName,Enabled,Direction
are properties it understands.Protocol
andLocalPort
aren’t, but are often of interest.Get-NetFirewallPortFilter
can get you bothProtocol
andLocalPort
.- There are more functions named like
Get-NetFirewall*Filter
, all of which require an-AssociatedNetFirewallRule <CimInstance>
(or an-All
) parameter which is whatGet-NetFirewallRule
returns. This way you can retrieve details not provided byGet-NetFirewallRule
. - The portions like
@{Name='Protocol';Expression={($PSItem | Get-NetFirewallPortFilter).Protocol}}
returns one property, in this case theProtocol
property fromGet-NetFirewallPortFilter
returned asProtocol
(the latter can be different if you want; the former needs to beProtocol
). - The
-ErrorAction SilentlyContinue
bit is to prevent this kind of exception when no-Name
matches:
Get-NetFirewallRule : No MSFT_NetFirewallRule objects found with property 'InstanceID' equal to 'RemoteDesktop-UserMode-In-TCP_'. Verify the value of the property and retry. At line:1 char:1 + Get-NetFirewallRule -Name 'RemoteDesktop-UserMode-In-TCP_' + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (RemoteDesktop-UserMode-In-TCP_:String) [Get-NetFirewallRule], CimJobExc eption + FullyQualifiedErrorId : CmdletizationQuery_NotFound_InstanceID,Get-NetFirewallRule
When the exception occurs, the execution continues, but since no object is returned the|
pipe will not execute and no details are returned.I got this trick from [Wayback/Archive] firewall – How can I stop the Powershell command `Get-NetFirewallRule` from throwing an error? – Stack Overflow (thanks [Wayback/Archive] Pure.Krome and [Wayback/Archive] arco444)
Notes:
- 3. also allows
Get-NetFirewallRule
to search for a group, then get all the firewall rules out of them, for instance with
Get-NetFirewallRule -DisplayGroup "File and Printer Sharing" | ForEach-Object { Write-Host $_.DisplayName ; Get-NetFirewallAddressFilter -AssociatedNetFirewallRule $_ }
- 4. also works the other way around, but only if you have elevated using an administrative token. The below lists all firewall rules involving port 3389 (Remote Desktop Protocol):
PowerShell "Get-NetFirewallPortFilter | Where LocalPort -eq 3389 | Get-NetFirewallRule"
Even a plain
Get-NetFirewallPortFilter
will get you an error without elevation:Get-NetFirewallPortFilter : Access is denied. At line:1 char:1 + Get-NetFirewallPortFilter + ~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : PermissionDenied: (MSFT_NetProtocolPortFilter:root/standardci...tocolPortFilter) [Get-Ne tFirewallPortFilter], CimException + FullyQualifiedErrorId : Windows System Error 5,Get-NetFirewallPortFilter
You might want to return more details than just Protocol
and Localport
, so I dug around and made the below table to document the asymmetry.