tjernigan
tjernigan

Reputation: 191

How can you check for existing firewall rules using Powershell

So, I've got this script:

function Add-FirewallRule {
   param( 
      $name,
      $tcpPorts,
      $appName = $null,
      $serviceName = $null
   )
    $fw = New-Object -ComObject hnetcfg.fwpolicy2 
    $rule = New-Object -ComObject HNetCfg.FWRule

    $rule.Name = $name
    if ($appName -ne $null) { $rule.ApplicationName = $appName }
    if ($serviceName -ne $null) { $rule.serviceName = $serviceName }
    $rule.Protocol = 6 #NET_FW_IP_PROTOCOL_TCP
    $rule.LocalPorts = $tcpPorts
    $rule.Enabled = $true
    $rule.Grouping = "@firewallapi.dll,-23255"
    $rule.Profiles = 7 # all
    $rule.Action = 1 # NET_FW_ACTION_ALLOW
    $rule.EdgeTraversal = $false
    if(*here*)
    {
    $fw.Rules.Add($rule)
    }

}

and I want to be able to put something in the if() that will check and see if the rule already exists before it adds it. I'm not terribly familiar with powershell, so go easy on me :P

Upvotes: 7

Views: 26898

Answers (7)

js2010
js2010

Reputation: 27428

This doesn't seem to be widely known. You can do a fast search of the firewall rules by going first to the filter commands, for example, to list the ones with 'chrome.exe' as the program. You can use a wildcard with -Program, even though it doesn't seem to be documented.

Get-NetFirewallApplicationFilter -Program *chrome.exe | Get-NetFirewallRule | 
  % Displayname

Google Chrome (mDNS-In)
Get-NetFirewallPortFilter | Where Localport -match 3389 | Get-NetFirewallRule | 
  % Displayname

Remote Desktop - User Mode (TCP-In)
Remote Desktop - User Mode (UDP-In)

Upvotes: 3

Chris Mills
Chris Mills

Reputation: 410

PowerShell Firewall example for SDL Microservices

Only create a new firewall rule if it does not already exist

$rules = Get-NetFirewallRule

$par = @{
    DisplayName = ""
    LocalPort = 80
    Direction="Inbound"
    Protocol ="TCP" 
    Action = "Allow"
}

$par.LocalPort = 8081
$par.DisplayName = "SDL Web 8 Stage Content Microservice on port $($par.LocalPort)"
if (-not $rules.DisplayName.Contains($par.DisplayName)) {New-NetFirewallRule @par}

$par.LocalPort = 8082
$par.DisplayName = "SDL Web 8 Stage Discovery Microservice on port $($par.LocalPort)"
if (-not $rules.DisplayName.Contains($par.DisplayName)) {New-NetFirewallRule @par"}

Upvotes: 8

Marius
Marius

Reputation: 9664

Why not just:

$r = Get-NetFirewallRule -DisplayName 'Docker Cluster Management Communications' 2> $null; 
if ($r) { 
    write-host "found it"; 
} 
else { 
    write-host "did not find it" 
}

Upvotes: 7

reniasa
reniasa

Reputation: 213

You can do it in hacky way, so using Get-NetFirewallRule and surround it in try catch statement. If the rule doesn't exist, it will move us to catch statement so we can create a new rule there.

try {
    $firewallRule = Get-NetFirewallRule -DisplayName PROGRAM -ErrorAction Stop
    "Firewall rule already exist for program.exe" | Add-Content 'file.log'
}
catch {
    if(-Not $firewallRule) {
        New-NetFirewallRule -Program $ecfClient -Action Allow -Profile Any -DisplayName "PROGRAM"
        "Firewall rule for ecfClient.exe succesffully created" | Add-Content 'file.log'
    }
}

You can also check the value from the Get-NetFirewallRule, if the rule exists it will return true because variable isn't empty.

I know it's a dirty way for doing this, but when I was looking for the shortest way that really helped me.

Upvotes: 1

Varun
Varun

Reputation: 763

Following up @Trevor Sullivian Suggestion here is test script which achieves the same using NetSecurity Module.

Import-Module NetSecurity
new-netfirewallrule -Action Allow -Direction Inbound -Enabled True -Protocol TCP                                   -LocalPort <<Port>> -DisplayName <<Name>>

Upvotes: 0

user189198
user189198

Reputation:

MSDN has some extensive documentation on the Windows Firewall API here:

http://msdn.microsoft.com/en-us/library/aa366449(v=vs.85).aspx

You'll want to start with instantiating the HNetCfg.FwMgr COM object -- this will give you access to query various existing rules via the HNetCfg.FwMgr.LocalPolicy.CurrentProfile.

There are several different types of rules: Authorized Applications, Globally Open Ports, ICMP settings, and "services." The INetFwProfile object (retrieved via the CurrentProfile) has properties that allow access to these rules.

http://msdn.microsoft.com/en-us/library/aa365327(v=vs.85).aspx

Update (2014-01-30): In Windows 8 and Windows Server 2012, there is a PowerShell module called NetSecurity, which contains the Get-NetFirewallRule command. You can use this command to discover which firewall rules are already defined. To add a new firewall rule, use the New-NetFirewallRule command in the same NetSecurity module.

Upvotes: 5

user4531
user4531

Reputation: 2565

This answer over on serverfault, which was based on this blog-post, might help:

Function Get-EnabledRules
{
    Param($profile)
    $rules = (New-Object -comObject HNetCfg.FwPolicy2).rules
    $rules = $rules | where-object {$_.Enabled -eq $true}
    $rules = $rules | where-object {$_.Profiles -bAND $profile}
    $rules
}

$networkListManager = [Activator]::CreateInstance([Type]::GetTypeFromCLSID([Guid]"{DCB00C01-570F-4A9B-8D69-199FDBA5723B}"))
 $connections = $networkListManager.GetNetworkConnections()
[int[] ] $connTypes = @()
$connTypes = ($connections | % {$_.GetNetwork().GetCategory()})
#$connTypes += 1
Write-Host $connTypes

$connTypes | ForEach-Object {Get-EnabledRules -profile $_ | sort localports,Protocol | format-table -wrap -autosize -property Name, @{Label="Action"; expression={$_.action}}, @{Label="Protocol"; expression={$_.protocol}}, localPorts,applicationname}

you will need to check the enabled rules in your 'if()' ..

Upvotes: 1

Related Questions