DSCResources/MSFT_xDFSNamespaceRoot/MSFT_xDFSNamespaceRoot.psm1
data LocalizedData { # culture="en-US" ConvertFrom-StringData -StringData @' GettingNamespaceRootMessage=Getting {0} DFS Namespace Root "{1}" Target "{2}". NamespaceRootExistsMessage={0} DFS Namespace Root "{1}" exists. NamespaceRootDoesNotExistMessage={0} DFS Namespace Root "{1}" does not exist. NamespaceRootTargetExistsMessage={0} DFS Namespace Root "{1}" target "{2}" exists. NamespaceRootTargetDoesNotExistMessage={0} DFS Namespace Root "{1}" target "{2}" does not exist. SettingNamespaceRootMessage=Setting {0} DFS Namespace Root "{1}" Target "{2}". NamespaceRootUpdateParameterMessage=Setting {0} DFS Namespace Root "{1}" parameter {3} to "{4}". NamespaceRootTargetUpdateParameterMessage=Setting {0} DFS Namespace Root "{1}" Target "{2}" parameter {3} to "{4}". NamespaceRootCreatedMessage={0} DFS Namespace Root "{1}" Target "{2}" created. NamespaceRootTargetRemovedMessage={0} DFS Namespace Root "{1}" Target "{2}" removed. TestingNamespaceRootMessage=Testing {0} DFS Namespace Root "{1}" Target "{2}". NamespaceRootTypeConversionError=Error- {0} DFS Namespace can not be added to a {3} DFS Namespace. NamespaceRootParameterNeedsUpdateMessage={0} DFS Namespace Root "{1}" {3} is different. Change required. NamespaceRootTargetParameterNeedsUpdateMessage={0} DFS Namespace Root "{1}" Target "{2}" {3} is different. Change required. NamespaceRootDoesNotExistButShouldMessage={0} DFS Namespace Root "{1}" does not exist but should. Change required. NamespaceRootTargetExistsButShouldNotMessage={0} DFS Namespace Root "{1}" Target "{2}" exists but should not. Change required. NamespaceRootTargetDoesNotExistButShouldMessage={0} DFS Namespace Root "{1}" Target "{2}" does not exist but should. Change required. NamespaceRootDoesNotExistAndShouldNotMessage={0} DFS Namespace Root "{1}" does not exist and should not. Change not required. NamespaceRootTargetDoesNotExistAndShouldNotMessage={0} DFS Namespace Root "{1}" Target "{2}" does not exist and should not. Change not required. '@ } function Get-TargetResource { [CmdletBinding()] [OutputType([Hashtable])] param ( [parameter(Mandatory = $true)] [String] $Path, [parameter(Mandatory = $true)] [String] $TargetPath, [parameter(Mandatory = $true)] [ValidateSet('Present','Absent')] [String] $Ensure, [parameter(Mandatory = $true)] [ValidateSet('Standalone','DomainV1','DomainV2')] [String] $Type ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.GettingNamespaceRootMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) # Generate the return object assuming absent. $ReturnValue = @{ Path = $Path TargetPath = $TargetPath Ensure = 'Absent' Type = $Type } # Remove the Ensue parmeter from the bound parameters $null = $PSBoundParameters.Remove('Ensure') # Lookup the existing Namespace root $Root = Get-Root ` -Path $Path if ($Root) { # The namespace exists Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootExistsMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) } else { # The namespace does not exist Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootDoesNotExistMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) return $ReturnValue } $ReturnValue += @{ TimeToLiveSec = $Root.TimeToLiveSec State = $Root.State Description = $Root.Description EnableSiteCosting = ($Root.Flags -contains 'Site Costing') EnableInsiteReferrals = ($Root.Flags -contains 'Insite Referrals') EnableAccessBasedEnumeration = ($Root.Flags -contains 'AccessBased Enumeration') EnableRootScalability = ($Root.Flags -contains 'Root Scalability') EnableTargetFailback = ($Root.Flags -contains 'Target Failback') } # DFS Root exists but does target exist? $Target = Get-RootTarget ` -Path $Path ` -TargetPath $TargetPath if ($Target) { # The target exists in this namespace $ReturnValue.Ensure = 'Present' $ReturnValue += @{ ReferralPriorityClass = $Target.ReferralPriorityClass ReferralPriorityRank = $Target.ReferralPriorityRank } Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootTargetExistsMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) } else { # The target does not exist in this namespace Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootTargetDoesNotExistMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) } return $ReturnValue } # Get-TargetResource function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [String] $Path, [parameter(Mandatory = $true)] [String] $TargetPath, [parameter(Mandatory = $true)] [ValidateSet('Present','Absent')] [String] $Ensure, [parameter(Mandatory = $true)] [ValidateSet('Standalone','DomainV1','DomainV2')] [String] $Type, [String] $Description, [Uint32] $TimeToLiveSec, [Boolean] $EnableSiteCosting, [Boolean] $EnableInsiteReferrals, [Boolean] $EnableAccessBasedEnumeration, [Boolean] $EnableRootScalability, [Boolean] $EnableTargetFailback, [ValidateSet('Global-High','SiteCost-High','SiteCost-Normal','SiteCost-Low','Global-Low')] [String] $ReferralPriorityClass, [Uint32] $ReferralPriorityRank ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.SettingNamespaceRootMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) # Lookup the existing Namespace root $Root = Get-Root ` -Path $Path if ($Ensure -eq 'Present') { # Set desired Configuration if ($Root) { # Does the root need to be updated? [boolean] $RootChange = $false # The root properties that will be updated $RootProperties = @{ State = 'online' } if (($Description) ` -and ($Root.Description -ne $Description)) { $RootProperties += @{ Description = $Description } $RootChange = $true } if (($TimeToLiveSec) ` -and ($Root.TimeToLiveSec -ne $TimeToLiveSec)) { $RootProperties += @{ TimeToLiveSec = $TimeToLiveSec } $RootChange = $true } if (($EnableSiteCosting -ne $null) ` -and (($Root.Flags -contains 'Site Costing') -ne $EnableSiteCosting)) { $RootProperties += @{ EnableSiteCosting = $EnableSiteCosting } $RootChange = $true } if (($EnableInsiteReferrals -ne $null) ` -and (($Root.Flags -contains 'Insite Referrals') -ne $EnableInsiteReferrals)) { $RootProperties += @{ EnableInsiteReferrals = $EnableInsiteReferrals } $RootChange = $true } if (($EnableAccessBasedEnumeration -ne $null) ` -and (($Root.Flags -contains 'AccessBased Enumeration') -ne $EnableAccessBasedEnumeration)) { $RootProperties += @{ EnableAccessBasedEnumeration = $EnableAccessBasedEnumeration } $RootChange = $true } if (($EnableRootScalability -ne $null) ` -and (($Root.Flags -contains 'Root Scalability') -ne $EnableRootScalability)) { $RootProperties += @{ EnableRootScalability = $EnableRootScalability } $RootChange = $true } if (($EnableTargetFailback -ne $null) ` -and (($Root.Flags -contains 'Target Failback') -ne $EnableTargetFailback)) { $RootProperties += @{ EnableTargetFailback = $EnableTargetFailback } $RootChange = $true } if ($RootChange) { # Update root settings $null = Set-DfsnRoot ` -Path $Path ` @RootProperties ` -ErrorAction Stop $RootProperties.GetEnumerator() | ForEach-Object -Process { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootUpdateParameterMessage) ` -f $Type,$Path,$TargetPath,$_.name, $_.value ) -join '' ) } } # Get target $Target = Get-RootTarget ` -Path $Path ` -TargetPath $TargetPath # Does the target need to be updated? [boolean] $TargetChange = $false # The Target properties that will be updated $TargetProperties = @{} # Check the target properties if (($ReferralPriorityClass) ` -and ($Target.ReferralPriorityClass -ne $ReferralPriorityClass)) { $TargetProperties += @{ ReferralPriorityClass = ($ReferralPriorityClass -replace '-','') } $TargetChange = $true } if (($ReferralPriorityRank) ` -and ($Target.ReferralPriorityRank -ne $ReferralPriorityRank)) { $TargetProperties += @{ ReferralPriorityRank = $ReferralPriorityRank } $TargetChange = $true } # Is the target a member of the namespace? if ($Target) { # Does the target need to be changed? if ($TargetChange) { # Update target settings $null = Set-DfsnRootTarget ` -Path $Path ` -TargetPath $TargetPath ` @TargetProperties ` -ErrorAction Stop } } else { # Add target to Namespace $null = New-DfsnRootTarget ` -Path $Path ` -TargetPath $TargetPath ` @TargetProperties ` -ErrorAction Stop } # Output the target parameters that were changed/set $TargetProperties.GetEnumerator() | ForEach-Object -Process { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootTargetUpdateParameterMessage) ` -f $Type,$Path,$TargetPath,$_.name, $_.value ) -join '' ) } } else { # Prepare to use the PSBoundParameters as a splat to created # The new DFS Namespace root. $null = $PSBoundParameters.Remove('Ensure') # Correct the ReferralPriorityClass field if ($ReferralPriorityClass) { $PSBoundParameters.ReferralPriorityClass = ($ReferralPriorityClass -replace '-','') } # Create New-DfsnRoot $null = New-DfsnRoot ` @PSBoundParameters ` -ErrorAction Stop $PSBoundParameters.GetEnumerator() | ForEach-Object -Process { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootUpdateParameterMessage) ` -f $Type,$Path,$TargetPath,$_.name, $_.value ) -join '' ) } } } else { # The Namespace Target should not exist # Get root target $Target = Get-RootTarget ` -Path $Path ` -TargetPath $TargetPath if ($Target) { # Remove the target from the namespace $null = Remove-DfsnRootTarget ` -Path $Path ` -TargetPath $TargetPath ` -Confirm:$false ` -ErrorAction Stop Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootTargetRemovedMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) } } } # Set-TargetResource function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory = $true)] [String] $Path, [parameter(Mandatory = $true)] [String] $TargetPath, [parameter(Mandatory = $true)] [ValidateSet('Present','Absent')] [String] $Ensure, [parameter(Mandatory = $true)] [ValidateSet('Standalone','DomainV1','DomainV2')] [String] $Type, [String] $Description, [Uint32] $TimeToLiveSec, [Boolean] $EnableSiteCosting, [Boolean] $EnableInsiteReferrals, [Boolean] $EnableAccessBasedEnumeration, [Boolean] $EnableRootScalability, [Boolean] $EnableTargetFailback, [ValidateSet('Global-High','SiteCost-High','SiteCost-Normal','SiteCost-Low','Global-Low')] [String] $ReferralPriorityClass, [Uint32] $ReferralPriorityRank ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.TestingNamespaceRootMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) # Flag to signal whether settings are correct [Boolean] $DesiredConfigurationMatch = $true # Lookup the existing Namespace root $Root = Get-Root ` -Path $Path if ($Ensure -eq 'Present') { # The Namespace root should exist if ($Root) { # The Namespace root exists and should # Changing the namespace type is not possible - the namespace # can only be recreated if the type should change. if (($Root.Type -replace ' ','') -ne $Type) { $ErrorParam = @{ ErrorId = 'NamespaceTypeConversionError' ErrorMessage = $($LocalizedData.NamespaceRootTypeConversionError) ` -f $Type,$Path,$TargetPath,($Root.Type -replace ' ','') ErrorCategory = 'InvalidOperation' ErrorAction = 'Stop' } New-TerminatingError @ErrorParam } # Check the Namespace parameters if (($Description) ` -and ($Root.Description -ne $Description)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootParameterNeedsUpdateMessage) ` -f $Type,$Path,$TargetPath,'Description' ) -join '' ) $desiredConfigurationMatch = $false } if (($TimeToLiveSec) ` -and ($Root.TimeToLiveSec -ne $TimeToLiveSec)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootParameterNeedsUpdateMessage) ` -f $Type,$Path,$TargetPath,'TimeToLiveSec' ) -join '' ) $desiredConfigurationMatch = $false } if (($EnableSiteCosting -ne $null) ` -and (($Root.Flags -contains 'Site Costing') -ne $EnableSiteCosting)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootParameterNeedsUpdateMessage) ` -f $Type,$Path,$TargetPath,'EnableSiteCosting' ) -join '' ) $desiredConfigurationMatch = $false } if (($EnableInsiteReferrals -ne $null) ` -and (($Root.Flags -contains 'Insite Referrals') -ne $EnableInsiteReferrals)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootParameterNeedsUpdateMessage) ` -f $Type,$Path,$TargetPath,'EnableInsiteReferrals' ) -join '' ) $desiredConfigurationMatch = $false } if (($EnableAccessBasedEnumeration -ne $null) ` -and (($Root.Flags -contains 'AccessBased Enumeration') -ne $EnableAccessBasedEnumeration)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootParameterNeedsUpdateMessage) ` -f $Type,$Path,$TargetPath,'EnableAccessBasedEnumeration' ) -join '' ) $desiredConfigurationMatch = $false } if (($EnableRootScalability -ne $null) ` -and (($Root.Flags -contains 'Root Scalability') -ne $EnableRootScalability)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootParameterNeedsUpdateMessage) ` -f $Type,$Path,$TargetPath,'EnableRootScalability' ) -join '' ) $desiredConfigurationMatch = $false } if (($EnableTargetFailback -ne $null) ` -and (($Root.Flags -contains 'Target Failback') -ne $EnableTargetFailback)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootParameterNeedsUpdateMessage) ` -f $Type,$Path,$TargetPath,'EnableTargetFailback' ) -join '' ) $desiredConfigurationMatch = $false } $Target = Get-RootTarget ` -Path $Path ` -TargetPath $TargetPath if ($Target) { if (($ReferralPriorityClass) ` -and ($Target.ReferralPriorityClass -ne $ReferralPriorityClass)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootTargetParameterNeedsUpdateMessage) ` -f $Type,$Path,$TargetPath,'ReferralPriorityClass' ) -join '' ) $desiredConfigurationMatch = $false } if (($ReferralPriorityRank) ` -and ($Target.ReferralPriorityRank -ne $ReferralPriorityRank)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootTargetParameterNeedsUpdateMessage) ` -f $Type,$Path,$TargetPath,'ReferralPriorityRank' ) -join '' ) $desiredConfigurationMatch = $false } } else { # The Root target does not exist but should - change required Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootTargetDoesNotExistButShouldMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) $desiredConfigurationMatch = $false } } else { # Ths Namespace root doesn't exist but should - change required Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootDoesNotExistButShouldMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) $desiredConfigurationMatch = $false } } else { # The Namespace target should not exist if ($Root) { $Target = Get-RootTarget ` -Path $Path ` -TargetPath $TargetPath if ($Target) { # The Root target exists but should not - change required Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootTargetExistsButShouldNotMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) $desiredConfigurationMatch = $false } else { # The Namespace exists but the target doesn't - change not required Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootTargetDoesNotExistAndShouldNotMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) } } else { # The Namespace does not exist (so neither does the target) - change not required Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceRootDoesNotExistAndShouldNotMessage) ` -f $Type,$Path,$TargetPath ) -join '' ) } } # if return $DesiredConfigurationMatch } # Test-TargetResource # Helper Functions Function Get-Root { param ( [parameter(Mandatory = $true)] [String] $Path ) # Lookup the DFSN Root. # Return null if doesn't exist. try { $DfsnRoot = Get-DfsnRoot ` -Path $Path ` -ErrorAction Stop } catch [Microsoft.Management.Infrastructure.CimException] { $DfsnRoot = $null } catch { Throw $_ } Return $DfsnRoot } Function Get-RootTarget { param ( [parameter(Mandatory = $true)] [String] $Path, [parameter(Mandatory = $true)] [String] $TargetPath ) # Lookup the DFSN Root Target in a namespace. # Return null if doesn't exist. try { $DfsnTarget = Get-DfsnRootTarget ` -Path $Path ` -TargetPath $TargetPath ` -ErrorAction Stop } catch [Microsoft.Management.Infrastructure.CimException] { $DfsnTarget = $null } catch { Throw $_ } Return $DfsnTarget } function New-TerminatingError { [CmdletBinding()] param ( [Parameter(Mandatory)] [String] $ErrorId, [Parameter(Mandatory)] [String] $ErrorMessage, [Parameter(Mandatory)] [System.Management.Automation.ErrorCategory] $ErrorCategory ) $exception = New-Object ` -TypeName System.InvalidOperationException ` -ArgumentList $errorMessage $errorRecord = New-Object ` -TypeName System.Management.Automation.ErrorRecord ` -ArgumentList $exception, $errorId, $errorCategory, $null $PSCmdlet.ThrowTerminatingError($errorRecord) } Export-ModuleMember -Function *-TargetResource |