Public/08_Security/Get-VBFirewallPortRules.ps1
|
# ============================================================ # FUNCTION : Get-VBFirewallPortRules # VERSION : 1.0.2 # CHANGED : 10-04-2026 -- Initial VB-compliant release # AUTHOR : Vibhu Bhatnagar # PURPOSE : Retrieve Windows Firewall port rules from target computer # ENCODING : UTF-8 with BOM # ============================================================ <# .SYNOPSIS Retrieve Windows Firewall inbound port rules from target computer(s). .DESCRIPTION Queries firewall rules with port filters. Filters out Microsoft default rules by default. Supports filtering by protocol, port, status. Can export to CSV. Returns detailed rule information including status and configuration. .PARAMETER ComputerName Target computer(s). Defaults to local machine. Accepts pipeline input. Aliases: Name, Server, Host .PARAMETER Credential Alternate credentials for remote execution. .PARAMETER Protocol Filter rules by protocol (TCP, UDP, Any). Case-insensitive. .PARAMETER Port Filter rules by specific port number. .PARAMETER IncludeBlocked Include rules where Action is Block. Default excludes blocked rules. .PARAMETER IncludeDisabled Include disabled rules. Default shows enabled rules only. .PARAMETER IncludeDefaultRules Include Windows/Microsoft default rules. Default shows custom rules only. .PARAMETER Detailed Show additional properties including description, addresses, and authentication. .PARAMETER ExportCSV Export results to CSV file at specified path. .EXAMPLE Get-VBFirewallPortRules Retrieves custom inbound firewall rules on local computer. .EXAMPLE Get-VBFirewallPortRules -ComputerName SERVER01 -Protocol TCP Retrieves custom TCP firewall rules from SERVER01. .EXAMPLE Get-VBFirewallPortRules -Port 443 -Detailed Retrieves rules for port 443 with detailed information. .EXAMPLE 'SERVER01', 'SERVER02' | Get-VBFirewallPortRules -ExportCSV 'C:\rules.csv' Exports firewall rules to CSV. .OUTPUTS [PSCustomObject]: ComputerName, RuleID, Name, Enabled, Direction, Profile, Action, Protocol, LocalPort, RemotePort, Program, ProgramPath, Status, CollectionTime (plus optional detailed properties) .NOTES Version : 1.0.2 Author : Vibhu Bhatnagar Modified : 10-04-2026 Category : Security #> function Get-VBFirewallPortRules { [CmdletBinding()] param( [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('Name', 'Server', 'Host')] [string[]]$ComputerName = $env:COMPUTERNAME, [PSCredential]$Credential, [ValidateSet('TCP', 'UDP', 'Any', IgnoreCase = $true)] [string]$Protocol, [string]$Port, [switch]$IncludeBlocked, [switch]$IncludeDisabled, [switch]$IncludeDefaultRules, [switch]$Detailed, [string]$ExportCSV ) process { foreach ($computer in $ComputerName) { try { # Step 1 -- Define remote script block $scriptBlock = { param($protocol, $port, $includeBlocked, $includeDisabled, $includeDefaultRules, $detailed) # Step 1a -- Get base firewall rules $rules = Get-NetFirewallRule -PolicyStore ActiveStore | Where-Object { ($_.Direction -eq 'Inbound') -and ($includeBlocked -or $_.Action -eq 'Allow') -and ($includeDisabled -or $_.Enabled -eq $true) -and ($includeDefaultRules -or -not ($_.Owner -like '*Microsoft*' -or $_.DisplayName -like '*Windows*' -or $_.DisplayGroup -like '*Windows*' -or $_.DisplayGroup -like '*Microsoft*' -or $_.Group -like '*Windows*' -or $_.Group -like '*Microsoft*' -or $_.Group -like '@*' -or $_.DisplayName -like '@*')) } $results = [System.Collections.ArrayList]::new() # Step 1b -- Process each rule foreach ($rule in $rules) { $portFilters = Get-NetFirewallPortFilter -AssociatedNetFirewallRule $rule -ErrorAction SilentlyContinue if (-not $portFilters -and -not $detailed) { continue } $addressFilter = Get-NetFirewallAddressFilter -AssociatedNetFirewallRule $rule -ErrorAction SilentlyContinue $appFilter = Get-NetFirewallApplicationFilter -AssociatedNetFirewallRule $rule -ErrorAction SilentlyContinue $securityFilter = Get-NetFirewallSecurityFilter -AssociatedNetFirewallRule $rule -ErrorAction SilentlyContinue if ($portFilters) { foreach ($filter in $portFilters) { if ($protocol -and $filter.Protocol -ne $protocol) { continue } if ($port) { if (-not $filter.LocalPort -or ($filter.LocalPort -ne $port -and $filter.LocalPort -ne 'Any' -and $filter.LocalPort -notlike "*,$port,*" -and $filter.LocalPort -notlike "$port,*" -and $filter.LocalPort -notlike "*,$port")) { continue } } $resultObj = [PSCustomObject]@{ RuleID = $rule.Name Name = $rule.DisplayName Enabled = if ($rule.Enabled -eq $true) { 'Yes' } else { 'No' } Direction = $rule.Direction Profile = $rule.Profile Action = $rule.Action Protocol = if ($filter.Protocol -eq 'Any') { 'Any' } else { $filter.Protocol } LocalPort = if ($filter.LocalPort -eq 'Any') { 'Any' } else { $filter.LocalPort } RemotePort = if ($filter.RemotePort -eq 'Any') { 'Any' } else { $filter.RemotePort } Program = if ($appFilter.Program -eq '*') { 'Any' } else { Split-Path $appFilter.Program -Leaf } ProgramPath = if ($appFilter.Program -eq '*') { 'Any' } else { $appFilter.Program } } if ($detailed) { Add-Member -InputObject $resultObj -NotePropertyName 'Description' -NotePropertyValue $rule.Description Add-Member -InputObject $resultObj -NotePropertyName 'Group' -NotePropertyValue $rule.Group Add-Member -InputObject $resultObj -NotePropertyName 'LocalAddress' -NotePropertyValue ($addressFilter.LocalAddress -join ', ') Add-Member -InputObject $resultObj -NotePropertyName 'RemoteAddress' -NotePropertyValue ($addressFilter.RemoteAddress -join ', ') Add-Member -InputObject $resultObj -NotePropertyName 'Authentication' -NotePropertyValue $securityFilter.Authentication Add-Member -InputObject $resultObj -NotePropertyName 'Encryption' -NotePropertyValue $securityFilter.Encryption } [void]$results.Add($resultObj) } } elseif ($detailed) { $resultObj = [PSCustomObject]@{ RuleID = $rule.Name Name = $rule.DisplayName Enabled = if ($rule.Enabled -eq $true) { 'Yes' } else { 'No' } Direction = $rule.Direction Profile = $rule.Profile Action = $rule.Action Protocol = 'N/A' LocalPort = 'N/A' RemotePort = 'N/A' Program = if ($appFilter.Program -eq '*') { 'Any' } else { Split-Path $appFilter.Program -Leaf } ProgramPath = if ($appFilter.Program -eq '*') { 'Any' } else { $appFilter.Program } Description = $rule.Description Group = $rule.Group LocalAddress = ($addressFilter.LocalAddress -join ', ') RemoteAddress = ($addressFilter.RemoteAddress -join ', ') Authentication = $securityFilter.Authentication Encryption = $securityFilter.Encryption } [void]$results.Add($resultObj) } } return $results | Sort-Object -Property Name } # Step 2 -- Execute locally or remotely if ($computer -eq $env:COMPUTERNAME) { $results = & $scriptBlock -protocol $Protocol -port $Port -includeBlocked $IncludeBlocked -includeDisabled $IncludeDisabled -includeDefaultRules $IncludeDefaultRules -detailed $Detailed } else { $splat = @{ ComputerName = $computer ScriptBlock = $scriptBlock ArgumentList = @($Protocol, $Port, $IncludeBlocked, $IncludeDisabled, $IncludeDefaultRules, $Detailed) } if ($Credential) { $splat['Credential'] = $Credential } $results = Invoke-Command @splat } # Step 3 -- Output results with metadata foreach ($item in $results) { [PSCustomObject]@{ ComputerName = $computer RuleID = $item.RuleID Name = $item.Name Enabled = $item.Enabled Direction = $item.Direction Profile = $item.Profile Action = $item.Action Protocol = $item.Protocol LocalPort = $item.LocalPort RemotePort = $item.RemotePort Program = $item.Program ProgramPath = $item.ProgramPath Status = 'Success' CollectionTime = (Get-Date).ToString('dd-MM-yyyy HH:mm:ss') } } } catch { [PSCustomObject]@{ ComputerName = $computer Status = 'Failed' Error = $_.Exception.Message CollectionTime = (Get-Date).ToString('dd-MM-yyyy HH:mm:ss') } } } } } |