DFS Replication (DFS-R) is a fantastic tool in any sysadmins belt when it comes to creating highly redundant and scalable file shares. And yet anyone who has used it, knows that monitoring it can be difficult at the best of times.

Windows Server 2012 introduced several Powershell commands for DFS-R which help discover partnerships and their status, however none of them test replication end-to-end.

So here are the goals I get out to achieve with Powershell:

Test a file replicates successfully between 2 servers using DFS-R

Fail the test if the file doesn’t replicate within an expected period

Dynamically discover replicated folders

Dynamically discover replication groups

Dynamically discover replication partners

Run both locally and remotely

If you don’t want to learn how the code works, you can skip to the examples of the script in action, or just download the script here.

Building the Code

The first step is pretty straight forward, create a file and test it arrives at the other side.

1 # Test File Name 2 $FileName = "DFSRTest_ $( Get-Date -format yyyyMMddmmhhss) .txt" 3 # Source Server Path 4 $SourcePath = "\\DFSR01\Data\$FileName" 5 # Destination Server Pth 6 $TargetPath = "\\DFSR02\Data\$FileName" 7 # Create test file 8 New-Item -ItemType File $SourcePath | out-null 9 10 # Start loop looking for file on destination server 11 do { 12 $found = Test-Path -Path $TargetPath 13 } until ( $found ) 14 Remove-Item $SourcePath -Force 15 "DFSR Replication succeeded = $found"

Now to make sure this loop doesn’t run forever if replication isn’t working or there is a large backlog, we need to add a timeout. To do this, we’ll use the stopwatch function.

1 # Test File Name 2 $FileName = "DFSRTest_ $( Get-Date -format yyyyMMddmmhhss) .txt" 3 # Source Server Path 4 $SourcePath = "\\DFSR01\Data\$FileName" 5 # Destination Server Pth 6 $TargetPath = "\\DFSR02\Data\$FileName" 7 # Timeout in Minutes 8 $Timeout = 5 9 # Create and start a stopwatch timer 10 $StopWatch = [System.Diagnostics.Stopwatch]::StartNew() 11 # Create test file 12 New-Item -ItemType File $SourcePath | out-null 13 14 # Start loop looking for file on destination server 15 do { 16 $found = Test-Path -Path $TargetPath 17 } until ( 18 $found -or ` 19 $StopWatch .Elapsed.TotalMinutes -ge $Timeout 20 ) 21 Remove-Item $SourcePath -Force 22 "DFSR Replication succeeded = $found"

The last 3 steps we can tick off at the same time using DFS-R in-box Powershell to help us. Get-DFSRConnection can be used to query a machine for what connections it’s part of, this tells us the group names and the destination servers. With this information, we can then use Get-DFSRMembership to query the folder names and paths to test.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 # Test File Name $FileName = "DFSRTest_ $( Get-Date -format yyyyMMddmmhhss) .txt" # Source Server $SourceServer = "DFSR01" # Timeout in Minutes $Timeout = 5 # DFSR Groups in the domain $Groups = Get-DFSRConnection -SourceComputerName $SourceServer | Group-object -Property GroupName # Loop through groups Foreach ( $Group in $Groups ) { $GroupName = $Group .Name $Folders = Get-DFSRMembership -GroupName $GroupName -ComputerName $Group .Group.SourceComputerName, $Group .Group.DestinationComputerName | Group-Object -Property FolderName Foreach ( $Folder in $Folders ) { $FolderName = $Folder .Name $SourceFolder = $Folder .Group.Where{ $_ .ComputerName -eq $SourceServer } $Targets = $Folder .Group.ComputerName.Where{ $_ -ne $SourceServer } Foreach ( $Target in $Targets ) { $TargetFolder = $Folder .Group.Where{ $_ .ComputerName -ne $SourceServer } $SourcePath = "\\{0}\{1}\{2}" -f $SourceFolder .ComputerName, $SourceFolder .ContentPath.Replace( ":" , "$" ), $FileName $TargetPath = "\\{0}\{1}\{2}" -f $TargetFolder .ComputerName, $TargetFolder .ContentPath.Replace( ":" , "$" ), $FileName # Create and start a stopwatch timer $StopWatch = [System.Diagnostics.Stopwatch]::StartNew() # Create test file New-Item -ItemType File $SourcePath | out-null # Start loop looking for file on destination server do { $found = Test-Path -Path $TargetPath } until ( $found -or ` $StopWatch .Elapsed.TotalMinutes -ge $Timeout ) Remove-Item $SourcePath -Force "$FolderName replication from $SourceServer to $Target working = $found" } } }

We now have a way to test the folders a server replicates using DFS-R is working. To make this a bit more reusable, I turned the above code into a script that can be fed specific parameters.

Meet Test-DfsrReplication , a script you can use to test one or more servers, either for a specific folder or all folders. Not only that, but it will test replication in both directions.

You can download an up-to-date copy of it any time from my Github account here.

Examples

And here are some examples of it in action!

# Test all replicated folders for DFSR01 Test-DfsrReplication -ComputerName DFSR01 | ft -au

# Test replication for the Data folder Test-DfsrReplication -ComputerName DFSR01 -Folder Data | ft -au

# Test one folder that exists, and one that doesn't with verbose output Test-DfsrReplication -ComputerName DFSR01 -Folder Data1,Profiles -Verbose | ft -au<

As always, please comment if you have any further questions or have found this useful!