diff --git a/services/file-services/windows-server/DFS Namespaces with Replication.md b/services/file-services/windows-server/DFS Namespaces with Replication.md index 6a0f32c..deb0189 100644 --- a/services/file-services/windows-server/DFS Namespaces with Replication.md +++ b/services/file-services/windows-server/DFS Namespaces with Replication.md @@ -420,4 +420,123 @@ dfsmgmt.msc ``` !!! success "DFS Management GUI Restored" - At this point, the DFS Management snap-in (should) be successfully showing all of the DFS namespaces and replication groups when you re-open "DFS Management". \ No newline at end of file + At this point, the DFS Management snap-in (should) be successfully showing all of the DFS namespaces and replication groups when you re-open "DFS Management". + +#### Check Replication Progress +You may want to check that replication is occurring bi-directionally between every member server in your DFS deployment. I wrote a script below that effectively shows you every replication group and each directional backlog status. + +```powershell +# --- CONFIG --- +$Members = @("LAB-FPS-01","LAB-FPS-02") +$SummarizeAcrossFolders = $true # $true = one line per direction per RG; $false = per-folder lines + +function Invoke-DfsrBacklogStatus { + param( + [Parameter(Mandatory)] [string] $RG, + [Parameter(Mandatory)] [string] $RF, + [Parameter(Mandatory)] [string] $Send, + [Parameter(Mandatory)] [string] $Recv + ) + + $out = & dfsrdiag backlog /rgname:"$RG" /rfname:"$RF" /sendingmember:"$Send" /receivingmember:"$Recv" 2>&1 | Out-String + $outTrim = ($out -split "`r?`n" | ForEach-Object { $_.Trim() }) | Where-Object { $_ -ne "" } + + if ($out -match 'No Backlog') { + return [pscustomobject]@{ Status="No Backlog"; Count=0; Detail=$null } + } + + $count = $null + $countLine = $outTrim | Where-Object { $_ -match '(?i)backlog' } | Select-Object -First 1 + if ($countLine -and ($countLine -match '(\d+)')) { $count = [int]$matches[1] } + + $detail = ($outTrim | Select-Object -First 8) -join " | " + + return [pscustomobject]@{ + Status = if ($count -ne $null) { "Backlog: $count" } else { "Backlog/Check Output" } + Count = $count + Detail = $detail + } +} + +$groups = Get-DfsReplicationGroup | Sort-Object GroupName + +foreach ($g in $groups) { + $rg = $g.GroupName + $rfs = Get-DfsReplicatedFolder -GroupName $rg | Sort-Object FolderName + + Write-Host "" + Write-Host ("== Replication Group: {0} ==" -f $rg) + + foreach ($send in $Members) { + foreach ($recv in $Members) { + if ($send -eq $recv) { continue } + + if ($SummarizeAcrossFolders) { + $worstCount = 0 + $nonZero = @() + $errorsOrDetails = @() + + foreach ($rfObj in $rfs) { + $rf = $rfObj.FolderName + $res = Invoke-DfsrBacklogStatus -RG $rg -RF $rf -Send $send -Recv $recv + + if ($res.Status -ne "No Backlog") { + $nonZero += [pscustomobject]@{ RF=$rf; Status=$res.Status; Count=$res.Count; Detail=$res.Detail } + if ($res.Count -ne $null -and $res.Count -gt $worstCount) { $worstCount = $res.Count } + + # ✅ FIX: ${rf} avoids the ':' parsing issue + if ($res.Detail) { $errorsOrDetails += "RF=${rf}: $($res.Detail)" } + } + } + + if ($nonZero.Count -eq 0) { + Write-Host ("{0} -> {1}: No Backlog" -f $send, $recv) + } else { + if ($worstCount -gt 0) { + Write-Host ("{0} -> {1}: Backlog (max {2} across RFs)" -f $send, $recv, $worstCount) + } else { + Write-Host ("{0} -> {1}: Backlog/Errors (see details)" -f $send, $recv) + } + + $errorsOrDetails | Select-Object -First 5 | ForEach-Object { Write-Host (" - {0}" -f $_) } + if ($errorsOrDetails.Count -gt 5) { Write-Host " - ... (more omitted)" } + } + } + else { + foreach ($rfObj in $rfs) { + $rf = $rfObj.FolderName + $res = Invoke-DfsrBacklogStatus -RG $rg -RF $rf -Send $send -Recv $recv + + if ($res.Status -eq "No Backlog") { + Write-Host ("{0} -> {1} [{2}]: No Backlog" -f $send, $recv, $rf) + } else { + Write-Host ("{0} -> {1} [{2}]: {3}" -f $send, $recv, $rf, $res.Status) + if ($res.Detail) { Write-Host (" - {0}" -f $res.Detail) } + } + } + } + } + } +} +``` + +!!! example "Example Output" + You will see output like the following when you run the script. + + ```powershell + == Replication Group: bunny-lab.io\music\fl studio plugins == + LAB-FPS-01 -> LAB-FPS-02: No Backlog + LAB-FPS-02 -> LAB-FPS-01: No Backlog + + == Replication Group: bunny-lab.io\music\personal music == + LAB-FPS-01 -> LAB-FPS-02: No Backlog + LAB-FPS-02 -> LAB-FPS-01: No Backlog + + == Replication Group: bunny-lab.io\music\shared music == + LAB-FPS-01 -> LAB-FPS-02: No Backlog + LAB-FPS-02 -> LAB-FPS-01: No Backlog + + == Replication Group: bunny-lab.io\projects\coding == + LAB-FPS-01 -> LAB-FPS-02: No Backlog + LAB-FPS-02 -> LAB-FPS-01: No Backlog + ``` \ No newline at end of file