Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firewall: Fix issue #428 - DSC_Firewall #518

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Firewall
- Added `PolicyStore` parameter (defaults to PersistentStore to prevent a breaking change) and read only property `PolicyStoreSourceType` - fixes [Issue #428](https://github.com/dsccommunity/NetworkingDsc/issues/428).

### Changed

- Updated CHANGELOG.md
Expand Down
65 changes: 33 additions & 32 deletions source/DSCResources/DSC_Firewall/DSC_Firewall.data.psd1
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
@{
ParameterList = @(
@{ Name = 'Name'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'DisplayName'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'Group'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'DisplayGroup'; Variable = 'FirewallRule'; Type = '' }
@{ Name = 'Enabled'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'Action'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'Profile'; Variable = 'FirewallRule'; Type = 'Array'; Delimiter = ', ' }
@{ Name = 'Direction'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'Description'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'RemotePort'; Variable = 'properties'; Property = 'PortFilters'; Type = 'Array' }
@{ Name = 'LocalPort'; Variable = 'properties'; Property = 'PortFilters'; Type = 'Array' }
@{ Name = 'Protocol'; Variable = 'properties'; Property = 'PortFilters'; Type = 'String' }
@{ Name = 'Program'; Variable = 'properties'; Property = 'ApplicationFilters'; Type = 'String' }
@{ Name = 'Service'; Variable = 'properties'; Property = 'ServiceFilters'; Type = 'String' }
@{ Name = 'Authentication'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'String' }
@{ Name = 'Encryption'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'String' }
@{ Name = 'InterfaceAlias'; Variable = 'properties'; Property = 'InterfaceFilters'; Type = 'Array' }
@{ Name = 'InterfaceType'; Variable = 'properties'; Property = 'InterfaceTypeFilters'; Type = 'String' }
@{ Name = 'LocalAddress'; Variable = 'properties'; Property = 'AddressFilters'; Type = 'ArrayIP' }
@{ Name = 'LocalUser'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'String' }
@{ Name = 'Package'; Variable = 'properties'; Property = 'ApplicationFilters'; Type = 'String' }
@{ Name = 'Platform'; Variable = 'FirewallRule'; Type = 'Array' }
@{ Name = 'RemoteAddress'; Variable = 'properties'; Property = 'AddressFilters'; Type = 'ArrayIP' }
@{ Name = 'RemoteMachine'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'String' }
@{ Name = 'RemoteUser'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'String' }
@{ Name = 'DynamicTransport'; Variable = 'properties'; Property = 'PortFilters'; Type = 'String' }
@{ Name = 'EdgeTraversalPolicy'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'IcmpType'; Variable = 'properties'; Property = 'PortFilters'; Type = 'Array' }
@{ Name = 'LocalOnlyMapping'; Variable = 'FirewallRule'; Type = 'Boolean' }
@{ Name = 'LooseSourceMapping'; Variable = 'FirewallRule'; Type = 'Boolean' }
@{ Name = 'OverrideBlockRules'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'Boolean' }
@{ Name = 'Owner'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'Name'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'DisplayName'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'Group'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'DisplayGroup'; Variable = 'FirewallRule'; Type = '' }
@{ Name = 'Enabled'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'Action'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'Profile'; Variable = 'FirewallRule'; Type = 'Array'; Delimiter = ', ' }
@{ Name = 'Direction'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'Description'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'RemotePort'; Variable = 'properties'; Property = 'PortFilters'; Type = 'Array' }
@{ Name = 'LocalPort'; Variable = 'properties'; Property = 'PortFilters'; Type = 'Array' }
@{ Name = 'Protocol'; Variable = 'properties'; Property = 'PortFilters'; Type = 'String' }
@{ Name = 'Program'; Variable = 'properties'; Property = 'ApplicationFilters'; Type = 'String' }
@{ Name = 'Service'; Variable = 'properties'; Property = 'ServiceFilters'; Type = 'String' }
@{ Name = 'Authentication'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'String' }
@{ Name = 'Encryption'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'String' }
@{ Name = 'InterfaceAlias'; Variable = 'properties'; Property = 'InterfaceFilters'; Type = 'Array' }
@{ Name = 'InterfaceType'; Variable = 'properties'; Property = 'InterfaceTypeFilters'; Type = 'String' }
@{ Name = 'LocalAddress'; Variable = 'properties'; Property = 'AddressFilters'; Type = 'ArrayIP' }
@{ Name = 'LocalUser'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'String' }
@{ Name = 'Package'; Variable = 'properties'; Property = 'ApplicationFilters'; Type = 'String' }
@{ Name = 'Platform'; Variable = 'FirewallRule'; Type = 'Array' }
@{ Name = 'RemoteAddress'; Variable = 'properties'; Property = 'AddressFilters'; Type = 'ArrayIP' }
@{ Name = 'RemoteMachine'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'String' }
@{ Name = 'RemoteUser'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'String' }
@{ Name = 'DynamicTransport'; Variable = 'properties'; Property = 'PortFilters'; Type = 'String' }
@{ Name = 'EdgeTraversalPolicy'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'IcmpType'; Variable = 'properties'; Property = 'PortFilters'; Type = 'Array' }
@{ Name = 'LocalOnlyMapping'; Variable = 'FirewallRule'; Type = 'Boolean' }
@{ Name = 'LooseSourceMapping'; Variable = 'FirewallRule'; Type = 'Boolean' }
@{ Name = 'OverrideBlockRules'; Variable = 'properties'; Property = 'SecurityFilters'; Type = 'Boolean' }
@{ Name = 'Owner'; Variable = 'FirewallRule'; Type = 'String' }
@{ Name = 'PolicyStoreSourceType'; Variable = 'FirewallRule'; Type = 'String' } # Use this instead of PolicyStore as Get-NetFirewallRule does not include PoliyStore
)
}
88 changes: 72 additions & 16 deletions source/DSCResources/DSC_Firewall/DSC_Firewall.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ $script:parameterList = $script:resourceData.ParameterList

.PARAMETER Name
Name of the firewall rule.

.PARAMETER PolicyStore
Targets the policy store from which to retrieve the rules.
#>
function Get-TargetResource
{
Expand All @@ -45,7 +48,12 @@ function Get-TargetResource
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Name
$Name,

[Parameter()]
[ValidateSet('PersistentStore', 'localhost')]
[String]
$PolicyStore = 'PersistentStore'
)

$ErrorActionPreference = 'Stop'
Expand All @@ -57,7 +65,7 @@ function Get-TargetResource
$($script:localizedData.FindFirewallRuleMessage) -f $Name
) -join '')

