DSCResources/DSC_DnsClientNrptRule/DSC_DnsClientNrptRule.psm1
$modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'Modules' # Import the Networking Common Modules Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'NetworkingDsc.Common' ` -ChildPath 'NetworkingDsc.Common.psm1')) Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') # Import Localization Strings $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' # This must be a script parameter so that it is accessible $script:dnsPolicyConfigRegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters\DnsPolicyConfig' <# .SYNOPSIS Returns the current state of a DNS Client NRPT Rule. .PARAMETER Name Specifies the name which uniquely identifies a rule. #> function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $Name ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.GettingNrptRuleMessage) ` -f $Name ` ) -join '' ) # Lookup the existing NrptRule $NrptRule = Get-NrptRule -Name $Name $returnValue = @{ Name = $Name } if ($NrptRule) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NrptRuleExistsMessage) ` -f $Name ` ) -join '' ) $returnValue += @{ Ensure = 'Present' Comment = [System.String] $NrptRule.Comment DAEnable = [System.Boolean] $NrptRule.DAEnable DAIPsecEncryptionType = [System.String] $NrptRule.DAIPsecEncryptionType DAIPsecRequired = [System.Boolean] $NrptRule.DAIPsecRequired DANameServers = [System.String[]] $NrptRule.DANameServers DAProxyServerName = [System.String] $NrptRule.DAProxyServerName DAProxyType = [System.String] $NrptRule.DAProxyType DisplayName = [System.String] $NrptRule.DisplayName DnsSecEnable = [System.Boolean] $NrptRule.DnsSecEnable DnsSecIPsecEncryptionType = [System.String] $NrptRule.DnsSecIPsecEncryptionType DnsSecIPsecRequired = [System.Boolean] $NrptRule.DnsSecIPsecRequired DnsSecValidationRequired = [System.Boolean] $NrptRule.DnsSecValidationRequired IPsecTrustAuthority = [System.String] $NrptRule.IPsecTrustAuthority NameEncoding = [System.String] $NrptRule.NameEncoding NameServers = [System.String[]] $NrptRule.NameServers Namespace = [System.String] $NrptRule.Namespace } } else { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NrptRuleDoesNotExistMessage) ` -f $Name ` ) -join '' ) $returnValue += @{ Ensure = 'Absent' } } return $returnValue } # Get-TargetResource <# .SYNOPSIS Sets a NRPT Rule. .PARAMETER Name Specifies the name which uniquely identifies a rule. .PARAMETER Comment Stores administrator notes. .PARAMETER DAEnable Indicates the rule state for DirectAccess. .PARAMETER DAIPsecEncryptionType Specifies the Internet Protocol security (IPsec) encryption setting for DirectAccess. .PARAMETER DAIPsecRequired Indicates that IPsec is required for DirectAccess. .PARAMETER DANameServers Specifies an array of DNS servers to query when DirectAccess is enabled. .PARAMETER DAProxyServerName "Specifies the proxy server to use when connecting to the Internet. This parameter is only applicable if the DAProxyType parameter is set to UseProxyName. .PARAMETER DAProxyType Specifies the proxy server type to be used when connecting to the Internet. .PARAMETER DisplayName Specifies an optional friendly name for the NRPT rule. .PARAMETER DnsSecEnable Enables Domain Name System Security Extensions (DNSSEC) on the rule. .PARAMETER DnsSecIPsecEncryptionType Specifies the IPsec tunnel encryption setting. .PARAMETER DnsSecIPsecRequired Indicates the DNS client must set up an IPsec connection to the DNS server. .PARAMETER DnsSecValidationRequired Indicates that DNSSEC validation is required. .PARAMETER IPsecTrustAuthority Specifies the certification authority to validate the IPsec channel. .PARAMETER NameEncoding Specifies the encoding format for host names in the DNS query. .PARAMETER NameServers Specifies the DNS servers to which the DNS query is sent when DirectAccess is disabled. .PARAMETER Namespace Specifies the DNS namespace. #> function Set-TargetResource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $Name, [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', [Parameter()] [System.String] $Comment, [Parameter()] [System.Boolean] $DAEnable, [Parameter()] [ValidateSet('None', 'Low', 'Medium', 'High')] [System.String] $DAIPsecEncryptionType, [Parameter()] [System.Boolean] $DAIPsecRequired, [Parameter()] [System.String[]] $DANameServers, [Parameter()] [System.String] $DAProxyServerName, [Parameter()] [ValidateSet('NoProxy', 'UseDefault', 'UseProxyName')] [System.String] $DAProxyType, [Parameter()] [System.String] $DisplayName, [Parameter()] [System.Boolean] $DnsSecEnable, [Parameter()] [ValidateSet('None', 'Low', 'Medium', 'High')] [System.String] $DnsSecIPsecEncryptionType, [Parameter()] [System.Boolean] $DnsSecIPsecRequired, [Parameter()] [System.Boolean] $DnsSecValidationRequired, [Parameter()] [System.String] $IPsecTrustAuthority, [Parameter()] [ValidateSet('Disable', 'Utf8WithMapping', 'Utf8WithoutMapping', 'Punycode')] [System.String] $NameEncoding, [Parameter()] [System.String[]] $NameServers, [Parameter()] [System.String] $Namespace ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.SettingNrptRuleMessage) ` -f $Name ` ) -join '' ) # Remove any parameters that can't be splatted. $null = $PSBoundParameters.Remove('Ensure') # Lookup the existing NrptRule $NrptRule = Get-NrptRule -Name $Name if ($Ensure -eq 'Present') { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.EnsureNrptRuleExistsMessage) ` -f $Name ` ) -join '' ) if ($NrptRule) { # The NrptRule exists - update it Set-DnsClientNrptRule @PSBoundParameters ` -ErrorAction Stop Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NrptRuleUpdatedMessage) ` -f $Name ` ) -join '' ) } else { # The NrptRule does not exit - create it Add-NrptRule @PSBoundParameters ` -ErrorAction Stop Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NrptRuleCreatedMessage) ` -f $Name ` ) -join '' ) } } else { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.EnsureNrptRuleDoesNotExistMessage) ` -f $Name ` ) -join '' ) if ($NrptRule) { <# The NrptRule exists - remove it Use Force as confirm does not work in DnsClientNrptRule #> Remove-DnsClientNrptRule -Name $Name ` -Force ` -ErrorAction Stop Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NrptRuleRemovedMessage) ` -f $Name ` ) -join '' ) } # if } # if } # Set-TargetResource <# .SYNOPSIS Tests the state of a NRPT Rule. .PARAMETER Name Specifies the name which uniquely identifies a rule. .PARAMETER Comment Stores administrator notes. .PARAMETER DAEnable Indicates the rule state for DirectAccess. .PARAMETER DAIPsecEncryptionType Specifies the Internet Protocol security (IPsec) encryption setting for DirectAccess. .PARAMETER DAIPsecRequired Indicates that IPsec is required for DirectAccess. .PARAMETER DANameServers Specifies an array of DNS servers to query when DirectAccess is enabled. .PARAMETER DAProxyServerName "Specifies the proxy server to use when connecting to the Internet. This parameter is only applicable if the DAProxyType parameter is set to UseProxyName. .PARAMETER DAProxyType Specifies the proxy server type to be used when connecting to the Internet. .PARAMETER DisplayName Specifies an optional friendly name for the NRPT rule. .PARAMETER DnsSecEnable Enables Domain Name System Security Extensions (DNSSEC) on the rule. .PARAMETER DnsSecIPsecEncryptionType Specifies the IPsec tunnel encryption setting. .PARAMETER DnsSecIPsecRequired Indicates the DNS client must set up an IPsec connection to the DNS server. .PARAMETER DnsSecValidationRequired Indicates that DNSSEC validation is required. .PARAMETER IPsecTrustAuthority Specifies the certification authority to validate the IPsec channel. .PARAMETER NameEncoding Specifies the encoding format for host names in the DNS query. .PARAMETER NameServers Specifies the DNS servers to which the DNS query is sent when DirectAccess is disabled. .PARAMETER Namespace Specifies the DNS namespace. #> function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $Name, [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', [Parameter()] [System.String] $Comment, [Parameter()] [System.Boolean] $DAEnable, [Parameter()] [ValidateSet('None', 'Low', 'Medium', 'High')] [System.String] $DAIPsecEncryptionType, [Parameter()] [System.Boolean] $DAIPsecRequired, [Parameter()] [System.String[]] $DANameServers, [Parameter()] [System.String] $DAProxyServerName, [Parameter()] [ValidateSet('NoProxy', 'UseDefault', 'UseProxyName')] [System.String] $DAProxyType, [Parameter()] [System.String] $DisplayName, [Parameter()] [System.Boolean] $DnsSecEnable, [Parameter()] [ValidateSet('None', 'Low', 'Medium', 'High')] [System.String] $DnsSecIPsecEncryptionType, [Parameter()] [System.Boolean] $DnsSecIPsecRequired, [Parameter()] [System.Boolean] $DnsSecValidationRequired, [Parameter()] [System.String] $IPsecTrustAuthority, [Parameter()] [ValidateSet('Disable', 'Utf8WithMapping', 'Utf8WithoutMapping', 'Punycode')] [System.String] $NameEncoding, [Parameter()] [System.String[]] $NameServers, [Parameter()] [System.String] $Namespace ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.TestingNrptRuleMessage) ` -f $Name ` ) -join '' ) # Flag to signal whether settings are correct [System.Boolean] $desiredConfigurationMatch = $true # Remove any parameters that can't be splatted. $null = $PSBoundParameters.Remove('Ensure') # Check the parameters # Assert-ResourceProperty @PSBoundParameters # Lookup the existing NrptRule $NrptRule = Get-NrptRule -Name $Name if ($Ensure -eq 'Present') { # The NrptRule should exist if ($NrptRule) { # The NrptRule exists and does - but check the parameters $currentState = Get-TargetResource -Name $Name return Test-DscParameterState -CurrentValues $currentState -DesiredValues $PSBoundParameters } else { # The NrptRule doesn't exist but should Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NrptRuleDoesNotExistButShouldMessage) ` -f $Name ` ) -join '' ) $desiredConfigurationMatch = $false } } else { # The NrptRule should not exist if ($NrptRule) { # The NrptRule exists but should not Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NrptRuleExistsButShouldNotMessage) ` -f $Name ` ) -join '' ) $desiredConfigurationMatch = $false } else { # The NrptRule does not exist and should not Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NrptRuleDoesNotExistAndShouldNotMessage) ` -f $Name ` ) -join '' ) } } # if return $desiredConfigurationMatch } # Test-TargetResource <# .SYNOPSIS This function looks up DNS Client NRPT Rule using the parameters and returns it. If the rule is not found $null is returned. .PARAMETER Name Specifies the name which uniquely identifies a rule. #> function Get-NrptRule { param ( [Parameter()] [System.String] $Name ) try { $nrptRule = Get-DnsClientNrptRule ` -Name $Name ` -ErrorAction SilentlyContinue } catch [Microsoft.PowerShell.Cmdletization.Cim.CimJobException] { $nrptRule = $null } catch { throw $_ } return $nrptRule } <# .SYNOPSIS This function create a DNS Client NRPT Rule using the parameters. This is a dedicated function adding the Rule Name parameter as the built-in Add-DnsClientNrptRule cmdlet does not support it. .PARAMETER Name Specifies the name which uniquely identifies a rule. .PARAMETER Comment Stores administrator notes. .PARAMETER DAEnable Indicates the rule state for DirectAccess. .PARAMETER DAIPsecEncryptionType Specifies the Internet Protocol security (IPsec) encryption setting for DirectAccess. .PARAMETER DAIPsecRequired Indicates that IPsec is required for DirectAccess. .PARAMETER DANameServers Specifies an array of DNS servers to query when DirectAccess is enabled. .PARAMETER DAProxyServerName "Specifies the proxy server to use when connecting to the Internet. This parameter is only applicable if the DAProxyType parameter is set to UseProxyName. .PARAMETER DAProxyType Specifies the proxy server type to be used when connecting to the Internet. .PARAMETER DisplayName Specifies an optional friendly name for the NRPT rule. .PARAMETER DnsSecEnable Enables Domain Name System Security Extensions (DNSSEC) on the rule. .PARAMETER DnsSecIPsecEncryptionType Specifies the IPsec tunnel encryption setting. .PARAMETER DnsSecIPsecRequired Indicates the DNS client must set up an IPsec connection to the DNS server. .PARAMETER DnsSecValidationRequired Indicates that DNSSEC validation is required. .PARAMETER IPsecTrustAuthority Specifies the certification authority to validate the IPsec channel. .PARAMETER NameEncoding Specifies the encoding format for host names in the DNS query. .PARAMETER NameServers Specifies the DNS servers to which the DNS query is sent when DirectAccess is disabled. .PARAMETER Namespace Specifies the DNS namespace. #> function Add-NrptRule { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $Name, [Parameter()] [System.String] $Comment, [Parameter()] [System.Boolean] $DAEnable, [Parameter()] [ValidateSet('None', 'Low', 'Medium', 'High')] [System.String] $DAIPsecEncryptionType, [Parameter()] [System.Boolean] $DAIPsecRequired, [Parameter()] [System.String[]] $DANameServers, [Parameter()] [System.String] $DAProxyServerName, [Parameter()] [ValidateSet('NoProxy', 'UseDefault', 'UseProxyName')] [System.String] $DAProxyType, [Parameter()] [System.String] $DisplayName, [Parameter()] [System.Boolean] $DnsSecEnable, [Parameter()] [ValidateSet('None', 'Low', 'Medium', 'High')] [System.String] $DnsSecIPsecEncryptionType, [Parameter()] [System.Boolean] $DnsSecIPsecRequired, [Parameter()] [System.Boolean] $DnsSecValidationRequired, [Parameter()] [System.String] $IPsecTrustAuthority, [Parameter()] [ValidateSet('Disable', 'Utf8WithMapping', 'Utf8WithoutMapping', 'Punycode')] [System.String] $NameEncoding, [Parameter()] [System.String[]] $NameServers, [Parameter()] [System.String] $Namespace ) # Remove Name parameter as Add-DnsClientNrptRule cmdlet doesn't support it $null = $PSBoundParameters.Remove("Name") # The NrptRule does not exit - create it (PassThru to get the name of the rule created) $NrptRuleName = (Add-DnsClientNrptRule @PSBoundParameters -PassThru).Name # If rule has been created, rename it by registry as Name cannot be provided in Add-DnsClientNrptRule cmdlet if (Test-IsGuid -InputValue $NrptRuleName) { # Rename the registry key Rename-Item -Path "$($script:dnsPolicyConfigRegistryPath)\$($NrptRuleName)" ` -NewName $Name ` -ErrorAction Stop } } <# .SYNOPSIS This function check if the string provided is a GUID. .PARAMETER InputValue Specifies the value to test. #> function Test-IsGuid { [OutputType([System.Boolean])] param ( [Parameter()] [System.String] $InputValue ) try { # Attempt to parse the string as a GUID [void][Guid]::Parse($InputValue) # If successful, return true return $true } catch { # If an exception is thrown, the string is not a valid GUID return $false } } Export-ModuleMember -Function *-TargetResource |