What is this?

This knowledgebase contains questions and answers about PRTG Network Monitor and network monitoring in general.

Learn more

PRTG Network Monitor

Intuitive to Use. Easy to manage.
More than 500,000 users rely on Paessler PRTG every day. Find out how you can reduce cost, increase QoS and ease planning, as well.

Free Download

Top Tags


View all Tags

How to monitor DFS replication status

Votes:

0

How to monitor DFS replication on several servers/sites

dfs server windows

Created on Oct 17, 2016 11:40:48 AM



Best Answer

Accepted Answer

Votes:

3

Below you find my modified and extended version for DFS monitoring...

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.

PRTG Example

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.

Script: Get-DFS-Backlog-For-Servers.ps1

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

This whole article can also be found on my personal blog-page where I posted more useful scripts - partly for PRTG as well https://www.it-admins.com/monitor-dfs-replication-backlog-between-servers-in-prtg

Regards Florian Rossmark

Created on Jul 10, 2018 3:15:38 PM



13 Replies

Votes:

9

While looking at at way to monitor our DFS replication I stumbled upon the DFS Backlog By monitoring the DFS Backlog on each server we get a good and solid view to the state of our DFS replication. As DFS replication are known to take it's time to come around its replication we allow quite some time before changing status to failed.

Implementation:

The script was saved under "Custom Sensors/EXE" with the name "Get-DFS-Backlog-For-Server.ps1"

Param(
	$hosttransfere=$args[0]
)

import-module Dfsr

$computername = [System.Net.Dns]::GetHostByAddress($hosttransfere).hostname
$computername = $computername.Replace(".domainname.com","")
$testDFSBacklog = Get-DfsrBacklog -computername $computername

$count = -1
ForEach($Item in $testDFSBacklog)
{	
	If($count -eq -1){$count = 0}
	$count += $Item.Backlog
}

Write-host $count,":OK"

Monitoring:

The sensor was then added to a server running DFS as a "EXE/Script" sensor.

  • Tag: DFS
  • EXE/Scripts: Get-DFS-Backlog-For-Server-ps1
  • Parameters:'%host'
  • Timeout (Sec.): 600
  • EXE Result: " Write EXE result to disk in case of error"
  • Scanning Interval: 1 hour

When a Sensor Reports an Error: Set sensor to warning for 5 intervals, then set to "down"


Finally the Channel was altered to have:

  • "Upper Error Limit (#)" of 50.000 (this is to be adjusted according to your number of files in DFS)
  • "Lower Error Limit (#)" 0 (as the script starts at -1 until contact with the server is in place this will tell you if the servers was available at the time)

The sensor was added to several servers and displayed in a Custom map Object build on the "Top 10 list container" The Object was saved under "webroot/mapobjects" with the name "Top10 Count-DFS.htm"

Sorting and columns can be altered as you wish to see them.

<!--Custom Collection: DFS-->

<div class="map_object map_table" id="<@itemid>" objectid="<@objectid>" subid="<@subid>" style="overflow:auto;<#mapobject type="coordinates" subid="<@subid>" mode="<@editmode>">">
<#mapobject type="objectgrip" mode="<@editmode>">
<#mapobject type="htmlbefore" subid="<@subid>">
<#checkobjecttype objecttype="probenode,group,device" nicemessage="true" id="<@objectid>">

			<div class="top10listcontainer" style="overflow:hidden">
			<#lang default="DFS (@@@@)" var="tabletitle">
			<#table tableid="sensortable"
					   content="sensors"
					   columns="lastvalue,sensor"
					   sortby="sensor"
_subid='2'
					   sortable="false"
					   refreshable="false"
					   infoheader="false"
					   links="false"
					   filter_tags="@tag(DFS)"
					   count="15"
					   varexpand="tabletitle"
					   tabletitle="DFS Backlog (1 hour update)"
                       id="<@objectid>">
			</div>


<#mapobject type="htmlafter" subid="<@subid>">
</div>



I hope this can help some of you - It has given us a big help in our daily monitoring :)

Edit: Some changes to formatting. Thank you for sharing!
In Addition: Thanks to Florian for a modified and extended version for DFS monitoring here.

Created on Oct 17, 2016 1:13:51 PM

Last change on Jul 11, 2018 12:55:52 PM by  Birk Guttmann [Paessler Support]



Votes:

0

Hi I've now set this up exactly as above but all I see under last value is -1. When I manually check the backlog there are 50 plus items. Do you know what would be causing this to display the wrong item count?

Created on Mar 29, 2018 8:09:50 AM



Votes:

0

Hello there,

In order to get further, you can analyse the sensor results. Please enable "Write result to disk" in the sensor's "Settings" tab. With the next scan it will write one or several result-files into "C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Sensors)" of your PRTG server (or on the Remote Probe if applicable). All files have the sensor's numeric ID in their filenames. The sensor ID can be found on the sensor's "Overview" tab.

Please do not hesitate to ask further questions.


Kind regards,
Birk Guttmann, Tech Support Team

Created on Mar 29, 2018 2:40:32 PM by  Birk Guttmann [Paessler Support]



Votes:

1

Hi

The -1 indicates that no contact has been taken with the server that you are requesting DFSR information from It is most likely a powershell connection problem

Try to run this code on your PRTG server (the one executing the sensor) to validate teh powershell connection

import-module Dfsr
Get-DfsrBacklog -computername $computername

Created on Apr 3, 2018 7:47:54 AM