$firewallRule = Get-FirewallRule -Name $Name
$firewallRule = Get-FirewallRule -Name $Name -PolicyStore $PolicyStore

if (-not $firewallRule)
{
Expand All @@ -70,7 +78,7 @@ function Get-TargetResource
}
}

$properties = Get-FirewallRuleProperty -FirewallRule $firewallRule
$properties = Get-FirewallRuleProperty -FirewallRule $firewallRule -PolicyStore $PolicyStore

$result = @{
Ensure = 'Present'
Expand Down Expand Up @@ -238,6 +246,9 @@ function Get-TargetResource

.PARAMETER Owner
Specifies that matching firewall rules of the indicated owner are created.

.PARAMETER PolicyStore
Specifies the policy store from which to retrieve the rules to be created.
#>
function Set-TargetResource
{
Expand Down Expand Up @@ -397,7 +408,12 @@ function Set-TargetResource
[Parameter()]
[ValidateNotNullOrEmpty()]
[String]
$Owner
$Owner,

[Parameter()]
[ValidateSet('PersistentStore', 'localhost')]
[String]
$PolicyStore = 'PersistentStore'
)

Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): "
Expand All @@ -410,7 +426,7 @@ function Set-TargetResource
Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): "
$($script:localizedData.FindFirewallRuleMessage) -f $Name
) -join '')
$firewallRule = Get-FirewallRule -Name $Name
$firewallRule = Get-FirewallRule -Name $Name -PolicyStore $PolicyStore

$exists = ($null -ne $firewallRule)

