DSCResources/DSC_DFSReplicationGroupMembership/DSC_DFSReplicationGroupMembership.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 Replication Group Membership. .PARAMETER GroupName The name of the DFS Replication Group. .PARAMETER FolderName The name of the DFS Replication Group Folder. .PARAMETER ComputerName The computer name of the Replication Group member. This can be specified using either the ComputerName or FQDN name for the member. If an FQDN name is used and the DomainName parameter is set, the FQDN domain name must match. .PARAMETER DomainName The name of the AD Domain the DFS Replication Group this replication group is in. #> function Get-TargetResource { [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] [System.String] $GroupName, [Parameter(Mandatory = $true)] [System.String] $FolderName, [Parameter(Mandatory = $true)] [System.String] $ComputerName, [Parameter()] [System.String] $DomainName ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.GettingReplicationGroupMembershipMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) # Lookup the existing Replication Group $membershipParameters = @{ GroupName = $GroupName ComputerName = $ComputerName } $returnValue = $membershipParameters if ($DomainName) { $membershipParameters += @{ DomainName = $DomainName } } $returnValue += @{ FolderName = $FolderName } $replicationGroupMembership = Get-DfsrMembership @membershipParameters ` -ErrorAction Stop ` | Where-Object { $_.FolderName -eq $FolderName } if ($replicationGroupMembership) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipExistsMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) $returnValue.ComputerName = $replicationGroupMembership.ComputerName if ($replicationGroupMembership.Enabled) { $ensureEnabled = 'Enabled' } else { $ensureEnabled = 'Disabled' } # if $returnValue += @{ EnsureEnabled = $ensureEnabled ContentPath = $replicationGroupMembership.ContentPath StagingPath = $replicationGroupMembership.StagingPath StagingPathQuotaInMB = $replicationGroupMembership.StagingPathQuotaInMB MinimumFileStagingSize = $replicationGroupMembership.MinimumFileStagingSize ConflictAndDeletedPath = $replicationGroupMembership.ConflictAndDeletedPath ConflictAndDeletedQuotaInMB = $replicationGroupMembership.ConflictAndDeletedQuotaInMB ReadOnly = $replicationGroupMembership.ReadOnly RemoveDeletedFiles = $replicationGroupMembership.RemoveDeletedFiles PrimaryMember = $replicationGroupMembership.PrimaryMember DfsnPath = $replicationGroupMembership.DfsnPath DomainName = $replicationGroupMembership.DomainName } } else { # The Rep Group membership doesn't exist Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipDoesNotExistMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) } return $returnValue } # Get-TargetResource <# .SYNOPSIS Sets DFS Replication Group Membership. .PARAMETER GroupName The name of the DFS Replication Group. .PARAMETER FolderName The name of the DFS Replication Group Folder. .PARAMETER ComputerName The computer name of the Replication Group member. This can be specified using either the ComputerName or FQDN name for the member. If an FQDN name is used and the DomainName parameter is set, the FQDN domain name must match. .PARAMETER EnsureEnabled Ensures that membership is either Enabled or Disabled. .PARAMETER ContentPath The local content path for the DFS Replication Group Folder. .PARAMETER StagingPath The local staging path for the DFS Replication Group Folder. .PARAMETER StagingPathQuotaInMB The local staging path quota size in MB. .PARAMETER MinimumFileStagingSize The minimum file size that DFS Replication stages during outbound replication. .PARAMETER ConflictAndDeletedQuotaInMB The local conflict and deleted path quota size in MB. .PARAMETER ReadOnly Specify if this content path should be read only. .PARAMETER RemoveDeletedFiles Specify if a member computer deletes files and folders immediately following inbound replication. .PARAMETER PrimaryMember Used to configure this as the Primary Member. Every folder must have at least one primary member for initial replication to take place. Only set during initial creation of membership. .PARAMETER DfsnPath Specify the DFS Namespace folder path of the membership. This value does not affect replication. .PARAMETER DomainName The name of the AD Domain the DFS Replication Group this replication group is in. #> function Set-TargetResource { param ( [Parameter(Mandatory = $true)] [System.String] $GroupName, [Parameter(Mandatory = $true)] [System.String] $FolderName, [Parameter(Mandatory = $true)] [System.String] $ComputerName, [Parameter()] [ValidateSet('Enabled','Disabled')] [System.String] $EnsureEnabled = 'Enabled', [Parameter()] [System.String] $ContentPath, [Parameter()] [System.String] $StagingPath, [Parameter()] [System.UInt32] $StagingPathQuotaInMB, [Parameter()] [ValidateSet('Size256KB','Size512KB', 'Size1MB','Size2MB','Size4MB','Size8MB','Size16MB','Size32MB','Size64MB','Size128MB','Size256MB','Size512MB', 'Size1GB','Size2GB','Size4GB','Size8GB','Size16GB','Size32GB','Size64GB','Size128GB','Size256GB','Size512GB', 'Size1TB','Size2TB','Size4TB','Size8TB','Size16TB','Size32TB','Size64TB','Size128TB','Size256TB','Size512TB')] [System.String] $MinimumFileStagingSize, [Parameter()] [System.UInt32] $ConflictAndDeletedQuotaInMB, [Parameter()] [System.Boolean] $ReadOnly, [Parameter()] [System.Boolean] $RemoveDeletedFiles, [Parameter()] [System.Boolean] $PrimaryMember, [Parameter()] [System.String] $DfsnPath, [Parameter()] [System.String] $DomainName ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.SettingRegGroupMembershipMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) # Remove Ensure so the PSBoundParameters can be used to splat $null = $PSBoundParameters.Remove('EnsureEnabled') $null = $PSBoundParameters.Add('DisableMembership',($EnsureEnabled -eq 'Disabled')) # Now apply the changes Set-DfsrMembership @PSBoundParameters ` -ErrorAction Stop Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipUpdatedMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) } # Set-TargetResource <# .SYNOPSIS Tests DFS Replication Group Membership. .PARAMETER GroupName The name of the DFS Replication Group. .PARAMETER FolderName The name of the DFS Replication Group Folder. .PARAMETER ComputerName The computer name of the Replication Group member. This can be specified using either the ComputerName or FQDN name for the member. If an FQDN name is used and the DomainName parameter is set, the FQDN domain name must match. .PARAMETER EnsureEnabled Ensures that membership is either Enabled or Disabled. .PARAMETER ContentPath The local content path for the DFS Replication Group Folder. .PARAMETER StagingPath The local staging path for the DFS Replication Group Folder. .PARAMETER StagingPathQuotaInMB The local staging path quota size in MB. .PARAMETER MinimumFileStagingSize The minimum file size that DFS Replication stages during outbound replication. .PARAMETER ConflictAndDeletedQuotaInMB The local conflict and deleted path quota size in MB. .PARAMETER ReadOnly Specify if this content path should be read only. .PARAMETER RemoveDeletedFiles Specify if a member computer deletes files and folders immediately following inbound replication. .PARAMETER PrimaryMember Used to configure this as the Primary Member. Every folder must have at least one primary member for initial replication to take place. Only set during initial creation of membership. .PARAMETER DfsnPath Specify the DFS Namespace folder path of the membership. This value does not affect replication. .PARAMETER DomainName The name of the AD Domain the DFS Replication Group this replication group is in. #> function Test-TargetResource { [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [System.String] $GroupName, [Parameter(Mandatory = $true)] [System.String] $FolderName, [Parameter(Mandatory = $true)] [System.String] $ComputerName, [Parameter()] [ValidateSet('Enabled','Disabled')] [System.String] $EnsureEnabled = 'Enabled', [Parameter()] [System.String] $ContentPath, [Parameter()] [System.String] $StagingPath, [Parameter()] [System.UInt32] $StagingPathQuotaInMB, [Parameter()] [ValidateSet('Size256KB','Size512KB', 'Size1MB','Size2MB','Size4MB','Size8MB','Size16MB','Size32MB','Size64MB','Size128MB','Size256MB','Size512MB', 'Size1GB','Size2GB','Size4GB','Size8GB','Size16GB','Size32GB','Size64GB','Size128GB','Size256GB','Size512GB', 'Size1TB','Size2TB','Size4TB','Size8TB','Size16TB','Size32TB','Size64TB','Size128TB','Size256TB','Size512TB')] [System.String] $MinimumFileStagingSize, [Parameter()] [System.UInt32] $ConflictAndDeletedQuotaInMB, [Parameter()] [System.Boolean] $ReadOnly, [Parameter()] [System.Boolean] $RemoveDeletedFiles, [Parameter()] [System.Boolean] $PrimaryMember, [Parameter()] [System.String] $DfsnPath, [Parameter()] [System.String] $DomainName ) # Flag to signal whether settings are correct [System.Boolean] $desiredConfigurationMatch = $true Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.TestingRegGroupMembershipMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) # Lookup the existing Replication Group $membershipParameters = @{ GroupName = $GroupName ComputerName = $ComputerName } if ($DomainName) { $membershipParameters += @{ DomainName = $DomainName } } $replicationGroupMembership = Get-DfsrMembership @membershipParameters ` -ErrorAction Stop ` | Where-Object { $_.FolderName -eq $FolderName } if ($replicationGroupMembership) { # The rep group folder is found Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipExistsMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) # Check the Enabled if (($EnsureEnabled -eq 'Enabled') ` -and (-not $replicationGroupMembership.Enabled) ` -or ($EnsureEnabled -eq 'Disabled') ` -and ($replicationGroupMembership.Enabled)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipEnabledMismatchMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) $desiredConfigurationMatch = $false } # if # Check the ContentPath if (($PSBoundParameters.ContainsKey('ContentPath')) ` -and ($replicationGroupMembership.ContentPath -ne $ContentPath)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipContentPathMismatchMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) $desiredConfigurationMatch = $false } # if # Check the StagingPath if (($PSBoundParameters.ContainsKey('StagingPath')) ` -and ($replicationGroupMembership.StagingPath -ne $StagingPath)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipStagingPathMismatchMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) $desiredConfigurationMatch = $false } # if # Check the StagingPathQuota if (($PSBoundParameters.ContainsKey('StagingPathQuotaInMB')) ` -and ($replicationGroupMembership.StagingPathQuotaInMB -ne $StagingPathQuotaInMB)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipStagingPathQuotaMismatchMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) $desiredConfigurationMatch = $false } # if # Check the MinimumFileStagingSize if (($PSBoundParameters.ContainsKey('MinimumFileStagingSize')) ` -and ($replicationGroupMembership.MinimumFileStagingSize -ne $MinimumFileStagingSize)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipMinimumFileStagingMismatchMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) $desiredConfigurationMatch = $false } # if # Check the ConflictAndDeletedQuotaInMB if (($PSBoundParameters.ContainsKey('ConflictAndDeletedQuotaInMB')) ` -and ($replicationGroupMembership.ConflictAndDeletedQuotaInMB -ne $ConflictAndDeletedQuotaInMB)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipConflictAndDeletedMismatchMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) $desiredConfigurationMatch = $false } # if # Check the ReadOnly if (($PSBoundParameters.ContainsKey('ReadOnly')) ` -and ($replicationGroupMembership.ReadOnly -ne $ReadOnly)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipReadOnlyMismatchMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) $desiredConfigurationMatch = $false } # if # Check the RemoveDeletedFiles if (($PSBoundParameters.ContainsKey('RemoveDeletedFiles')) ` -and ($replicationGroupMembership.RemoveDeletedFiles -ne $RemoveDeletedFiles)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipRemoveDeletedFilesMismatchMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) $desiredConfigurationMatch = $false } # if # Check the PrimaryMember if (($PSBoundParameters.ContainsKey('PrimaryMember')) ` -and ($replicationGroupMembership.PrimaryMember -ne $PrimaryMember)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipPrimaryMemberMismatchMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) <# See https://techcommunity.microsoft.com/t5/storage-at-microsoft/the-primary-member-in-dfs-replication/ba-p/423127 Do not flag as a change required as flag is cleared after initial sync #> } # if # Check the DfsnPath if (($PSBoundParameters.ContainsKey('DfsnPath')) ` -and ($replicationGroupMembership.DfsnPath -ne $DfsnPath)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipDfsnPathMismatchMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) $desiredConfigurationMatch = $false } # if } else { # The Rep Group membership doesn't exist Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ReplicationGroupMembershipDoesNotExistMessage) ` -f $GroupName,$FolderName,$ComputerName ) -join '' ) $desiredConfigurationMatch = $false } # if return $desiredConfigurationMatch } # Test-TargetResource Export-ModuleMember -Function *-TargetResource |