2

On a Server 2008 R2 machine, I would like to use Powershell to query the list of "remote addresses" for a specific rule. The rule in question has been created through a group policy applying to the machine.

I know there is netsh advfirewall firewall show rule name=<name> as well as the list returned by (New-object –comObject HNetCfg.FwPolicy2).rules, but both seem to only include rules which have been defined locally and do not list any of the rules created by the firewall GPO extension.

How do I conveniently get at the properties of policy-created rules?

the-wabbit
  • 40,737
  • 13
  • 111
  • 174

1 Answers1

0

I resorted to parsing the strings which are written to HKLM\SOFTWARE\Policies\Microsoft\WindowsFirewall\FirewallRules by the group policy firewall extension. This is what the raw registry value data might look like for a specific rule:

v2.10|Action=Allow|Active=TRUE|Dir=In|Protocol=6|LPort=5666|RA4=192.168.21.55|RA4=192.168240.10|RA4=192.168.240.11|RA4=192.168.240.12|App=%ProgramFiles%\NSClient++\nscp.exe|Name=NSClient++ Monitoring Agent|Desc=Allow NSClient/NRPE connections from Nagios servers|

As those are Name=Value pairs of data where "Name" is not unique, there is some more work than just a series of Split() calls, but it still sufficiently clean to work with in PowerShell v2 and onwards:

Function Get-GPOFirewallRules()
{
    $regPath="HKLM:\SOFTWARE\Policies\Microsoft\WindowsFirewall\FirewallRules"

    # fetch rule value strings from registry into an array of strings, 
    # map version info and GPO rule ID into fields in string
    $rulesRaw = (Get-ItemProperty -Path $regPath).PSObject.Properties | `
                Where-Object { $_.Name -like "{[0-9A-F\-]*}" } | `
                Select-Object "Name", "Value" | `
                ForEach-Object { $_.Value -replace "^(v[0-9\.]*)\|", `
                                                   "GPOID=$($_.Name)|GPOVERSION=`$1|" }

    # construct a result set of hashtables 
    $rulesRaw | ForEach-Object {
        $rule=@{}            # initialize as hashtable
        $_.Split("|") | ForEach-Object {
            $name = $_.Split("=")[0]
            $value = $_.Split("=")[1]
            # for multi-valued names, cast to array and add value element
            If ($rule.ContainsKey($name)) {
                $rule.$name = [array]($rule.$name) + $value
            } Else {
                $rule.Add($name, $value)
            }
        } # $_.Split("|") | ForEach-Object
        $rule
    } #$rulesRaw | ForEach-Object
}

The output is a list of hashtables where key names have been derived from the respective registry field names and the values are either strings or arrays of strings:

Get-GPOFirewallRules

Action                         Allow
GPOVERSION                     v2.10
Dir                            In
Desc                           Allow NSClient/NRPE connections from Nagios servers
Name                           NSClient++ Monitoring Agent
Active                         TRUE
RA4                            {192.168.21.55, 192.168.240.10, 192.168.240.11, 192.168.240.12}
App                            %ProgramFiles%\NSClient++\nscp.exe
Protocol                       6
LPort                          5666
GPOID                          {1FEFA84F-0779-4279-9C02-F5678C949304}

Action                         Allow
GPOVERSION                     v2.10
Dir                            In
Name                           Allow ICMP for Monitoring und Management     
Active                         TRUE
RA4                            {192.168.21.55, 192.168.3.60, 192.168.3.61, 192.168.8.0/255.255.255.0...}
ICMP4                          {3:*, 8:*, 11:*}
Protocol                       1
GPOID                          {6CA2C52C-6AD6-4513-B197-3702637BD9DF}

The naming scheme is different from what (New-object –comObject HNetCfg.FwPolicy2).rules is returning and the structure seems to be slightly different (and likely subject to change in future Windows versions) too, but it seems to serve its purpose for now.

the-wabbit
  • 40,737
  • 13
  • 111
  • 174