Last change on Apr 3, 2018 8:19:56 AM by  Birk Guttmann [Paessler Support]



Accepted Answer

Votes:

3

Below you find my modified and extended version for DFS monitoring...

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.

PRTG Example

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.

Script: Get-DFS-Backlog-For-Servers.ps1

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

This whole article can also be found on my personal blog-page where I posted more useful scripts - partly for PRTG as well https://www.it-admins.com/monitor-dfs-replication-backlog-between-servers-in-prtg

Regards Florian Rossmark

Created on Jul 10, 2018 3:15:38 PM



Votes:

0

Hi Florian,

Thanks a lot for sharing your work. We appreciate that.


Kind regards,
Birk Guttmann, Tech Support Team

Created on Jul 11, 2018 12:50:16 PM by  Birk Guttmann [Paessler Support]



Votes:

0

Hi! Thank you for the script.

Any clues why it gives me "incorrect format answer:

$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>"

??

thx!

Created on Apr 3, 2019 3:07:23 PM

Last change on Apr 4, 2019 8:50:14 AM by  Birk Guttmann [Paessler Support]



Votes:

1

Hi Yupsolo,

What you posted is a part of the PowerShell script. I don't see an issue there.

Assuming PRTG says incorrect format, can you please enable the script logging and post the information?

Write sensor result to disk (Filename: Result of Sensor [ID].txt)

I don't think the XML output is the issue, there is likely another issue that prevents the script to execute correctly.

Regards

Florian

Created on Apr 4, 2019 1:41:28 PM



Votes:

0

Hey crew,

Thought i'd post what enabled this sensor to work in our environment.

We have many sites with local file servers. We have a few main file servers in our datacentre. Each data centre file server may contain information for 5-10 remote site file server sync'd files. Because of this the main file server will have different files to the local file server. Therefore we needed the additional switches for groupname and foldername.

Param(
$SourceComputer=$args[0],
$DestinationComputer=$args[1],
$GroupName=$args[2],
$FolderName=$args[3]
)

We were only wanting the file count so modified the command to be:

$err = $null 
$Count = (Get-DfsrBacklog -SourceComputerName "$SourceComputer" -DestinationComputerName "$DestinationComputer" -GroupName "$GroupName" -FolderName "$FolderName" -ea SilentlyContinue -ev err -verbose 4>&1).Message.Split(':')[2];      
If ($err -ne $null) 
{ 
    $Response=$err #"-2:Script error with GET-DFSRBACKLOG"

The other thing we had to do was change the security context of the sensor:
- sensor\settings\security context = "Use Windows credentials of parent device"

Thanks again Florian for giving back to the community. If there's ever a nomination of best PRTG guy forward it to me and i'll nominate you mate!

Cheers

Dean

Created on Oct 29, 2019 1:24:34 AM

Last change on Oct 29, 2019 5:30:31 AM by  Sven Roggenhofer [Paessler Technical Support]



Votes:

0

I've been able to get the sensor created and running, but with the dreaded -1 result. Strange thing is that the script returns the correct values if I run it manually.

Script run using the sensor

<prtg> <result> <channel>CLT to PDX BackLog Count</channel> <value>-1</value> <unit>Count</unit> </result> <result> <channel>CLT to PDX BackLog Size</channel> <value>0</value> <unit>BytesFile</unit> </result> <result> <channel>PDX to CLT BackLog Count</channel> <value>-1</value> <unit>Count</unit> </result> <result> <channel>PDX to CLT BackLog Size</channel> <value>0</value> <unit>BytesFile</unit> </result> </prtg>

Script executed manually:

<prtg> <result> <channel>CLT to PDX BackLog Count</channel> <value>101</value> <unit>Count</unit> </result> <result> <channel>CLT to PDX BackLog Size</channel> <value>374728560</value> <unit>BytesFile</unit> </result> <result> <channel>PDX to CLT BackLog Count</channel> <value>-0</value> <unit>Count</unit> </result> <result> <channel>PDX to CLT BackLog Size</channel> <value>0</value> <unit>BytesFile</unit> </result> </prtg>

Any ideas?

Created on Sep 22, 2021 6:58:15 PM

Last change on Sep 23, 2021 3:32:39 PM by  Felix Wiesneth [Paessler Support]



Votes:

0

Matt,

That channel is putting a negative before both responses. You can see it's -1 when the sensor executes it, and -0 when you execute it manually. That needs to be corrected.

Benjamin Day
[Paessler Support]

Created on Sep 24, 2021 7:16:53 PM by  Benjamin Day [Paessler Support] (1,441) 2 1



Votes:

0

Hi all!

The script that Florian posted looks like it might be exactly what we're looking for! Could someone post how the parameters should be set up in order to pass in the two server names and a limit integer value?

Created on Sep 25, 2023 7:24:07 PM



Votes:

0

Test it simply on a PowerShell prompt with scriptname.ps1 "server1","server2",100 this should give you some XML code back with the results. If you see an error, you need to investigate it, likely rights issues or missing tools like remote management tools.

It's also explained here, as mentioned before: https://www.it-admins.com/monitor-dfs-replication-backlog-between-servers-in-prtg/

Should be very straightforward.

Florian

Created on Sep 27, 2023 12:54:25 PM




Disclaimer: The information in the Paessler Knowledge Base comes without warranty of any kind. Use at your own risk. Before applying any instructions please exercise proper system administrator housekeeping. You must make sure that a proper backup of all your data is available.