Home > Powershell, Scripting > Powershell and DFSR

Powershell and DFSR

Rating 4.00 out of 5

Sorry for the long delay between posts, but work has been absolutely crazy.

Anyway, one of the recent tasks I have been working on is to find a way to check DFSR to make sure that our remote sites are properly replicating data back to our corporate datacenter.  Part of this new infrastructure relies heavily on Microsoft DFSR and all the cool stuff it brings (in 2003 R2).

Our support teams have been asking for ways to ensure that data has completely synchronized to our corporate datacenter every night.  Unfortunately there isn’t an easy way to determine this scriptomatically.  Well leave it to me to try some different things and attempt to put SOMETHING in place to do this.

Basically we have remote sites replicating during non-business-hours back to a central “hub” DFSR server.  We would then backup this “hub” server with our corporate backup infrastructure.  This is a WHOLE lot easier than getting users in remote sites to swap tapes or whatever and send them offsite, etc. 

The only way I have been able to determine the state of replication is to query the “backlog” of the remote site DFSR servers.  This should tell us how many files are sitting there awaiting replication. DFSRDIAG is a tool that can help us enumerate these files, but then we have to parse out the data.  We also need to know which replication partner, which replicated folder, and which replication group these remote sites belong to.

One way to enumerate that info is through a WMI query.  From the DFSR “hub” server you can enumerate all DFSR connections, groups, folders, etc. by running some queries against the “MicrosoftDFS” namespace.  This is different from standard WMI queries because the default namespace (cimv2) does not contain any DFSR configuruations.

Once we connect to this namespace, it is a fairly trivial task to cycle through all the connection partners, replication groups, and replicated folders.

We can then run the “DFSRDIAG” tool to see how many files are in the backlog.

Once we have determine how many files are out there for each replicated folder, we then write a custom event log entry and have our monitoring tools pick those up.

For this script I have set a threshold of 10 files before writing an “error” event log.  This can easily be changed based on your specific needs, though.  

You should also be able to easily customize the eventIDs and source information by modifying the values assigned to those variables.

For actually writing to the event log, I am “borrowing” some code my colleauge Mike put together.

Anyway, I think the script is fairly self explanitory.  If you need additionaly info or have questions, please let me know.

Thanks and happy scripting…

– Mark

## Check-DFSR.ps1 script
## Written by: Mark A. Weaver
## Site: http://www.vmweaver.com
## Version: 2.0
## Date: 5/7/2009
## Purpose: This script will query the local WMI root for DFS replication groups and folders.  
##				It will then run DFS utilities to determine the number of files in the backlog on the
##          destination partners in the replication group.
##          
##          This script was written for the spefic use of being run on a centralized DFSR server
##          which acts as the HUB for remote office backups.
##         
##        
##          Monitoring Rules can be setup to collect and report on the events being generated.
## 
##          Event information is written to the Application log using the EventIDs at the bottom.
## Input: None
#############################
## Updates:
##  20090408 Weaver: Fixed issue where multiple events are generated throughout the execution
##  20090408 Weaver: Added BacklogFileCount to event message
##  20090409 Weaver: Fixed list of replication connections issue due to change in replication topology
##  20090507 Weaver: Added functionality to return results from all partners in the replication
##
##
######################################################################
######################################################################
# Write-Event powershell function
# Written by Mike Hays
# http://blog.mike-hays.net
#
#
 
function Write-Event(
	[string]$Source = $(throw "An event Source must be specified."),
	[int]$EventId = $(throw "An Event ID must be specified."),
	[System.Diagnostics.EventLogEntryType] $EventType = $(throw "Event EventType must be specified. (Error, Warning, Information, SuccessAudit, FailureAudit)"),
	[string]$Message = $(throw "An event Message must be specified."),
	$EventLog
)
{
	#Uncommon event logs can be specified (even custom ones), but since that isn't generally
	#the desired result, I prevent that here
	$acceptedEventLogs = "Application", "System"
	if ($eventEventLog -eq $null)
	{
		$eventEventLog = "Application"
	}
	elseif (!($acceptedEventLogs -icontains $eventEventLog))
	{
		Write-Host "This function supports writing to the following event logs:" $acceptedEventLogs
		Write-Host "Defaulting to Application Eventlog"
		$eventEventLog = "Application"
	}
 
	#Create a .NET object that is connected to the Eventlog
	$event = New-Object -type System.Diagnostics.Eventlog -argumentlist $EventLog
	#Define the Source property
	$event.Source = $Source
	#Write the event to the log
	$event.WriteEntry($Message, $EventType, $EventId)
}
 
######################################################################
######################################################################
## Main 
## Errors written:
##   Log File: Application
##   Source: Check-DFSR Script
##   ID: 9500 - Lists fully replicated replication folders
##   ID: 9501 - Lists replication folders with less than the $BacklogErrorLevel files waiting 
##   ID: 9502 - Lists replication folders with more than the $BacklogErrorLevel files waiting
##   ID: 9503 - If a connection is not pingable, this event is written.
 
$BacklogErrorLevel = 10 
 
