Running this script in the PowerShell ISE will give you a nice output comparing the server you’re running it on with the other connection members in the replication group(s) it belongs to.

You will see “warnings” highlighted in yellow and “errors” highlighted in red.

  • Since this was ran in a production environment I had to blur out the server names and replication group names.

 

 

It uses WMI to query the DFS Replication Groups and further gather the backlog statistics.

 

Copy the code below into PowerShell ISE and run it!

#Gets DFSR backlog counts for all replication groups or one(s) you specify

Param (
    [String[]]$ReplicationGroupList = ("")
)


$RGroups = Get-WmiObject  -Namespace "root\MicrosoftDFS" -Query "SELECT * FROM DfsrReplicationGroupConfig"
#If  replication groups specified, use only those.
if($ReplicationGroupList)
{
    $SelectedRGroups = @()
    foreach($ReplicationGroup IN $ReplicationGroupList)
    {
        $SelectedRGroups += $rgroups | Where-Object {$_.ReplicationGroupName -eq $ReplicationGroup}
    }
    if($SelectedRGroups.count -eq 0)
    {
        Write-Error "None of the group names specified were found, exiting"
        exit
    }
    else
    {
        $RGroups = $SelectedRGroups
    }
}
        
$ComputerName=$env:ComputerName
$Succ=0
$Warn=0
$Err=0
 
foreach ($Group in $RGroups)
{
    $RGFoldersWMIQ = "SELECT * FROM DfsrReplicatedFolderConfig WHERE ReplicationGroupGUID='" + $Group.ReplicationGroupGUID + "'"
    $RGFolders = Get-WmiObject -Namespace "root\MicrosoftDFS" -Query  $RGFoldersWMIQ
    $RGConnectionsWMIQ = "SELECT * FROM DfsrConnectionConfig WHERE ReplicationGroupGUID='"+ $Group.ReplicationGroupGUID + "'"
    $RGConnections = Get-WmiObject -Namespace "root\MicrosoftDFS" -Query  $RGConnectionsWMIQ
    foreach ($Connection in $RGConnections)
    {
        $ConnectionName = $Connection.PartnerName#.Trim()
        if ($Connection.Enabled -eq $True)
        {
            #if (((New-Object System.Net.NetworkInformation.ping).send("$ConnectionName")).Status -eq "Success")
            #{
                foreach ($Folder in $RGFolders)
                {
                    $RGName = $Group.ReplicationGroupName
                    $RFName = $Folder.ReplicatedFolderName
 
                    if ($Connection.Inbound -eq $True)
                    {
                        $SendingMember = $ConnectionName
                        $ReceivingMember = $ComputerName
                        $Direction="inbound"
                    }
                    else
                    {
                        $SendingMember = $ComputerName
                        $ReceivingMember = $ConnectionName
                        $Direction="outbound"
                    }
 
                    $BLCommand = "dfsrdiag Backlog /RGName:'" + $RGName + "' /RFName:'" + $RFName + "' /SendingMember:" + $SendingMember + " /ReceivingMember:" + $ReceivingMember
                    $Backlog = Invoke-Expression -Command $BLCommand
 
                    $BackLogFilecount = 0
                    foreach ($item in $Backlog)
                    {
                        if ($item -ilike "*Backlog File count*")
                        {
                            $BacklogFileCount = [int]$Item.Split(":")[1].Trim()
                        }
                    }
 
                    if ($BacklogFileCount -eq 0)
                    {
                        $Color="white"
                        $Succ=$Succ+1
                    }
                    elseif ($BacklogFilecount -lt 10)
                    {
                        $Color="yellow"
                        $Warn=$Warn+1
                    }
                    else
                    {
                        $Color="red"
                        $Err=$Err+1
                    }
                    Write-Host "$BacklogFileCount files in backlog $SendingMember->$ReceivingMember for $RGName" -fore $Color
 
                } # Closing iterate through all folders
            #} # Closing  If replies to ping
        } # Closing  If Connection enabled
    } # Closing iteration through all connections
} # Closing iteration through all groups
Write-Host "$Succ successful, $Warn warnings and $Err errors from $($Succ+$Warn+$Err) replications."

 

I have modified the script for my environment to send the results via e-mail, but I’d like to polish that up a little more if I am going to share it.

 

I hope this helps you!

 

Update 2/6/2018:

I updated the script with ability to email the results.

At line 31 it starts a transcript of the PS session and saves it at C:\scripts\dfsr1.txt

Lines 100 and beyond are where the output file is processed for email and actually sent.

  • I was sending through an open mail relay that does not need authentication.
  • If you need authentication for the SMTP server,  you will have to modify the Send-MailMessage line

 

#Gets DFSR backlog counts for all replication groups or one(s) you specify

Param (
    [String[]]$ReplicationGroupList = ("")
)

