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-NetFirewallRulegets a firewall rule with a specific name, but can only get you a few properties that can be set throughSet-NetFirewallRule.Name,DisplayName,Enabled,Directionare properties it understands.ProtocolandLocalPortaren’t, but are often of interest.Get-NetFirewallPortFiltercan get you bothProtocolandLocalPort.- There are more functions named like
Get-NetFirewall*Filter, all of which require an-AssociatedNetFirewallRule <CimInstance>(or an-All) parameter which is whatGet-NetFirewallRulereturns. 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 theProtocolproperty fromGet-NetFirewallPortFilterreturned asProtocol(the latter can be different if you want; the former needs to beProtocol). - The
-ErrorAction SilentlyContinuebit is to prevent this kind of exception when no-Namematches:
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-NetFirewallRuleWhen 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-NetFirewallRuleto 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-NetFirewallPortFilterwill 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-NetFirewallRuleGet-NetFirewallRuleSet-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-NetFirewallRulecompatible properties provided by it[Wayback/Archive] Get-NetFirewallRuleName PolicyStoreSource DisplayName Description Enabled Profile Platform Direction Action EdgeTraversalPolicy LooseSourceMapping LocalOnlyMapping Owner[Wayback/Archive] Get-NetFirewallAddressFilterLocalAddress RemoteAddress[Wayback/Archive] Get-NetFirewallPortFilterProtocol LocalPort RemotePort IcmpType DynamicTarget[Wayback/Archive] Get-NetFirewallApplicationFilterProgram Package[Wayback/Archive] Get-NetFirewallServiceFilterService[Wayback/Archive] Get-NetFirewallInterfaceFilterInterfaceAlias[Wayback/Archive] Get-NetFirewallInterfaceTypeFilterInterfaceType[Wayback/Archive] Get-NetFirewallSecurityFilterLocalUser 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 comment