$ComputerName = $env:ComputerName
## Query DFSR groups from the local MicrosftDFS WMI namespace.
$DFSRGroupWMIQuery = "SELECT * FROM DfsrReplicationGroupConfig"
$RGroups = Get-WmiObject -Namespace "root\MicrosoftDFS" -Query $DFSRGroupWMIQuery
 
 
## Setup my variables
$ping = New-Object System.Net.NetworkInformation.Ping
$SuccessAudit = $Null
$WarningAudit = $Null
$ErrorAudit = $Null
$EventSource = "Check-DFSR Script"
$SuccessEventID = 9500
$WarningEventID = 9501
$ErrorEventID = 9502
$NoPingEventID = 9503
 
foreach ($Group in $RGroups)
{
	## Cycle through all Replication groups found
	$DFSRGFoldersWMIQuery = "SELECT * FROM DfsrReplicatedFolderConfig WHERE ReplicationGroupGUID='" + $Group.ReplicationGroupGUID + "'"
	$RGFolders = Get-WmiObject -Namespace "root\MicrosoftDFS" -Query $DFSRGFoldersWMIQuery
 
	## Grab all connections associated with a Replication Group
	$DFSRConnectionWMIQuery = "SELECT * FROM DfsrConnectionConfig WHERE ReplicationGroupGUID='" + $Group.ReplicationGroupGUID + "'"
	$RGConnections = Get-WmiObject -Namespace "root\MicrosoftDFS" -Query $DFSRConnectionWMIQuery	
	foreach ($Connection in $RGConnections)
	{
 
		$ConnectionName = $Connection.PartnerName.Trim()
		$IsInBound = $Connection.Inbound
		$IsEnabled = $Connection.Enabled
 
		## Do not attempt to look at connections that are Disabled
		if ($IsEnabled -eq $True)
		{  
			## If the connection is not ping-able, do not attempt to query it for Backlog info
			$Reply = $ping.send("$ConnectionName")
			if ($reply.Status -eq "Success")
			{
 
 
				## Cycle through the Replication Folders that are part of the replication group and run DFSRDIAG tool to determine the backlog on the connection partners.
				foreach ($Folder in $RGFolders)
				{
					$RGName = $Group.ReplicationGroupName
					$RFName = $Folder.ReplicatedFolderName
 
					## Determine if current connect is an inbound connection or not, set send/receive members accordingly
					if ($IsInBound -eq $True)
					{
						$SendingMember = $ConnectionName
						$ReceivingMember = $ComputerName
					}
					else
					{
						$SendingMember = $ComputerName
						$ReceivingMember = $ConnectionName
					}
					   $Out = $RGName + ":" + $RFName +  " - S:"+$SendingMember + " R:" + $ReceivingMember 
					   Write-Host $Out
						## Execute the dfsrdiag command and get results back in the $Backlog variable
						$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)
						{
							#Update Success Audit 
							$SuccessAudit += $RGName + ":" + $RFName + " is in sync with 0 files in the backlog from "+ $SendingMember + " to " + $ReceivingMember +".`n"					
 
						}
						elseif ($BacklogFilecount -lt $BacklogErrorLevel)
						{
							#Update Warning Audit
							$WarningAudit += $RGName + ":" + $RFName + " has " + $BacklogFileCount + " files in the backlog from " + $SendingMember + " to " + $ReceivingMember + ".`n"
						}
						else
						{
							#Update Error Audit
							$ErrorAudit += $RGName + ":" + $RFName + " has " + $BacklogFilecount + " files in the backlog from " + $SendingMember + " to " + $ReceivingMember + ".`n"
						}
						#Write-Host + $Folder.ReplicatedFolderName "- " $BackLogFilecount -foregroundcolor $FGColor
					}
				}
				else
				{ 
				Write-Host $ConnectionName "is not pingable" 
				$NoPingMessage = "Server """ + $ConnectionName + """ could not be reached.`nPlease verify it is on the network and pingable."
				Write-Event $EventSource $NoPingEventID "Warning" $NoPingMessage "Application"
				}
			}
 
	}
 
}
## Write my events to the local Application log.
 
if ($SuccessAudit -ne $Null)
{
	Write-Event $EventSource $SuccessEventID "Information" $SuccessAudit "Application"
}
 
if ($WarningAudit -ne $Null)
{
	Write-Event $EventSource $WarningEventID "Warning" $WarningAudit "Application"
}
 
if ($ErrorAudit -ne $Null)
{
	Write-Event $EventSource $ErrorEventID "Error" $ErrorAudit "Application"
}
Categories: Powershell, Scripting Tags: , ,
  1. Ferrell Fuller
    April 29th, 2009 at 07:53 | #1

    Hey there… Your script is awesome however, i have a request… Can you help me out in modifying it to do multiple rep groups, with multiple connections and have it report on backlogs from both sides? As it stands, its only reporting on the hub server… as you stated in your post. Thanks in advance!!

  2. April 29th, 2009 at 16:03 | #2

    Let me look into that.
    I am actually in the process of doing “Version 2″ which will include some of this.
    Are you doing a full-mesh type of topology for replication?
    Can you give me an example of what this environment may look like?
    — Mark

  3. Ferrell Fuller
    April 30th, 2009 at 08:53 | #3

    Thank you!! The envrionment is a full Mesh consisting of 5 sites. Windows Server 2008. 6 replicas with meshed connections to other members. Thanks so much for your contributuion. I mucked with the script and got it to simi work but i’m just a hack. Thanks again!

  4. Ferrell Fuller
    May 6th, 2009 at 14:54 | #4

    Any Luck on the new version? Thanks bud!

  5. May 7th, 2009 at 17:54 | #5

    I have updated the script in my post to reflect some changes. This should now look at all inbound and outbound connections on a given server and look at all connection partners to report where backlog files exist.
    Let me know if additional clarification is needed.

    Thanks!
    — Mark

  6. Serge
    May 17th, 2009 at 03:11 | #6

    Hello,

    you seem to be skilled in scripting and DFSR knowledge ! Simple question but almost philosophical response : do you know why some directories are not replicated though the health reports and the DFSR eventlog are clean ?
    11 servers replicating users volumes to one hub server through 44 RG for centralized backup…
    Bootle in the see…

    Greetings from France,
    SR

  7. May 17th, 2009 at 12:03 | #7

    SR,
    A few things to check:

    Have you set up any special filters for replication? I think by default DFSR will not replicate ~*.*,*.bak, and *.tmp files. If you plan on replicating SQL backups, then you will need to remove the *.bak filter. Filters are set per replication group.

    Are you doing one-way replication from remote site to your hub? One thing I noticed (and will spend some time trying to figure out) is that if files/folders are deleted from the receiving member of a one-way replication, then those folders are NOT “re-replicated” from the sending memeber.

    Have you look in the DFSR log files on both sending and receiving servers?
    They are at %systemroot%\Debug.

    Other things to look at would be to make sure your Staging Folder size is large enough to handle the size of your data. I think MS recommends it be twice as large as your largest file you want to replicate.

    I don’t know that I can reproduce what you are experiencing, but would be happy to help if I can.

    Merci Beaucoup!
    – Mark

  8. May 21st, 2009 at 05:17 | #8

    Hi Mark

    I have to take my hat off to you! I have been struggling with trying to get some kind of decent monitoring of DFSR backlogs for some time now. Finding your script has made my life a lot easier, so thank you very much!!!!

    Just one small change I would recommend is to quote out the RFName and RGName for cases where you may have spaces and/or &’s like I have (yes I know its a nasty thing to do having dodgy characters in Namespaces but hey I’m stuck with it). Anyway, I achieved this by making the following change to your script:-

    $BLCommand = “dfsrdiag Backlog /RGName:’” + $RGName + “‘ /RFName:’” + $RFName + “‘ /SendingMember:” + $SendingMember + ” /ReceivingMember:” + $ReceivingMember

    Note the single ‘ quotes!

    I have integrated this script into my monitoring using Nagios and so far so good.

    Danny

  9. May 21st, 2009 at 19:24 | #9

    Danny,
    Thanks for the feedback and glad you found this helpful. Great suggestion on the mod. I will make that change on my next update!
    – Mark

  10. Dejan
    June 18th, 2009 at 00:31 | #10

    Hello!
    First of all, sorry for my bad english!
    My knowledge of DFSR is = 0!
    I have to write a script in powershell, which monitors the DFSR!
    So I find this wonderfully script of Mark! Thank you, is great!
    But I couldn’t find the WindowsDFS class in my WMI!
    Can somebody help me ??
    Thanks in advance!!

  11. June 18th, 2009 at 14:53 | #11

    Dejan,
    MicrosoftDFS is actually its own NAMESPACE. By default most WMI queries default to the root\CIMV2 namespace.
    If you are using the Get-WMIObject cmdlet, you will need to specify it as such:
    $DFSInfo = Get-WMIObject -Namespace “root\MicrosoftDFS” DfsrReplicatedFolderConfig

    This would bring back all of the ReplicatedFolderConfigs. If you are using a WMI Browser to look at WMI, then you will need to specify the WMI Namespace accordingly as “root\MicrosoftDFS”.

    Additionally, you will need to make sure you are on or connecting to a server that has DFSr on it.
    Let me know if you have additional questions or continue to have issues and I will help out if I can.

    – Mark

  12. Dejan
    June 22nd, 2009 at 00:42 | #12

    Hello Marko,
    Thank you for your quick reaction!

    I’m an apprentice and haven’t much experience!
    My task is to write(or find) a Powershell-Script,which monitors DFS-R.
    This monitoring should be on a FileServer and should show me if the files are replicated on a other FileServer.
    Currently I test the replication so that I start a remote control on a server and for examlpe create a .txt file on one server and watch if the same work was done on the other! And this should be monitored!

    When I open the WMI Object Browser on my local pc, and wirte the Namespace “root\MicrosoftDFS”
    this error show up: Login failed to machine “..my hostname..”

    So my question is, whether I should open the WMI Objct Browser on my machine or on the Server ?
    What I need for the finished work! (Powershell, WMI.. and what else ?

    I’m from Germany and my english ist not good, sorry for my bad phrasing!!
    Thank you in advance !

  13. June 22nd, 2009 at 09:13 | #13

    Dejan,
    You will only see the “root/MicrosoftDFS” namespace on the servers running DFSr, so you will need to open the WMI browser on the Server.
    I would say you will need the following:
    1. Windows Server 2003 or greater (I have only tested mine on Windows 2003 R2 and Server 2008)
    2. DFS Replication installed
    3. WMI should already be there
    4. Powershell v1.0 or greater (Requires .NET 2.0 framework or greater)

    One approach is to use the “Backlog File count” which is what my script does. The assumption is that if it comes back as “0″ then we have fully replicated the data.

    If you do not have a lot of data, another approach may be to compare the directories and files on one server to the other server.

    If you run this script on one of your servers, it should tell if you have backlogged files on both servers.

    I hope this helps.

    – Mark

  14. Dejan
    June 23rd, 2009 at 05:42 | #14

    Hello Marc,
    it was a help for me!
    But when I “Set Initial Tree Root” and chose for example DfsrConfig, then I get the error “Login failed to machine “..server-name..”. Cannot access WMI on the target machine.”

    Do you know if I can monitor DFS-R without WMI?
    I need just a script, which return 0,1 or 2, for nagios!!
    The script should be a .bat file!! Can your script help me ?

    Do you have some ideas for me ?
    Thank you for your time!! stören

  15. Dejan
    June 23rd, 2009 at 05:45 | #15

    sorry! marK !

  16. Dejan
    June 24th, 2009 at 11:36 | #16

    Do you have some idea for me ??
    Please help !!

  17. June 26th, 2009 at 15:02 | #17

    Dejan,
    Sorry. Been a crazy week at work.
    What version of Windows are you running DFS on? 2000? 2003? 2003R2? 2008?

    You will need to make sure that you are logged into the server or connecting to the server with an Administator account.

    I am not sure why the WMI provider isn’t working for you, but you could do it a manual way using a simple batch script (or in Powershell if you wanted).

    You could create a CSV file that includes the Replication Group, Replicated Folder Name, SendingMember, Receiving Member.
    Then you would read the file and cycle through each line in it and run the DFSRDiag command with the appropriate syntax.
    For Example:
    C:\Temp\DFS.txt
    NAReplicationGroup,Users,NAServ1,NAServ2
    NAReplicationGroup,Users,NAServ2,NAServ1

    If you had a file with this contents could write a batch script like this:

    @Echo off
    for /f "tokens=1,2,3,4 delims=," %%i in (C:\Temp\DFS.txt) DO (
          for /f "tokens=2* delims=:" %%m in ('dfsrdiag backlog /RGName:"%%i" /RFName:"%%j" /SendingMember:"%%k" /ReceivingMember:"%%l" ^| find /i "Backlog File count"') do (
          if not defined %%m (echo [ReplicationGroup:%%i] [Replicatedfolder:%%j] has%%m files in the backlog from %%k to %%l)
         )
      )
    

    This would output whether something had items in the backlog. Instead of Echo-ing to the screen you could write an event or log file too.
    In this example, the CSV file would contain
    ReplicationGroup,ReplicatedFolder,SendingMember,ReceivingMember
    %%i is the ReplicationGroupName
    %%j is the Replicated Folder name
    %%k is the Sending Member
    %%l is the Receiving Member
    %%m will be the number of files in the backlog (unless it is “0″)

    Not sure if this is what you were looking for, though.

    – Mark

  18. Dejan
    June 29th, 2009 at 02:48 | #18

    Good Morning Mark,

    I running Windows Server 2003 R2 !!

    But WMI..
    When I write the Maschine Name ‘..server-name..’ and the Starting Namespace ‘root/MicrosoftDfs’ and click ‘Connect’, then I get a connection.
    The problem is: When I add a class f.e.’DfsrConfig’ and click the Ok-Button. After that a result window opens and there is the ‘DfsrConfig’ class, but when I try to login, I get the error ‘Login failed to machine ‘..server-name..’. Cannot access WMI on the target machine.’

    I’am a administrator of the server and could create remote control on the server through the CMDlet -> mstsc!!
    Perhaps it’s possible monitor the Dfs-R without WMI ??
    Do you know where I can find a good and simple tutorial or documentation ?

    At best would be a very small script which monitor the Dfs-R and returns 0,1 or 2!
    Then I would give it to my colleague and he would finish the work with Nagios.

    Thank you Mark,
    regards Dejan!

  19. Dejan
    July 2nd, 2009 at 01:21 | #19

    Should I start perhaps some services ??

  20. July 7th, 2009 at 10:36 | #20

    Dejan,
    Please verify that the “DFS Replication” and “Windows Management Instrumentation” services are running.
    The only purpose for WMI in my script is to be able to find information about the replication groups, replication folders, and partners.
    If you see the small batch script I replied with previously, you should be able to NOT use WMI, but you will need to manually create the CSV file containing all replicated folders, replication groups, and connections, etc.
    Have you actually tried logging into the server running DFS (via mstsc) with Administrator credentials and executing the powershell script or are you just trying to browse WMI?
    – Mark

  21. Dejan
    July 27th, 2009 at 05:10 | #21

    Hey Mark,

    my problem is, that I dont know how I should do my task.

    I have local: your script;a software for the script(PowerGUI Script Editor); WMI Object Browser)
    And I have the server, on which I could connect me with my account!
    What I have to do now? What work I have to do local and what on the server ?

    Should I make some changes in your script or just copy-paste?

    Thank you very much!
    Regards Dejan!

  22. July 30th, 2009 at 19:18 | #22

    Do you have Powershell on the server?
    If you do, can you run the script on the server?
    If you are trying to run the script from you computer (local) there will need to be a LOT of changes to the script to be able to run it against a remote server.

    The easiest is to install Powershell on the server, and run the script on the server.

    This script was not written to run “local”, but to be run on the server.

    I hope that makes sense.
    – Mark

  23. Dejan
    August 3rd, 2009 at 00:47 | #23

    hey mark,
    I think this would help me,
    but my chief want that I realize it local!!

    Can you say me exactly what I have to change in the Script ?
    Please help!!

    Thanks!!

  24. Dejan
    August 3rd, 2009 at 07:25 | #24

    Ok, i’ve now installed Powershell on the server and execute the script on Powershell.

    I get this: fs-replication:E: – S:**server2** R:**server1**
    fs-replication:E: – S:**server1** R:**server2**

    Is it all ? How I now whether the replication did work ?

    Thanks!

  25. August 3rd, 2009 at 18:04 | #25

    Dejan,
    Glad you have it running.
    Basically those are just status messages. There should be events written to the Application Event log on the server.

    ## Errors written:
    ## Log File: Application
    ## Source: Check-DFSR Script
    ## ID: 9500 – Lists fully replicated replication folders
    ## ID: 9501 – Lists replication folders with less than the $BacklogErrorLevel files waiting
    ## ID: 9502 – Lists replication folders with more than the $BacklogErrorLevel files waiting
    ## ID: 9503 – If a connection is not pingable, this event is written.

    Check those out. By default, if there are more than 10 files in the backlog, it will throw 9502 as Error, between 1 and 10, it will throw 9501 as a warning, and 0 files will throw 9500 as informational.

    I am not sure if Multilanguage versions of Windows call the log “Application”. If you don’t see them in the Event log, you may need to change the following lines, replacing “Application” with the actual name of the event log you want:

    ## Write my events to the local Application log.

    if ($SuccessAudit -ne $Null)
    {
    Write-Event $EventSource $SuccessEventID “Information” $SuccessAudit “Application”
    }

    if ($WarningAudit -ne $Null)
    {
    Write-Event $EventSource $WarningEventID “Warning” $WarningAudit “Application”
    }

    if ($ErrorAudit -ne $Null)
    {
    Write-Event $EventSource $ErrorEventID “Error” $ErrorAudit “Application”
    }

    and Also change this line:

    $acceptedEventLogs = “Application”, “System”

    to include the proper spelling of the event log.

    Hope this helps!
    — Mark

  26. Dejan
    August 4th, 2009 at 02:46 | #26

    Hello Mark!
    Thanks for fast reaction!

    “Application” is right! It was my mistake, because I didn’t know, what i have to write in powershell!
    I think all is work well, I just don’t know where I can see the output!

    I write in powershell: powershell.exe C:\Script.ps1
    then I get this:
    fs-replication:E: – S:**server2** R:**server1**
    fs-replication:E: – S:**server1** R:**server2**

    So I write: get-eventlog -logName Application -newest 1
    and I get this:
    9500,**Server1**,System.Byte[],7922,(0),0,Information,”fs-replication:E: is in sync with 0 files in the backlog from **Server2** to **Server1**.
    fs-replication:E: is in sync with 0 files in the backlog from **server1** to **server2**.
    “,”Check-DFSR Script”,System.String[],9500,”8/4/2009 10:10:34 AM”,”8/4/2009 10:10:34 AM”,,,

    I think this looks very good!!

    Now my question, did I have write the right commands ??
    What command I have to write ?

    Can I find the output”9500,**server1**…” anywhere ??
    perhaps as a .txt file or something like that ?
    or must I export the file personally?

    regards Dejan

  27. August 4th, 2009 at 11:14 | #27

    Dejan,
    Fantastic!
    One thing you can do if you want to see output as well as finding it in the Application Eventlog is to modify these lines (at the bottom of the script). This will write the output the screen and to the Eventlog:

    Write-Host “`n`n**********************************”
    Write-Host “** DFS Audit Results **”
    Write-Host “**********************************`n”
    if ($SuccessAudit -ne $Null)
    {
    Write-Event $EventSource $SuccessEventID “Information” $SuccessAudit “Application”
    Write-Host “*** Informational ***” -Foreground Green
    Write-Host $SuccessAudit -Foreground Green
    }

    if ($WarningAudit -ne $Null)
    {
    Write-Event $EventSource $WarningEventID “Warning” $WarningAudit “Application”
    Write-Host “*** Warning ***” -Foreground Yellow
    Write-Host $WarningAudit -Foreground Yellow
    }

    if ($ErrorAudit -ne $Null)
    {
    Write-Event $EventSource $ErrorEventID “Error” $ErrorAudit “Application”
    Write-Host “*** ERROR ***” -foreground RED
    Write-host $ErrorAudit -foreground RED
    }

  28. Shane
    August 4th, 2009 at 13:56 | #28

    How hard would it be to get the script to send an email via exchange to a distribution group?

    What about having it create output in html format?

    Great Script btw, it’s running flawless right of the box on our systems.

  29. August 4th, 2009 at 18:31 | #29

    Shane,
    Thanks for the feedback.
    On your Exchange question. I have NO idea. Sorry. I will look into it, though. If you see the previous reply to Dejan, you will find where in the code to “do” something based on the results.

    I will take both suggestions under consideration, though.
    Exporting to HTML should be cake, I think.
    It would be interesting to export some type of HTML report….
    Anyway.. I will see what I can come up with.
    — Mark

  30. Dejan
    August 5th, 2009 at 05:14 | #30

    Hi Mark!
    Thanks for dilation of the script!! I get the output =)

    Now I have to work with Nagios! With the NSClient !
    The Script should return
    0 for success,
    1 for warning,
    2 for error!
    I’ve did it, but I get only succes or warning!!
    ..
    Because of the replication success ever, i write the exit code always at the success command for testing.
    I write: “exit 0″ at “if ($BacklogFileCount -eq 0)..” – I get OK!
    I write “exit 1″ at “if ($BacklogFileCount -eq 0)..” – I get WARNING!
    I write “exit 2″ at “if ($BacklogFileCount -eq 0)..” – I get WARNING!!?!!
    I test also with exit 3 and get warning too!
    I never get the “error(critical)” warning !!

    Can Powershell only 0 and 1?
    Is “exit” proper or needs Powershell an other command ?
    Did I need a batch(.bat) file?
    Did you know what commands I need!

    Have a nice day
    Dejan

  31. Dejan
    August 10th, 2009 at 06:41 | #31

    Do you have any idea ?

  32. August 10th, 2009 at 10:24 | #32

    I am not sure how you are using the NetSaint client for nagios to call the powershell script, but if you do an “EXIT 0″ from a powershell script it causes POWERSHELL to exit with that ErrorLevel, not just the script.

    Only a single exit code can be sent, too.
    So, I assume that it should exit with the “worst” error code. I mean that if you have 3 replication groups and 1 is Good, 1 is Warning, and 1 is error, that the result should be error. Is this correct?

    If this is desired, then one way to do it would be to change the last bit of code to do this:

    if ($SuccessAudit -ne $Null)
    {
    Write-Event $EventSource $SuccessEventID “Information” $SuccessAudit “Application”
    $ExitCode = 0
    }

    if ($WarningAudit -ne $Null)
    {
    Write-Event $EventSource $WarningEventID “Warning” $WarningAudit “Application”
    $ExitCode = 1
    }

    if ($ErrorAudit -ne $Null)
    {
    Write-Event $EventSource $ErrorEventID “Error” $ErrorAudit “Application”
    $ExitCode = 2
    }

    Exit $ExitCode

    Pretty much just add the $ExitCode value you want for Success, Warning, and Error (in this example 0,1,2 respectively). These need to be in this order, too.

    Then Exit with that ExitCode.
    Again, I am not sure what the NetSaint client is looking for, but if it is looking for “ErrorLevel”, this should do it.

    — Mark

  33. Dejan
    August 11th, 2009 at 06:40 | #33

    hi mark,
    thanks!

    I get a timeout error!! Do you know which commando I need ?
    i write cmd /c echo c:\myScript.ps1 | powershell.exe -command -

    regards Dejan

  34. August 11th, 2009 at 13:42 | #34

    How are you trying to run it? As a scheduled Task? Interactively?

    if you wish to use CMD, you can do it like this:
    cmd /c “powershell c:\MyScript.ps1″
    – Mark

  35. Dejan
    August 17th, 2009 at 04:00 | #35

    hej mark,

    all works ! but the only problem is, that I get no ‘Critical’ on the Nagios!!
    Generally ‘exit 2′ ist for ther ‘Critical’ error!!
    !!! But I get always only a ‘Warning’ for the ‘exit 2′ !!!
    And for the ‘exit 1′ I get also ‘Warning’, this is correct!

    regards

  36. August 17th, 2009 at 09:15 | #36

    Dejan,
    Did you put the code in that I specified in the previous reply?
    Unfortunately I don’t really know anything about Nagios, so I won’t be of any help with that.

    The “errorlevel” that is coming from the exit of powershell may not be making it to the netsaint client.
    You could try running “powershell c:\MyScript.ps1″ instead of running “cmd /c powershell c:\MyScript.ps1″.

    Sorry I can’t help with the Nagios piece.
    — Mark

  37. Dejan
    August 19th, 2009 at 00:37 | #37

    hi mark

    Now all works fine!
    I delete the TABs in the script and it works :)

    regards

  38. Shane
    August 19th, 2009 at 16:33 | #38

    Danny :
    Hi Mark
    I have to take my hat off to you! I have been struggling with trying to get some kind of decent monitoring of DFSR backlogs for some time now. Finding your script has made my life a lot easier, so thank you very much!!!!
    Just one small change I would recommend is to quote out the RFName and RGName for cases where you may have spaces and/or &’s like I have (yes I know its a nasty thing to do having dodgy characters in Namespaces but hey I’m stuck with it). Anyway, I achieved this by making the following change to your script:-
    $BLCommand = “dfsrdiag Backlog /RGName:’” + $RGName + “‘ /RFName:’” + $RFName + “‘ /SendingMember:” + $SendingMember + ” /ReceivingMember:” + $ReceivingMember
    Note the single ‘ quotes!
    I have integrated this script into my monitoring using Nagios and so far so good.
    Danny

    What type of integration have you dont with Nagios so far and would you like to share? We are thinking about doing to the same.

  39. August 19th, 2009 at 18:06 | #39

    Shane,
    I haven’t actually done any work with Nagios, though Dejan (here on the comments) seems have gotten it to work. Please see the comments regarding this. Dejan may be able to shed some light on what changes were made to get it working.

    Do you currently have an implementation of Nagios? My understanding is that the NetSaint client can run scripts to check certain conditions. It seems that Exit Codes of 2, 1, 0 are Error, Warning, and Okay respectively. I am not sure if it is actually looking at “exitcodes” or if it actually looks at the ouput (looking for 2, 1, or 0).

    I modified the code (in a reply to Dejan) that may be helpful regarding generating a single exit code.

    Because of Dejan’s queries, I have been thinking about installing Nagios and “playing” with it to see what needs to happen.

    — Mark

  40. Sharon
    August 28th, 2009 at 10:55 | #40

    Mark,
    I too was very happy to see this script. I have a hub DFSR server (Windows Server 2008) and multiple branch servers (also Windows Server 2008) which are all replicating data to the hub DFSR server. Though it is set up fully meshed, files only change on the branck office servers.

    I’m not very proficient with powershell but copied your script as is into a .ps1 file. I then created a .bat file which calls the .ps1 file and scheduled the .bat file to run on a schedule. I see the 9500 events in the event logs and it properly finds all of the replication group connections in both directions. The problem I am having is that I only get 9500 events in the application event log, even when a “dfsrdiag backlog…” command run from a Dos prompt shows there are more than 10 files in the backlog.

    Am I causing a problem by scheduling a .bat file which calls the .ps1 file? Is there a better way to schedule this process? I hear everyone say how well it is working and I think so to except I can’t get the script to show backlogs accurately.

    Thank you,

  41. Sharon
    August 28th, 2009 at 11:59 | #41

    Mark,
    I figured out the above problem. I had the same problem Danny reported and needed to put the single quotes around the eplication roup name (spaces).
    Thanks Danny for that tip!!

    Sharon

  42. August 28th, 2009 at 19:01 | #42

    Glad that fixed it for you. That also reminds me that I need to go update it with Danny’s fix!
    – Mark

  43. Kevin
    September 14th, 2009 at 02:07 | #43

    I try to add on below to ps script, but somehow I only can get email from Error, but not from information or warning. any clue

    ## This is to create an email content
    $Mail = New-Object System.Net.Mail.MailMessage($Sender,$Recipient)

    if ($SuccessAudit -ne $NULL)
    {
    $MailTxt = “Information ”
    $Mail.Subject = $MailTxt + “: DFS-R Report on ” + (Get-Date)
    $Mail.Body = $MailTxt + $SuccessAudit
    }

    if ($WarningAudit -ne $NULL)
    {
    $MailTxt = “Warning ”
    $Mail.Subject = $MailTxt + “: DFS-R Report on ” + (Get-Date)
    $Mail.Body = $MailTxt + $WarningAudit
    }

    if ($ErrorAudit -ne $NULL)
    {
    $MailTxt = “Error ”
    $Mail.Subject = $MailTxt + “: DFS-R Report on ” + (Get-Date)
    $Mail.Body = $MailTxt + $ErrorAudit
    }

    $Mail.IsBodyHTML = $True

    ## Sent the event via smtp server
    $MailClient = New-Object System.Net.Mail.SmtpClient
    $MailClient.Host = $Mailserver
    $MailClient.Send($Mail)

  44. September 14th, 2009 at 09:18 | #44

    Kevin,
    So, you are only receiving the $ErrorAudit information in the email even when you have success events?
    Did you want to have a separate email for each condition (Information, Warning, and Error) or did you want to have a single Email containing all of them?

    Under each condition you are overwriting the $Mail.Body text, so when you go to SEND your email, the text that $Mail.body contains would be whichever condition was last met. Under Each condition you will need to SEND the message.

    If your plan is to send separate emails per condition, then I would modify the code as such:

    ## This is to create an email content
    $Mail = New-Object System.Net.Mail.MailMessage($Sender,$Recipient)
    $Mail.IsBodyHTML = $True

    ## Setup SMTP Mail Server info
    $MailClient = New-Object System.Net.Mail.SmtpClient
    $MailClient.Host = $Mailserver

    if ($SuccessAudit -ne $NULL)
    {
    $MailTxt = “Information ”
    $Mail.Subject = $MailTxt + “: DFS-R Report on ” + (Get-Date)
    $Mail.Body = $MailTxt + $SuccessAudit

    # Send the message
    $MailClient.Send($Mail)
    }

    if ($WarningAudit -ne $NULL)
    {
    $MailTxt = “Warning ”
    $Mail.Subject = $MailTxt + “: DFS-R Report on ” + (Get-Date)
    $Mail.Body = $MailTxt + $WarningAudit

    # Send the message
    $MailClient.Send($Mail)
    }

    if ($ErrorAudit -ne $NULL)
    {
    $MailTxt = “Error ”
    $Mail.Subject = $MailTxt + “: DFS-R Report on ” + (Get-Date)
    $Mail.Body = $MailTxt + $ErrorAudit

    # Send the message
    $MailClient.Send($Mail)
    }

    Since I don’t have a means to test this currently, please try it out and let me know if this gives you what you are looking to do.

    Thanks,
    – Mark

  45. Kevin
    September 18th, 2009 at 03:29 | #45

    ya the script work, it now sent 3 inidividual mail.
    but one issue is the content are all in single line, posible to split out each compare per line?

    current the result as below:-
    Warning domain.com\shared\deploy:deploy has 2 files in the backlog from MYAFS01 to MYFS03. domain.com\shared\data:data has 1 files in the backlog from DRFS01 to MYFS03. domain.com\shared\data:data has 1 files in the backlog from LONFS02 to MYFS03. domain.com\shared\data:data has 1 files in the backlog from SHAFS01 to MYFS03. domain.com\shared\data:data has 1 files in the backlog from NYFS01 to MYFS03.

  46. September 18th, 2009 at 09:36 | #46

    Interesting. I wonder if the mail provider is stripping the “Newline” character as the end of each line?
    You could try replacing “`n” with “`n`r” to force it to use both NewLine and Carriage Return.
    The other thing to try would be to (at the beginning of the script)
    $OFS = “`n`r”

    This sets the default “Output Field Separator” to be NewLine/Carriage Return (instead of a Space).
    Let me know how this works..

    — Mark

  47. Arvid Carlander
    October 4th, 2009 at 12:33 | #47

    Mark,

    Thanks for posting such a useful script.

    I found a way of listing backlogged files directly through WMI rather than by using the command line and I thought you might be interested:

    # Get count and list of backlogged files
    $source=”replace with the name of the sending server”
    $target=”replace with the name of the receiving server”
    $foldername=”replace with the name of the replication folder”
    $sleep=60
    $sourcefolder=get-wmiobject -namespace “root\microsoftdfs” -class “dfsrreplicatedfolderinfo” -computer $source| where {$_.replicatedfoldername -eq $foldername}
    $targetfolder=get-wmiobject -namespace “root\microsoftdfs” -class “dfsrreplicatedfolderinfo” -computer $target| where {$_.replicatedfoldername -eq $foldername}
    $vector=$targetfolder.getversionvector()
    $count=$sourcefolder.getoutboundbacklogfilecount($vector.versionvector)
    $backlog=$sourcefolder.getoutboundbacklogfileidrecords($vector.versionvector)
    function f {
    while ($true) {
    $vector=$targetfolder.getversionvector()
    $backlog=$sourcefolder.getoutboundbacklogfileidrecords($vector.versionvector)
    $count=$sourcefolder.getoutboundbacklogfilecount($vector.versionvector)
    $s=get-date
    $s=$s.tostring() + ” ” + [string]($backlog.backlogidrecords|%{$_.filename}|select -first 1)
    write-host $count.backlogfilecount, ” “,$s
    sleep $sleep
    }
    }
    Source this (i.e. “. ./filename.ps1) and run “f”

    The example lists the number of outstanding files plus the name of the first one in the queue which is useful at times.

    Another thing I am working on is a generic tool to list the backlog for all known replication groups irrespective of the servers involved. The source would ideally be active directory rather than one of the dfsr servers to make sure all groups are found. Have you heard of any way of querying a list of replication groups through AD?

    Again, thanks for a very useful script.

    -Arvid

  48. October 4th, 2009 at 12:52 | #48

    Arvid,
    Thanks for the comment. I would much prefer to query all of this through WMI instead of running external commands, so thanks for that as well.. I will have to take a look at integrating your suggestions into the script.
    I originally started looking at doing it through AD, but found it much easier to do it through WMI, so I didn’t really dig much more into it.
    Thanks again!
    — Mark

  49. Serge Rollin
    October 13th, 2009 at 03:29 | #49

    @Mark A. Weaver

    Hello Mark and thanks for answering. Yes, I have a filter list but not filtering the files/folders I have in difference. I have 44 RG (11 servers-4 volumes each) in a 2-ways repl. I have pointed out a few things that could explain (and maybe help you out) :
    - Old servers, some provided with only 512 Mb RAM
    - Old NTFS structures that have been somehow corrupted (loss of ownership on certain directories, etc)
    - Bad paths > than 255 char created by users and not reachable through the GUI anymore.
    - One RG seems to have lost something, the report says “waiting for initial repl.”, though it has finished a long time ago.
    I have corrected some of those problems and things are much better (not perfect, though). I writed a “DFSR handbook” for my company and would be happy to share if you give me a place to put it. Maybe you’ll find something useful in it.
    About deleted target that will not be re-replicated, all actions on the replicated files/folders are logged in the Dfsr logs in the Debug folder. That’s maybe why, but either the info is written somewhere else permanently, either the log file will be later replaced (normal process), and the data eventually re-replicated.
    I have also scripted a control tool based upon the Dircmp program (Mr. Noël Danjou, author of the prog, is improving it for this purpose, thanks to him). Maybe this can help somebody. Please write to me at my mail address if you can and if I may help you.

    Have a great day and thanx again,
    SR

  50. Serge Rollin
    October 13th, 2009 at 06:31 | #50

    Hello again,
    as one of my RG didn’t replicate anymore, I launched the command dfsradmin membership /IsPrimary:true and it began to empty my source and target directories. This darn thing is very dangerous ! I have lost more than 50 Gb of user data, in the middle of the day ! Imagine my situation…
    SR

Comment pages
1 2 126
  1. No trackbacks yet.