Created
June 25, 2015 16:42
-
-
Save jeffpatton1971/d21e4248bb372983052c to your computer and use it in GitHub Desktop.
This function creates a FWRule ComObject that can be added to the firewall.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Function New-FirewallRule | |
{ | |
<# | |
.SYNOPSIS | |
Creates a new HFnetCfg.FWRule ComObject | |
.DESCRIPTION | |
This function creates a FWRule ComObject that can be added to the firewall. | |
Each time you change a property of a rule, Windows Firewall commits the rule and verifies it for correctness. | |
As a result, when you edit a rule, you must perform the steps in a specific order. For example, if you add an ICMP | |
rule, you must first set the protocol to ICMP, then add the rule. If these steps are taken in the opposite order, an | |
error occurs and the change is lost. If you are editing a TCP port rule and converting it into an ICMP rule, first | |
delete the port, change protocol from TCP to ICMP, and then add the rule. | |
In order to retrieve and modify existing rules, instances of this interface must be retrieved through INetFwRules. | |
All configuration changes take place immediately. | |
When accessing the properties of a rule, keep in mind that there may be a small time lag before a newly-added | |
rule is applied. | |
Properties are used to create firewall rules. Many of the properties can be used in order to create very specific | |
firewall rules. | |
.PARAMETER Name | |
Specifies the friendly name of this rule. The string must not contain the "|" character. | |
.PARAMETER Action | |
Specifies the action for a rule or default setting. | |
.PARAMETER ApplicationName | |
Specifies the friendly name of the application to which this rule applies. | |
.PARAMETER Description | |
Specifies the description of this rule. The string must not contain the "|" character. | |
.PARAMETER Direction | |
Specifies the direction of traffic for which the rule applies. If this property is not specified, the default value is in. | |
.PARAMETER EdgeTraversal | |
Indicates whether edge traversal is enabled or disabled for this rule. | |
The EdgeTraversal property indicates that specific inbound traffic is allowed to tunnel through NATs and other edge devices | |
using the Teredo tunneling technology. In order for this setting to work correctly, the application or service with the | |
inbound firewall rule needs to support IPv6. The primary application of this setting allows listeners on the host to be | |
globally addressable through a Teredo IPv6 address. | |
New rules have the EdgeTraversal property disabled by default. | |
.PARAMETER Enabled | |
Enables or disables a rule. A new rule is disabled by default. | |
.PARAMETER Grouping | |
Specifies the group to which an individual rule belongs. | |
Using the Grouping property is highly recommended, as it groups multiple rules into a single line in the Windows Firewall | |
control panel. This allows the user to enable or disable multiple rules with a single click. The Grouping property can | |
also be specified using indirect strings. In this case, a group description can also be specified that will appear in the | |
rule group properties in the Windows Firewall control panel. For example, if the group string is specified by an indirect | |
string at index 1005 ("@yourresources.dll,-1005"), the group description can be specified at a resource string higher | |
by 10000 "@youresources.dll,-11005." | |
When indirect strings in the form of "h" are passed as parameters to the Windows Firewall with Advanced Security APIs, | |
they should either be placed under the System32 Windows directory or specified by a full path. Further, the file should | |
have a secure access that permits the Local Service account read access to allow the Windows Firewall Service to read the | |
strings. To avoid non-privileged security principals from modifying the strings, the DLLs should only allow write access | |
to the Administrator account. | |
.PARAMETER IcmpTypesAndCodes | |
Specifies the list of ICMP types and codes for this rule. The icmpTypesAndCodes parameter is a list of ICMP types and codes | |
separated by semicolon. "*" indicates all ICMP types and codes. | |
.PARAMETER Interfaces | |
Specifies the list of interfaces for which the rule applies. The interfaces in the list are represented by their friendly name. | |
.PARAMETER InterfaceTypes | |
Specifies the list of interface types for which the rule applies. Acceptable values for this property are "RemoteAccess", | |
"Wireless", "Lan", and "All". If more than one interface type is specified, the strings must be separated by a comma. | |
.PARAMETER LocalAddresses | |
Specifies the list of local addresses for this rule. | |
The localAddrs parameter consists of one or more comma-delimited tokens specifying the local addresses from which the application | |
can listen for traffic. "*" is the default value. Valid tokens include: | |
- "*" indicates any local address. If present, this must be the only token included. | |
- "Defaultgateway" | |
- "DHCP" | |
- "WINS" | |
- "LocalSubnet" indicates any local address on the local subnet. This token is not case-sensitive. | |
- A subnet can be specified using either the subnet mask or network prefix notation. If neither a | |
subnet mask not a network prefix is specified, the subnet mask defaults to 255.255.255.255. | |
- A valid IPv6 address. | |
- An IPv4 address range in the format of "start address - end address" with no spaces included. | |
- An IPv6 address range in the format of "start address - end address" with no spaces included. | |
.PARAMETER LocalPorts | |
Specifies the list of local ports for this rule. The Protocol property must be set before the LocalPorts property or an error will be returned. | |
.PARAMETER Protocol | |
Specifies the IP protocol of this rule. The Protocol property must be set before the LocalPorts or RemotePorts properties or an error will be returned. | |
.PARAMETER Profiles | |
Specifies the profiles to which the rule belongs. | |
.PARAMETER RemoteAddresses | |
Specifies the list of remote addresses for this rule. | |
The remoteAddrs parameter consists of one or more comma-delimited tokens specifying the remote addresses from which the application | |
can listen for traffic. The default value is "*". Valid tokens include: | |
- "*" indicates any remote address. If present, this must be the only token included. | |
- "Defaultgateway" | |
- "DHCP" | |
- "DNS" | |
- "WINS" | |
- "LocalSubnet" indicates any local address on the local subnet. This token is not case-sensitive. | |
- A subnet can be specified using either the subnet mask or network prefix notation. If neither a | |
subnet mask not a network prefix is specified, the subnet mask defaults to 255.255.255.255. | |
- A valid IPv6 address. | |
- An IPv4 address range in the format of "start address - end address" with no spaces included. | |
- An IPv6 address range in the format of "start address - end address" with no spaces included. | |
.PARAMETER RemotePorts | |
Specifies the list of remote ports for this rule. The Protocol property must be set before the RemotePorts property or an error will be returned. | |
.PARAMETER ServiceName | |
Specifies the service name property of the application. A serviceName value of "*" indicates that a service, not an application, must | |
be sending or receiving traffic. | |
#> | |
[CmdletBinding()] | |
[OutputType([__ComObject])] | |
Param | |
( | |
[Parameter(Position=0,Mandatory=$true)] | |
[ValidateScript({(!($_.Contains('|')) -and !($_.ToLower().Contains('any')))})] | |
[string]$Name, | |
[Parameter(Position=1,Mandatory=$false)] | |
[ValidateScript({(!($_.ToLower().Contains('any')))})] | |
[string]$Description, | |
[Parameter(Position=2,Mandatory=$false)] | |
[string]$ApplicationName, | |
[Parameter(Position=3,Mandatory=$false)] | |
[string]$ServiceName, | |
[Parameter(Position=4,Mandatory=$false)] | |
[ValidateSet('ICMPv4','IGMP','TCP','UDP','IPv6','IPv6Route','IPv6Frag','GRE','ICMPv6','IPv6NoNxt','IPv6Opts','VRRP','PGM','L2TP')] | |
[String]$Protocol, | |
[Parameter(Position=5,Mandatory=$false)] | |
[string[]]$LocalPorts, | |
[Parameter(Position=6,Mandatory=$false)] | |
[string[]]$RemotePorts, | |
[Parameter(Position=7,Mandatory=$false)] | |
[string[]]$LocalAddresses = @('*'), | |
[Parameter(Position=8,Mandatory=$false)] | |
[string[]]$RemoteAddresses = @('*'), | |
[Parameter(Position=7,Mandatory=$false)] | |
[string]$IcmpTypesAndCodes, | |
[Parameter(Position=9,Mandatory=$false)] | |
[ValidateSet('In','Out')] | |
[string]$Direction = 'In', | |
[Parameter(Position=10,Mandatory=$false)] | |
[string]$Interfaces, | |
[Parameter(Position=11,Mandatory=$false)] | |
[ValidateSet('RemoteAccess','Wireless','Lan','All')] | |
[string[]]$InterfaceTypes, | |
[Parameter(Position=12,Mandatory=$false)] | |
[bool]$Enabled = $false, | |
[Parameter(Position=13,Mandatory=$false)] | |
[string]$Grouping, | |
[Parameter(Position=14,Mandatory=$false)] | |
[ValidateSet('Domain','Private','Public','Any')] | |
[string[]]$Profiles, | |
[Parameter(Position=15,Mandatory=$false)] | |
[bool]$EdgeTraversal = $false, | |
[Parameter(Position=16,Mandatory=$false)] | |
[ValidateSet('Allow','Block')] | |
[string]$Action | |
) | |
Begin | |
{ | |
$ProtocolLookup = @{'ICMPv4'=1;'IGMP'=2;'TCP'=6;'UDP'=17;'IPv6'=41;'IPv6Route'=43;'IPv6Frag'=44;'GRE'=47;'ICMPv6'=48;'IPv6NoNxt'=59;'IPv6Opts'=60;'VRRP'=112;'PGM'=113;'L2TP'=115}; | |
$ProfileLookup = @{'Domain'=1; 'Private'=2;'Public'=4}; | |
} | |
Process | |
{ | |
try | |
{ | |
$Error.Clear(); | |
$ErrorActionPreference = 'Stop'; | |
$Rule = New-Object -ComObject "HNetCfg.FWRule"; | |
switch ($Action) | |
{ | |
'Allow' | |
{ | |
$Rule.Action = 1; | |
} | |
'Block' | |
{ | |
$Rule.Action = 0; | |
} | |
} | |
$Rule.ApplicationName = $ApplicationName; | |
$Rule.Description = $Description; | |
switch ($Direction) | |
{ | |
'In' | |
{ | |
$Rule.Direction = 1; | |
} | |
'Out' | |
{ | |
$Rule.Direction = 0; | |
} | |
} | |
$Rule.EdgeTraversal = $EdgeTraversal; | |
$Rule.Enabled = $Enabled; | |
$Rule.Grouping = $Grouping; | |
if ($IcmpTypesAndCodes) | |
{ | |
$Rule.IcmpTypesAndCodes = $IcmpTypesAndCodes; | |
} | |
if ($Interfaces) | |
{ | |
$Rule.Interfaces = $Interfaces; | |
} | |
$Rule.InterfaceTypes = $InterfaceTypes; | |
$Rule.LocalAddresses = [System.String]::Join(',',$LocalAddresses); | |
$Rule.Protocol = $ProtocolLookup.Keys |Where-Object {$_ -eq $Protocol} |ForEach-Object {$ProtocolLookup.Item($_)}; | |
if ($LocalPorts) | |
{ | |
$Rule.LocalPorts = $LocalPorts; | |
} | |
$Rule.Name = $Name; | |
if ($Profiles) | |
{ | |
[int]$Count = 0; | |
foreach ($P in $Profiles) | |
{ | |
$Count += $ProfileLookup.Keys |Where-Object {$_ -eq $P} |ForEach-Object {$ProfileLookup.Item($_)}; | |
} | |
$Rule.Profiles = $Count; | |
if ($Profiles.Contains('Any')) | |
{ | |
$Rule.Profiles = 2147483647; | |
} | |
} | |
$Rule.RemoteAddresses = [System.String]::Join(',',$RemoteAddresses); | |
if ($RemotePorts) | |
{ | |
$Rule.RemotePorts = $RemotePorts; | |
} | |
$Rule.serviceName = $ServiceName; | |
return $Rule; | |
} | |
catch | |
{ | |
throw $_ | |
} | |
} | |
End | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment