PowerShell: working around Get-NetFirewallRule not showing all the fields that Set-NetFirewallRule allows you to set
Posted by jpluimers on 2022/10/26
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.
Documenting the asymmetry
For documentation purposes, below is what Set-NetFirewallRule
and Get-NetFirewallRule
allow you to set and get.
All methods are in the [Wayback/Archive] NetSecurity
Module | Microsoft Docs.
Set-NetFirewallRule
Get-NetFirewallRule
Set-NetFirewallRule [-Name] <String[]> [-PolicyStore ] [-GPOSession ] [-NewDisplayName ] [-Description ] [-Enabled ] [-Profile ] [-Platform <String[]>] [-Direction ] [-Action ] [-EdgeTraversalPolicy ] [-LooseSourceMapping ] [-LocalOnlyMapping ] [-Owner ] [-LocalAddress <String[]>] [-RemoteAddress <String[]>] [-Protocol ] [-LocalPort <String[]>] [-RemotePort <String[]>] [-IcmpType <String[]>] [-DynamicTarget ] [-Program ] [-Package ] [-Service ] [-InterfaceAlias <WildcardPattern[]>] [-InterfaceType ] [-LocalUser ] [-RemoteUser ] [-RemoteMachine ] [-Authentication ] [-Encryption ] [-OverrideBlockRules ] [-CimSession <CimSession[]>] [-ThrottleLimit ] [-AsJob] [-PassThru] [-WhatIf] [-Confirm] []
TypeName: Microsoft.Management.Infrastructure.CimInstance#root/standardcimv2/MSFT_NetFirewallRule
[Wayback/Archive]Name PolicyStoreSource/PolicyStoreSourceType DisplayName (based on ElementName) Description Enabled Profiles -> Profiles Platform -> Platforms Direction Action EdgeTraversalPolicy LooseSourceMapping LocalOnlyMapping Owner
This is what is missing from Get-NetFirewallRule
when compared to Set-NetFirewallRule
:
[-GPOSession ] [-LocalAddress <String[]>] [-RemoteAddress <String[]>] [-Protocol ] [-LocalPort <String[]>] [-RemotePort <String[]>] [-IcmpType <String[]>] [-DynamicTarget ] [-Program ] [-Package ] [-Service ] [-InterfaceAlias <WildcardPattern[]>] [-InterfaceType ] [-LocalUser ] [-RemoteUser ] [-RemoteMachine ] [-Authentication ] [-Encryption ] [-OverrideBlockRules ] [-ThrottleLimit ] [-AsJob] [-PassThru] [-WhatIf] [-Confirm]
I listed all Get-NetFirewall*Filter
methods and their properties to get at this table of how to get all of the properties settable by Set-NetFirewallRule
:
Get-NetFirewall*
methodSet-NetFirewallRule
compatible properties provided by it[Wayback/Archive] Get-NetFirewallRule
Name PolicyStoreSource DisplayName Description Enabled Profile Platform Direction Action EdgeTraversalPolicy LooseSourceMapping LocalOnlyMapping Owner
[Wayback/Archive] Get-NetFirewallAddressFilter
LocalAddress RemoteAddress
[Wayback/Archive] Get-NetFirewallPortFilter
Protocol LocalPort RemotePort IcmpType DynamicTarget
[Wayback/Archive] Get-NetFirewallApplicationFilter
Program Package
[Wayback/Archive] Get-NetFirewallServiceFilter
Service
[Wayback/Archive] Get-NetFirewallInterfaceFilter
InterfaceAlias
[Wayback/Archive] Get-NetFirewallInterfaceTypeFilter
InterfaceType
[Wayback/Archive] Get-NetFirewallSecurityFilter
LocalUser RemoteUser RemoteMachine Authentication Encryption GetCimSessionComputerName GetCimSessionInstanceId
I could not find ways to retrieve these Set-NetFirewallRule
parameters from Get-NetFirewallRule*
methods:
[-Name] <String[]> [-PolicyStore ] [-GPOSession ] [-OverrideBlockRules ] [-ThrottleLimit ] [-AsJob] [-PassThru] [-WhatIf] [-Confirm] []
Vice versa, I could not find these properties returned from Get-NetFirewallRule
in the Set-NetFirewallRule
parameters:
Caption CommonName (ignored) ConditionListType (ignored) CreationClassName DisplayGroup (based on RuleGroup) ElementName (base for DisplayName) ExecutionStrategy (ignored) InstanceID (of the PolicyStore) Mandatory (ignored) PolicyDecisionStrategy (ignored) PolicyKeywords (ignored) PolicyRoles (ignored) PolicyRuleName (reserved for internal use) Priority (ignored) PSComputerName (PowerShell specific) RuleGroup RuleUsage (ignored) SequencedActions (ignored) StatusCode SystemCreationClassName (reserved for internal use) SystemName (reserved for internal use) EnforcementStatus PrimaryStatus Status
–jeroen
Leave a Reply