Expand Down Expand Up @@ -440,13 +456,13 @@ function Set-TargetResource
if ($PSBoundParameters.ContainsKey('Group') `
-and ($Group -ne $FirewallRule.Group))
{
Remove-NetFirewallRule -Name (ConvertTo-FirewallRuleNameEscapedString -Name $Name)
Remove-NetFirewallRule -Name (ConvertTo-FirewallRuleNameEscapedString -Name $Name) -PolicyStore $PolicyStore

<#
Merge the existing rule values into the PSBoundParameters
so that it can be splatted.
#>
$properties = Get-FirewallRuleProperty -FirewallRule $firewallRule
$properties = Get-FirewallRuleProperty -FirewallRule $firewallRule -PolicyStore $PolicyStore

<#
Loop through each possible property and if it is not passed as a parameter
Expand Down Expand Up @@ -532,7 +548,7 @@ function Set-TargetResource
) -join '')

# Remove the existing Firewall rule
Remove-NetFirewallRule -Name (ConvertTo-FirewallRuleNameEscapedString -Name $Name)
Remove-NetFirewallRule -Name (ConvertTo-FirewallRuleNameEscapedString -Name $Name) -PolicyStore $PolicyStore
}
else
{
Expand Down Expand Up @@ -660,6 +676,9 @@ function Set-TargetResource

.PARAMETER Owner
Specifies that matching firewall rules of the indicated owner are created.

.PARAMETER PolicyStore
Specifies the policy store from which to retrieve the rules to be created.
#>
function Test-TargetResource
{
Expand Down Expand Up @@ -820,7 +839,12 @@ function Test-TargetResource
[Parameter()]
[ValidateNotNullOrEmpty()]
[String]
$Owner
$Owner,

[Parameter()]
[ValidateSet('PersistentStore', 'localhost')]
[String]
$PolicyStore = 'PersistentStore'
)

Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): "
Expand All @@ -834,7 +858,7 @@ function Test-TargetResource
$($script:localizedData.FindFirewallRuleMessage) -f $Name
) -join '')

$firewallRule = Get-FirewallRule -Name $Name
$firewallRule = Get-FirewallRule -Name $Name -PolicyStore $PolicyStore

$exists = ($null -ne $firewallRule)

Expand Down Expand Up @@ -989,6 +1013,12 @@ function Test-TargetResource

.PARAMETER Owner
Specifies that matching firewall rules of the indicated owner are created.

.PARAMETER PolicyStore
Specifies the policy store from which to retrieve the rules to be created.

.PARAMETER PolicyStoreSourceType
Specifies that firewall rules that match the indicated policy store source type are retrieved.
#>
function Test-RuleProperties
{
Expand Down Expand Up @@ -1139,10 +1169,20 @@ function Test-RuleProperties

[Parameter()]
[String]
$Owner
$Owner,

[Parameter()]
[ValidateSet('PersistentStore', 'localhost')]
[String]
$PolicyStore = 'PersistentStore',

[Parameter()]
[ValidateSet('None', 'Local', 'GroupPolicy', 'Dynamic', 'Generated', 'Hardcoded')]
[String]
$PolicyStoreSourceType
)

$properties = Get-FirewallRuleProperty -FirewallRule $FirewallRule
$properties = Get-FirewallRuleProperty -FirewallRule $FirewallRule -PolicyStore $PolicyStore
$desiredConfigurationMatch = $true

<#
Expand Down Expand Up @@ -1242,6 +1282,9 @@ function Test-RuleProperties

.PARAMETER Name
The name of the Firewall Rule to Retrieve.

.PARAMETER PolicyStore
Specifies the policy store from which to retrieve the rules to be created.
#>
function Get-FirewallRule
{
Expand All @@ -1252,10 +1295,15 @@ function Get-FirewallRule
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Name
$Name,

[Parameter()]
[ValidateSet('PersistentStore', 'localhost')]
[String]
$PolicyStore = 'PersistentStore'
)

$firewallRule = @(Get-NetFirewallRule -Name (ConvertTo-FirewallRuleNameEscapedString -Name $Name) -ErrorAction SilentlyContinue)
$firewallRule = @(Get-NetFirewallRule -Name (ConvertTo-FirewallRuleNameEscapedString -Name $Name) -PolicyStore $PolicyStore -ErrorAction SilentlyContinue)

if (-not $firewallRule)
{
Expand Down Expand Up @@ -1285,6 +1333,9 @@ function Get-FirewallRule

.PARAMETER FirewallRule
The firewall rule object to pull the additional firewall objects for.

.PARAMETER PolicyStore
Specifies the policy store from which to retrieve the rules to be created.
#>
function Get-FirewallRuleProperty
{
Expand All @@ -1293,7 +1344,12 @@ function Get-FirewallRuleProperty
param
(
[Parameter(Mandatory = $true)]
$FirewallRule
$FirewallRule,

[Parameter()]
[ValidateSet('PersistentStore', 'localhost')]
[String]
$PolicyStore = 'PersistentStore'
)

Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): "
Expand Down Expand Up @@ -1371,7 +1427,7 @@ function ConvertTo-FirewallRuleNameEscapedString
$Name
)

return $Name.Replace('[','`[').Replace(']','`]').Replace('*','`*')
return $Name.Replace('[', '`[').Replace(']', '`]').Replace('*', '`*')
}

Export-ModuleMember -Function *-TargetResource
2 changes: 2 additions & 0 deletions source/DSCResources/DSC_Firewall/DSC_Firewall.schema.mof
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ class DSC_Firewall : OMI_BaseResource
[Write, Description("Indicates that matching firewall rules of the indicated value are created.")] Boolean LooseSourceMapping;
[Write, Description("Indicates that matching network traffic that would otherwise be blocked are allowed.")] Boolean OverrideBlockRules;
[Write, Description("Specifies that matching firewall rules of the indicated owner are created.")] String Owner;
[Write, Description("Specifies the policy store from which to retrieve the rules to be created."), ValueMap{"PersistentStore", "localhost"},Values{"PersistentStore", "localhost"}] String PolicyStore;
[Read, Description("Specifies that firewall rules that match the indicated policy store source type are retrieved.")] String PolicyStoreSourceType;
[Read, Description("The current value of the Display Group of the Firewall Rule.")] string DisplayGroup;
};