$RGroups = Get-WmiObject  -Namespace "root\MicrosoftDFS" -Query "SELECT * FROM DfsrReplicationGroupConfig"
#If  replication groups specified, use only those.
if($ReplicationGroupList)
{
    $SelectedRGroups = @()
    foreach($ReplicationGroup IN $ReplicationGroupList)
    {
        $SelectedRGroups += $rgroups | Where-Object {$_.ReplicationGroupName -eq $ReplicationGroup}
    }
    if($SelectedRGroups.count -eq 0)
    {
        Write-Error "None of the group names specified were found, exiting"
        exit
    }
    else
    {
        $RGroups = $SelectedRGroups
    }
}
        
$ComputerName=$env:ComputerName
$Succ=0
$Warn=0
$Err=0
Start-Transcript -path c:\scripts\dfsr1.txt
foreach ($Group in $RGroups)
{
    $RGFoldersWMIQ = "SELECT * FROM DfsrReplicatedFolderConfig WHERE ReplicationGroupGUID='" + $Group.ReplicationGroupGUID + "'"
    $RGFolders = Get-WmiObject -Namespace "root\MicrosoftDFS" -Query  $RGFoldersWMIQ
    $RGConnectionsWMIQ = "SELECT * FROM DfsrConnectionConfig WHERE ReplicationGroupGUID='"+ $Group.ReplicationGroupGUID + "'"
    $RGConnections = Get-WmiObject -Namespace "root\MicrosoftDFS" -Query  $RGConnectionsWMIQ
    foreach ($Connection in $RGConnections)
    {
        $ConnectionName = $Connection.PartnerName#.Trim()
        if ($Connection.Enabled -eq $True)
        {
            #if (((New-Object System.Net.NetworkInformation.ping).send("$ConnectionName")).Status -eq "Success")
            #{
                foreach ($Folder in $RGFolders)
                {
                    $RGName = $Group.ReplicationGroupName
                    $RFName = $Folder.ReplicatedFolderName
 
                    if ($Connection.Inbound -eq $True)
                    {
                        $SendingMember = $ConnectionName
                        $ReceivingMember = $ComputerName
                        $Direction="inbound"
                    }
                    else
                    {
                        $SendingMember = $ComputerName
                        $ReceivingMember = $ConnectionName
                        $Direction="outbound"
                    }
 
                    $BLCommand = "dfsrdiag Backlog /RGName:'" + $RGName + "' /RFName:'" + $RFName + "' /SendingMember:" + $SendingMember + " /ReceivingMember:" + $ReceivingMember
                    $Backlog = Invoke-Expression -Command $BLCommand
 
                    $BackLogFilecount = 0
                    foreach ($item in $Backlog)
                    {
                        if ($item -ilike "*Backlog File count*")
                        {
                            $BacklogFileCount = [int]$Item.Split(":")[1].Trim()
                        }
                    }
 
                    if ($BacklogFileCount -eq 0)
                    {
                        $Color="white"
                        $Succ=$Succ+1
                    }
                    elseif ($BacklogFilecount -lt 10)
                    {
                        $Color="yellow"
                        $Warn=$Warn+1
                    }
                    else
                    {
                        $Color="red"
                        $Err=$Err+1
                    }
                    Write-Output "$BacklogFileCount files in backlog $SendingMember->$ReceivingMember for $RGName"
                    
                } # Closing iterate through all folders
            #} # Closing  If replies to ping
        } # Closing  If Connection enabled
    } # Closing iteration through all connections
} # Closing iteration through all groups
Write-Output "$Succ successful, $Warn warnings and $Err errors from $($Succ+$Warn+$Err) replications."
Stop-Transcript

$file = "c:\scripts\dfsr1.txt"

get-content $file |
    select -Skip 18 |
    set-content "$file-temp"
move "$file-temp" $file -Force

$emailrecipients = "[email protected]";
$emailbody = Get-Content -Path c:\scripts\dfsr1.txt -Raw

Send-MailMessage -to $emailrecipients -smtpserver 192.168.2.100 -from "DFSR System <[email protected]>" -subject "DFSR Report for $(get-date -format MMM/dd/yyyy) from $env:COMPUTERNAME" -body $emailbody;

Remove-Item c:\scripts\dfsr1.txt

 


16 Comments

Max Ruegnitz · February 9, 2021 at 1:37 pm

Very nice script; thank you. How can this be modified to not output for Folders whose Membership Status is Disabled for and Enabled Connection?

Chris Findley · November 20, 2020 at 1:37 pm

Thank you, I’ve set this as an overnight scheduled task during a time of DFSR turmoil and troubleshooting. It’s saving me from a manual task I’ve been stepping through every morning for weeks. Glad I went looking for a solution and found yours.

    Chris Findley · January 14, 2022 at 3:43 pm

    Me again. Started a new job and implemented DFS-R soon after. Realized I needed your script once more and Google did not disappoint. In my previous position, the output of this script became a weekly discussion point during a department meeting on systems health.

David · October 23, 2019 at 10:44 am

Just what I was looking for so many thanks – but…. like John above what I get emailed is not what is shown on screen. As the script runs, the dfsr1.txt file builds correctly but what is emailed is only a partial.

This is a snapshot of the file as the script runs…

