How can you check for existing firewall rules using Powershell

流过昼夜 提交于 2019-12-02 09:36:55

问题


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


回答1:


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.




回答2:


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



回答3:


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



回答4:


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()' ..




回答5:


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



回答6:


How does one list the entire ruleset, including all source and destination addresses and ports, and protocols? These are not included in the default output from Get-NetFirewallRule...(why???)

The solution above looks like it would do that, but I don't want to have to write a function. I'm looking for a 'one-liner' solution.




回答7:


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.



来源:https://stackoverflow.com/questions/6597951/how-can-you-check-for-existing-firewall-rules-using-powershell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!