One of the challenges with DFS is to monitor the DFS replication backlog. There are various scripts out there to accomplish this. Unfortunately I found nothing I really liked and giving me the simple insight I wanted.
The goal was simple – a script that will monitor the backlog between two systems in both directions – meaning Server-A to Server-B and Server-B to Server-A. For both directions I wanted to see the amount of files as well as the size of those files. I did not care about what DFS groups and or DFS folders are affected in detail – this is because the amount of groups might change, the amount of folders will likely change rather frequently, meaning it would be a challenge to monitor it per group or even on a folder level very efficient. Monitoring the amounts of groups and folders alone has no really advantage, cause this would have been changed by an administrator.
Below you will find my script that actually expects three parameter – the two server names and a limit integer value. The limit will not influence the XML response of the script, you could add the <text>$Response</text> and <text>$Response2</text> tags in lines 77 and 79 after the </unit> and before the </result> tag if you want, I removed them currently.
See the picture below as an example of how the result looks like in PRTG.
Create the following script in C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML and make sure you have the C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Dfsr\ and the C:\Windows\SysWow64\WindowsPowerShell\v1.0\Modules\Dfsr\ folders – you might need to copy them over. If you miss them at all, you might need to add the needed Windows Roles/Features or install the RSAT (Remote Server Administration Tools) on your system.
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | Param( $SourceComputer=$args[0], $DestinationComputer=$args[1], $MaxBackLog=$args[2] ) Import-Module Dfsr #Import-Module -FullyQualifiedName "C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Dfsr\DfsrPowerShell.dll" #Module needs to be in System32 and SysWow64 directory - make sure the path exists in both cases $Count=-1 $TotalSize=0 $Count2=-1 $TotalSize2=0 $Response="-1:Script did not execute right" $Response2="-1:Script did not execute right" $err = $null $BackLog = Get-DfsrBacklog -SourceComputerName "$SourceComputer" -DestinationComputerName "$DestinationComputer" -ea SilentlyContinue -ev err; If ($err -ne $null) { $Response="-2:Script error with GET-DFSRBACKLOG" } Else { $Response = "-3:Error getting count" $Count = $BackLog.Count If ($Count -gt $MaxBackLog) { $Response = "Alarm - Backlog is over defined maximum of $MaxBackLog" } Else { $Response = "OK" } ForEach($Item in $BackLog) { $file = $Item.FullPathName $file = $file -replace ":", "$" $file = "\\$SourceComputer\$file" If (Test-Path $file) { $TotalSize += (Get-Item $file).Length } } } $err = $null $BackLog2 = Get-DfsrBacklog -DestinationComputerName "$SourceComputer" -SourceComputerName "$DestinationComputer" -ea SilentlyContinue -ev err; If ($err -ne $null) { $Response2="-2:Script error with GET-DFSRBACKLOG" } Else { $Response2 = "-3:Error getting count" $Count2 = $BackLog2.Count If ($Count2 -gt $MaxBackLog) { $Response2 = "Alarm - Backlog is over defined maximum of $MaxBackLog" } Else { $Response2 = "OK" } ForEach($Item in $BackLog2) { $file = $Item.FullPathName $file = $file -replace ":", "$" $file = "\\$DestinationComputer\$file" If (Test-Path $file) { $TotalSize2 += (Get-Item $file).Length } } } $XML = "<prtg>" $XML += "<result><channel>BackLog count 1</channel><value>$Count</value><unit>Count</unit></result>" $XML += "<result><channel>BackLog size 1</channel><value>$TotalSize</value><unit>BytesFile</unit></result>" $XML += "<result><channel>BackLog count 2</channel><value>$Count2</value><unit>Count</unit></result>" $XML += "<result><channel>BackLog size 2</channel><value>$TotalSize2</value><unit>BytesFile</unit></result>" $XML += "</prtg>" Function WriteXmlToScreen ([xml]$xml) { $StringWriter = New-Object System.IO.StringWriter; $XmlWriter = New-Object System.Xml.XmlTextWriter $StringWriter; $XmlWriter.Formatting = "indented"; $xml.WriteTo($XmlWriter); $XmlWriter.Flush(); $StringWriter.Flush(); Write-Output $StringWriter.ToString(); } WriteXmlToScreen $XML |