DSCResources/DSC_DFSNamespaceFolder/DSC_DFSNamespaceFolder.psm1
$modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'Modules' # Import the DFSDsc.Common Module Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') # Import Localization Strings $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS Returns the current state of a DFS Namespace Folder. .PARAMETER Path Specifies a path for the root of a DFS namespace. .PARAMETER TargetPath Specifies a path for a root target of the DFS namespace. .PARAMETER Ensure Specifies if the DFS Namespace root should exist. .PARAMETER TargetState Specifies the state of the DFS namespace folder target. #> function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] [System.String] $Path, [Parameter(Mandatory = $true)] [System.String] $TargetPath, [Parameter()] [ValidateSet('Present','Absent')] [System.String] $Ensure = 'Present', [Parameter()] [ValidateSet('Offline','Online')] [System.String] $TargetState = 'Online' ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.GettingNamespaceFolderMessage) ` -f $Path,$TargetPath ) -join '' ) # Generate the return object assuming absent. $returnValue = @{ Path = $Path TargetPath = $TargetPath Ensure = 'Absent' } # Lookup the existing Namespace Folder $folder = Get-Folder ` -Path $Path if ($folder) { # The namespace folder exists Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderExistsMessage) ` -f $Path ) -join '' ) } else { # The namespace folder does not exist Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderDoesNotExistMessage) ` -f $Path ) -join '' ) return $returnValue } # if $returnValue += @{ TimeToLiveSec = $folder.TimeToLiveSec State = $folder.State Description = $folder.Description EnableInsiteReferrals = ($folder.Flags -contains 'Insite Referrals') EnableTargetFailback = ($folder.Flags -contains 'Target Failback') } # DFS Folder exists but does target exist? $targetFolder = Get-FolderTarget ` -Path $Path ` -TargetPath $TargetPath if ($targetFolder) { # The target exists in this namespace $returnValue.Ensure = 'Present' $returnValue += @{ ReferralPriorityClass = $targetFolder.ReferralPriorityClass ReferralPriorityRank = $targetFolder.ReferralPriorityRank TargetState = $targetFolder.State } Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderTargetExistsMessage) ` -f $Path,$TargetPath ) -join '' ) } else { # The target does not exist in this namespace Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderTargetDoesNotExistMessage) ` -f $Path,$TargetPath ) -join '' ) } # if return $returnValue } # Get-TargetResource <# .SYNOPSIS Sets the current state of a DFS Namespace Folder. .PARAMETER Path Specifies a path for the root of a DFS namespace. .PARAMETER TargetPath Specifies a path for a root target of the DFS namespace. .PARAMETER Ensure Specifies if the DFS Namespace root should exist. .PARAMETER TargetState Specifies the state of the DFS namespace folder target. .PARAMETER Description The description of the DFS Namespace. .PARAMETER TimeToLiveSec Specifies a TTL interval, in seconds, for referrals. .PARAMETER EnableInsiteReferrals Indicates whether a DFS namespace server provides a client only with referrals that are in the same site as the client. .PARAMETER EnableTargetFailback Indicates whether a DFS namespace uses target failback. .PARAMETER ReferralPriorityClass Specifies the target priority class for a DFS namespace root. .PARAMETER ReferralPriorityRank Specifies the priority rank, as an integer, for a root target of the DFS namespace. #> function Set-TargetResource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.String] $Path, [Parameter(Mandatory = $true)] [System.String] $TargetPath, [Parameter()] [ValidateSet('Present','Absent')] [System.String] $Ensure = 'Present', [Parameter()] [ValidateSet('Offline','Online')] [System.String] $TargetState = 'Online', [Parameter()] [System.String] $Description, [Parameter()] [System.UInt32] $TimeToLiveSec, [Parameter()] [System.Boolean] $EnableInsiteReferrals, [Parameter()] [System.Boolean] $EnableTargetFailback, [Parameter()] [ValidateSet('Global-High','SiteCost-High','SiteCost-Normal','SiteCost-Low','Global-Low')] [System.String] $ReferralPriorityClass, [Parameter()] [System.UInt32] $ReferralPriorityRank ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.SettingNamespaceFolderMessage) ` -f $Path,$TargetPath ) -join '' ) # Lookup the existing Namespace Folder $folder = Get-Folder ` -Path $Path if ($Ensure -eq 'Present') { # Set desired Configuration if ($folder) { # Does the Folder need to be updated? [System.Boolean] $folderChange = $false # The Folder properties that will be updated $folderProperties = @{ State = 'Online' } if (($Description) ` -and ($folder.Description -ne $Description)) { $folderProperties += @{ Description = $Description } $folderChange = $true } if (($TimeToLiveSec) ` -and ($folder.TimeToLiveSec -ne $TimeToLiveSec)) { $folderProperties += @{ TimeToLiveSec = $TimeToLiveSec } $folderChange = $true } if (($null -ne $EnableInsiteReferrals) ` -and (($folder.Flags -contains 'Insite Referrals') -ne $EnableInsiteReferrals)) { $folderProperties += @{ EnableInsiteReferrals = $EnableInsiteReferrals } $folderChange = $true } if (($null -ne $EnableTargetFailback) ` -and (($folder.Flags -contains 'Target Failback') -ne $EnableTargetFailback)) { $folderProperties += @{ EnableTargetFailback = $EnableTargetFailback } $folderChange = $true } if ($folderChange) { # Update Folder settings $null = Set-DfsnFolder ` -Path $Path ` @FolderProperties ` -ErrorAction Stop $folderProperties.GetEnumerator() | ForEach-Object -Process { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderUpdateParameterMessage) ` -f $Path,$_.name, $_.value ) -join '' ) } } # Get target $targetFolder = Get-FolderTarget ` -Path $Path ` -TargetPath $TargetPath # Does the target need to be updated? [System.Boolean] $targetChange = $false # The Target properties that will be updated $targetProperties = @{} # Check the target properties if (($TargetState) ` -and ($targetFolder.State -ne $TargetState)) { $targetProperties += @{ State = $TargetState } $targetChange = $true } if (($ReferralPriorityClass) ` -and ($targetFolder.ReferralPriorityClass -ne $ReferralPriorityClass)) { $targetProperties += @{ ReferralPriorityClass = ($ReferralPriorityClass -replace '-','') } $targetChange = $true } if (($ReferralPriorityRank) ` -and ($targetFolder.ReferralPriorityRank -ne $ReferralPriorityRank)) { $targetProperties += @{ ReferralPriorityRank = $ReferralPriorityRank } $targetChange = $true } # Is the target a member of the namespace? if ($targetFolder) { # Does the target need to be changed? if ($targetChange) { # Update target settings $null = Set-DfsnFolderTarget ` -Path $Path ` -TargetPath $TargetPath ` @TargetProperties ` -ErrorAction Stop } } else { # Add target to Namespace $null = New-DfsnFolderTarget ` -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): " $($script:localizedData.NamespaceFolderTargetUpdateParameterMessage) ` -f $Path,$TargetPath,$_.name, $_.value ) -join '' ) } } else { <# Prepare to use the PSBoundParameters as a splat to created The new DFS Namespace Folder. #> $null = $PSBoundParameters.Remove('Ensure') # Correct the ReferralPriorityClass field if ($ReferralPriorityClass) { $PSBoundParameters.ReferralPriorityClass = ($ReferralPriorityClass -replace '-','') } # Create New-DfsnFolder $null = New-DfsnFolder ` @PSBoundParameters ` -ErrorAction Stop $PSBoundParameters.GetEnumerator() | ForEach-Object -Process { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderUpdateParameterMessage) ` -f $Path,$TargetPath,$_.name, $_.value ) -join '' ) } } } else { # The Namespace Folder Target should not exist # Get Folder target $targetFolder = Get-FolderTarget ` -Path $Path ` -TargetPath $TargetPath if ($targetFolder) { # Remove the target from the Namespace Folder $null = Remove-DfsnFolderTarget ` -Path $Path ` -TargetPath $TargetPath ` -Confirm:$false ` -ErrorAction Stop Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderTargetRemovedMessage) ` -f $Path,$TargetPath ) -join '' ) } } } # Set-TargetResource <# .SYNOPSIS Tests the current state of a DFS Namespace Folder. .PARAMETER Path Specifies a path for the root of a DFS namespace. .PARAMETER TargetPath Specifies a path for a root target of the DFS namespace. .PARAMETER Ensure Specifies if the DFS Namespace root should exist. .PARAMETER TargetState Specifies the state of the DFS namespace folder target. .PARAMETER Description The description of the DFS Namespace. .PARAMETER TimeToLiveSec Specifies a TTL interval, in seconds, for referrals. .PARAMETER EnableInsiteReferrals Indicates whether a DFS namespace server provides a client only with referrals that are in the same site as the client. .PARAMETER EnableTargetFailback Indicates whether a DFS namespace uses target failback. .PARAMETER ReferralPriorityClass Specifies the target priority class for a DFS namespace root. .PARAMETER ReferralPriorityRank Specifies the priority rank, as an integer, for a root target of the DFS namespace. #> function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [System.String] $Path, [Parameter(Mandatory = $true)] [System.String] $TargetPath, [Parameter()] [ValidateSet('Present','Absent')] [System.String] $Ensure = 'Present', [Parameter()] [ValidateSet('Offline','Online')] [System.String] $TargetState = 'Online', [Parameter()] [System.String] $Description, [Parameter()] [System.UInt32] $TimeToLiveSec, [Parameter()] [System.Boolean] $EnableInsiteReferrals, [Parameter()] [System.Boolean] $EnableTargetFailback, [Parameter()] [ValidateSet('Global-High','SiteCost-High','SiteCost-Normal','SiteCost-Low','Global-Low')] [System.String] $ReferralPriorityClass, [Parameter()] [System.UInt32] $ReferralPriorityRank ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.TestingNamespaceFolderMessage) ` -f $Path,$TargetPath ) -join '' ) # Flag to signal whether settings are correct [System.Boolean] $desiredConfigurationMatch = $true # Lookup the existing Namespace Folder $folder = Get-Folder ` -Path $Path if ($Ensure -eq 'Present') { # The Namespace Folder should exist if ($folder) { # The Namespace Folder exists and should # Check the Namespace parameters if (($Description) ` -and ($folder.Description -ne $Description)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderParameterNeedsUpdateMessage) ` -f $Path,'Description' ) -join '' ) $desiredConfigurationMatch = $false } if (($TimeToLiveSec) ` -and ($folder.TimeToLiveSec -ne $TimeToLiveSec)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderParameterNeedsUpdateMessage) ` -f $Path,'TimeToLiveSec' ) -join '' ) $desiredConfigurationMatch = $false } if (($null -ne $EnableInsiteReferrals) ` -and (($folder.Flags -contains 'Insite Referrals') -ne $EnableInsiteReferrals)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderParameterNeedsUpdateMessage) ` -f $Path,'EnableInsiteReferrals' ) -join '' ) $desiredConfigurationMatch = $false } if (($null -ne $EnableTargetFailback) ` -and (($folder.Flags -contains 'Target Failback') -ne $EnableTargetFailback)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderParameterNeedsUpdateMessage) ` -f $Path,'EnableTargetFailback' ) -join '' ) $desiredConfigurationMatch = $false } $targetFolder = Get-FolderTarget ` -Path $Path ` -TargetPath $TargetPath if ($targetFolder) { if (($TargetState) ` -and ($targetFolder.State -ne $TargetState)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.NamespaceFolderTargetParameterNeedsUpdateMessage) ` -f $Path,$TargetPath,'TargetState' ) -join '' ) $desiredConfigurationMatch = $false } if (($ReferralPriorityClass) ` -and ($targetFolder.ReferralPriorityClass -ne $ReferralPriorityClass)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderTargetParameterNeedsUpdateMessage) ` -f $Path,$TargetPath,'ReferralPriorityClass' ) -join '' ) $desiredConfigurationMatch = $false } if (($ReferralPriorityRank) ` -and ($targetFolder.ReferralPriorityRank -ne $ReferralPriorityRank)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderTargetParameterNeedsUpdateMessage) ` -f $Path,$TargetPath,'ReferralPriorityRank' ) -join '' ) $desiredConfigurationMatch = $false } } else { # The Folder target does not exist but should - change required Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderTargetDoesNotExistButShouldMessage) ` -f $Path,$TargetPath ) -join '' ) $desiredConfigurationMatch = $false } } else { # Ths Namespace Folder doesn't exist but should - change required Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderDoesNotExistButShouldMessage) ` -f $Path ) -join '' ) $desiredConfigurationMatch = $false } } else { # The Namespace target should not exist if ($folder) { $targetFolder = Get-FolderTarget ` -Path $Path ` -TargetPath $TargetPath if ($targetFolder) { # The Folder target exists but should not - change required Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderTargetExistsButShouldNotMessage) ` -f $Path,$TargetPath ) -join '' ) $desiredConfigurationMatch = $false } else { # The Namespace exists but the target doesn't - change not required Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderTargetDoesNotExistAndShouldNotMessage) ` -f $Path,$TargetPath ) -join '' ) } } else { # The Namespace does not exist (so neither does the target) - change not required Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.NamespaceFolderDoesNotExistAndShouldNotMessage) ` -f $Path ) -join '' ) } } # if return $desiredConfigurationMatch } # Test-TargetResource <# .SYNOPSIS Lookup the DFSN Folder. .PARAMETER Path Specifies a path for the root of a DFS namespace. #> function Get-Folder { param ( [Parameter(Mandatory = $true)] [System.String] $Path ) try { $dfsnFolder = Get-DfsnFolder ` -Path $Path ` -ErrorAction Stop } catch [Microsoft.Management.Infrastructure.CimException] { $dfsnFolder = $null } catch { throw $_ } return $dfsnFolder } <# .SYNOPSIS Lookup the DFSN Folder Target in a namespace. .PARAMETER Path Specifies a path for the root of a DFS namespace. .PARAMETER TargetPath Specifies a path for a root target of the DFS namespace. #> function Get-FolderTarget { param ( [Parameter(Mandatory = $true)] [System.String] $Path, [Parameter(Mandatory = $true)] [System.String] $TargetPath ) try { $dfsnTarget = Get-DfsnFolderTarget ` -Path $Path ` -TargetPath $TargetPath ` -ErrorAction Stop } catch [Microsoft.Management.Infrastructure.CimException] { $dfsnTarget = $null } catch { throw $_ } return $dfsnTarget } Export-ModuleMember -Function *-TargetResource |