Check firewall rules remotely using PowerShell

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:

PowerShellBros.com
PowerShellBros.com

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"
            }
  
        }
  
    }
  
}

2 thoughts on “Check firewall rules remotely using PowerShell

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.