Windows PowerShell transcript start
Start time: 20191023162958
Username: MSI\msisvc
RunAs User: MSI\msisvc
Machine: MSI-DATA-02 (Microsoft Windows NT 6.3.9600.0)
Host Application: powershell
Process ID: 4988

Transcript started, output file is c:\scripts\DFSRBackLog\dfsr1.txt
212117 files in backlog WBS-DATABAK->MSI-DATA-02 for msi.net\msi\data
0 files in backlog MSI-DATA-01->MSI-DATA-02 for msi.net\msi\data
0 files in backlog MSI-DATA-02->MSI-DATA-01 for msi.net\msi\data

which all is good & correct – but at the end, what is emailed is:

6 successful, 0 warnings and 2 errors from 8 replications.

Windows PowerShell transcript end
End time: 20191023163922

If I rem out the “Remove-Item c:\scripts\DFSRBackLog\dfsr1.txt” line that is the file which is left in the dir as well..

Anyway, thanks for sharing!

    David · October 23, 2019 at 10:46 am

    and on screen it looked fine….

    PS C:\Scripts\DFSRBackLog> ./dfsrbacklogcount2.ps1
    Transcript started, output file is c:\scripts\DFSRBackLog\dfsr1.txt
    90182 files in backlog WBS-DATABAK->MSI-DATA-02 for msi.net\msi\data
    0 files in backlog MSI-DATA-01->MSI-DATA-02 for msi.net\msi\data
    0 files in backlog MSI-DATA-02->MSI-DATA-01 for msi.net\msi\data
    2223606 files in backlog MSI-DATA-02->WBS-DATABAK for msi.net\msi\data
    0 files in backlog MSI-DATA-01->MSI-DATA-02 for msi.net\wbs\data
    0 files in backlog WBS-DATA-01->MSI-DATA-02 for msi.net\wbs\data
    0 files in backlog MSI-DATA-02->MSI-DATA-01 for msi.net\wbs\data
    0 files in backlog MSI-DATA-02->WBS-DATA-01 for msi.net\wbs\data
    6 successful, 0 warnings and 2 errors from 8 replications.
    Transcript stopped, output file is C:\scripts\DFSRBackLog\dfsr1.txt
    PS C:\Scripts\DFSRBackLog>

      David · October 23, 2019 at 10:58 am

      OK, sorted it….

      The problem is this block of code @ line 102.

      get-content $file |
      select -Skip 18 |
      set-content “$file-temp”
      move “$file-temp” $file -Force

      The -Skip 18 I guess refers to Tyler’s environment but with more DFSR servers then the output will be truncated so the ’18’ needs adjusting to your own taste.

      Once again Tyler, many thanks

      David

        Tyler Woods · October 23, 2019 at 11:18 am

        ahhh yes this is a classic “me” move. it applies specifically to my environment and I haven’t accounted for differences in others!

        thank you for sharing your experience.

          David · October 23, 2019 at 11:49 am

          Thanks Tyler – not a problem as it’s a great script.

          OOI, and to help educate us all, how, if you have time, is the value of 8 that you use calculated? I ‘fixed’ it by trial and error.. ;{

Nathan Dear · September 2, 2019 at 11:38 pm

Hi Tyler,

What a great script! Does exactly what I need it to do.

Don Hessey · March 20, 2019 at 9:37 am

How would you get a list of the actual backlogged files in the text file as well?

    Tyler Woods · March 20, 2019 at 10:26 am

    There are two ways to do this:

    1)
    dfsrdiag backlog /rgname:"REPLICATION_GROUP_NAME" /rfname:"REPLICATED_FOLDER_NAME" /smem:"SERVER_1" /rmem:"SERVER_2"

    2)
    Get-DfsrBacklog -DestinationComputerName "SRV1" -SourceComputerName "SRV02" -GroupName "RG01" -FolderName "RF1" | format-table fullpathname,updatetime

    more about get-dfsrbacklog

John · April 25, 2018 at 11:04 am

Hi Tyler, this is a nice script. I was looking for this long time. Great job.
I am getting all result on the screen , but not in the email body.
The email body is listing only the last three lines.Any suggestions?

    Tyler Woods · April 25, 2018 at 2:37 pm

    Did you copy+paste from the example I shared? I’m not able to test this against an environment right now, but I pulled that snippet from my repository of production scripts.

    I would ensure the start-transcript is up at the proper location, and you can also double check the .TXT file to see what its contents are as a way to diagnose if the problem is with sending the body of the message or with saving the transcript of the session.

    thanks!

Nick · February 7, 2018 at 8:32 am

Hi Tyler, this is great, thanks!
Did you ever get the emailing of results part working?
Thanks

    Tyler Woods · February 7, 2018 at 8:49 am

    Yes I did! I am going to update the post since posting the script in the comments doesn’t exactly work well. Thanks!

    Tyler Woods · February 7, 2018 at 8:58 am

    Nick, the post has been updated with the method I used for emailing the results.

Leave a Reply to Tyler WoodsCancel reply