In past few days I had to check firewall rules setting on several machines. It was a good opportunity to write PowerShell function for this and share it with you.
It’s just another simple function which will help you to gather the following firewall information from servers remotely:
– Server
– Direction
– Action
– Rule Name
– Profile
– Enabled
– Protocol
– Local Ports
Below you can find description of firewall rules properties values from:
(New-Object -ComObject hnetcfg.fwpolicy2).rules
Direction:
Inbound = 1
Outbound = 2
Action:
Block = 0
Allow = 1
Profiles:
Domain = 1
Private = 2
Public = 4
All = 2147483647
Protocols:
TCP = 6
UDP = 17
ICMPv4 = 1
ICMPv6 = 58
Example:

Unfortunately as you can see properties are represented by numbers instead of words. This is why we have to use “Switch” to make output readable.
Switch:
Switch($Rule.Direction) { "1" { $Direction = "Inbound" } "2" { $Direction = "Outbound" } } Switch($Rule.Action) { "0" { $Action = "Block" } "1" { $Action = "Allow" } } Switch($Rule.Profiles) { "1" { $Profile = "Domain" } "2" { $Profile = "Private" } "4" { $Profile = "Public" } "2147483647" { $Profile = "All" } } Switch($Rule.Protocol) { "6" { $Protocol = "TCP" } "17" { $Protocol = "UDP" } "1" { $Protocol = "ICMPv4" } "58" { $Protocol = "ICMPv6" } }
Usage:
Get-Firewall Get-Firewall -Servers DC01 Get-Firewall -Servers DC01,DC02 Get-Firewall -Servers (gc "c:\temp\input.txt) Get-Firewall -Servers DC01 -Enabled True Get-Firewall -Servers DC01 -RuleType Inbound Get-Firewall -Servers DC01 -Enabled False -RuleType Outbound
Final script:
Function Get-Firewall{ [CmdletBinding()] # Parameters used in this function param ( [Parameter(Position=0, Mandatory = $false, HelpMessage="Provide server names", ValueFromPipeline = $true)] $Servers = $env:computername, [Parameter(Position=1, Mandatory = $false, HelpMessage="Rule enabled (True, False)", ValueFromPipeline = $true)][ValidateSet("True", "False")][string] $Enabled = $null, [Parameter(Position=2, Mandatory = $false, HelpMessage="Select rule type (Inbound, Outbound)", ValueFromPipeline = $true)][ValidateSet("Inbound", "Outbound")][string] $RuleType = $null ) # Error action set to Stop $ErrorActionPreference = "Stop" If($Servers -eq $env:computername) { Write-Host "`nChecking $Servers" -ForegroundColor Yellow Try { If(!$Enabled) { $Firewall = (New-Object -ComObject hnetcfg.fwpolicy2).rules } Else { $Firewall = (New-Object -ComObject hnetcfg.fwpolicy2).rules | Where-Object { $_.enabled -like $enabled } } If (!$Firewall) {Throw "Failed to get FW rules"} } Catch { Write-Host $_.Exception.Message Break } # Array with alerts $FWArray = @() # Looping each alert $Firewall | ForEach-Object{ $Rule = $_ Switch($Rule.Direction) { "1" { $Direction = "Inbound" } "2" { $Direction = "Outbound" } } Switch($Rule.Action) { "0" { $Action = "Block" } "1" { $Action = "Allow" } } Switch($Rule.Profiles) { "1" { $Profile = "Domain" } "2" { $Profile = "Private" } "4" { $Profile = "Public" } "2147483647" { $Profile = "All" } } Switch($Rule.Protocol) { "6" { $Protocol = "TCP" } "17" { $Protocol = "UDP" } "1" { $Protocol = "ICMPv4" } "58" { $Protocol = "ICMPv6" } } # Create a custom object $Object = New-Object PSCustomObject $Object | Add-Member -MemberType NoteProperty -Name "Server" -Value $Servers $Object | Add-Member -MemberType NoteProperty -Name "Direction" -Value $Direction $Object | Add-Member -MemberType NoteProperty -Name "Action" -Value $Action $Object | Add-Member -MemberType NoteProperty -Name "Rule Name" -Value $Rule.name $Object | Add-Member -MemberType NoteProperty -Name "Profile" -Value $Profile $Object | Add-Member -MemberType NoteProperty -Name "Enabled" -Value $Rule.Enabled $Object | Add-Member -MemberType NoteProperty -Name "Protocol" -Value $Protocol $Object | Add-Member -MemberType NoteProperty -Name "Local Ports" -Value $Rule.Localports # Add custom object to our array $FWArray += $Object } If(!$RuleType) { $FWArray | Sort-Object enabled -Descending | ft -Wrap -AutoSize #$FWArray | Sort-Object enabled -Descending | Out-GridView -Title "Firewall rules for $Servers" } Else { $FWArray | Where-Object {$_.Direction -eq $Ruletype} | Sort-Object direction,enabled | ft -Wrap -AutoSize #$FWArray | Where-Object {$_.Direction -eq $Ruletype} | Sort-Object direction,enabled | Out-GridView -Title "Firewall rules for $Servers" } } Else { ForEach($Server in $Servers) { Write-Host "`nChecking $Server" -ForegroundColor Yellow Try { If(!$Enabled) { $Firewall = Invoke-Command $Server -ScriptBlock{(New-Object -ComObject hnetcfg.fwpolicy2).rules} } Else { $Firewall = Invoke-Command $Server -ScriptBlock{(New-Object -ComObject hnetcfg.fwpolicy2).rules | Where-Object { $_.enabled -like $enabled }} } If (!$Firewall) {Throw "Failed to get FW rules"} } Catch { Write-Host $_.Exception.Message Continue } # Array with alerts $FWArray = @() # Looping each alert $Firewall | ForEach-Object{ $Rule = $_ Switch($Rule.Direction) { "1" { $Direction = "Inbound" } "2" { $Direction = "Outbound" } } Switch($Rule.Action) { "0" { $Action = "Block" } "1" { $Action = "Allow" } } Switch($Rule.Profiles) { "1" { $Profile = "Domain" } "2" { $Profile = "Private" } "4" { $Profile = "Public" } "2147483647" { $Profile = "All" } } Switch($Rule.Protocol) { "6" { $Protocol = "TCP" } "17" { $Protocol = "UDP" } "1" { $Protocol = "ICMPv4" } "58" { $Protocol = "ICMPv6" } } $Object = New-Object PSCustomObject $Object | Add-Member -MemberType NoteProperty -Name "Server" -Value $Server $Object | Add-Member -MemberType NoteProperty -Name "Direction" -Value $Direction $Object | Add-Member -MemberType NoteProperty -Name "Action" -Value $Action $Object | Add-Member -MemberType NoteProperty -Name "Rule Name" -Value $Rule.name $Object | Add-Member -MemberType NoteProperty -Name "Profile" -Value $Profile $Object | Add-Member -MemberType NoteProperty -Name "Enabled" -Value $Rule.Enabled $Object | Add-Member -MemberType NoteProperty -Name "Protocol" -Value $Protocol $Object | Add-Member -MemberType NoteProperty -Name "Local Ports" -Value $Rule.Localports # Add custom object to our array $FWArray += $Object } If(!$RuleType) { $FWArray | Sort-Object enabled -Descending | ft -Wrap -AutoSize #$FWArray | Sort-Object enabled -Descending | Out-GridView -Title "Firewall rules for $Server" } Else { $FWArray | Where-Object {$_.Direction -eq $Ruletype} | Sort-Object direction,enabled | ft -Wrap -AutoSize #$FWArray | Where-Object {$_.Direction -eq $Ruletype} | Sort-Object direction,enabled | Out-GridView -Title "Firewall rules for $Server" } } } }
I get error “Failed to get FW rules” when run function firewall with 3 parameters
Got Failed to get FW rules as soon as there is more than 1 parameter.