DFSR monitoring script in PowerShell (Weekly e-mail report)

DFS-R is really great technology, but in production environment it’s critical to monitor health of your DFS infrastructure. You need to monitor free space and backlog files (objects in queue waiting for replication). If you have licensed Microsoft System Center Suite, Operation Manager (SCOM) is maybe the best monitoring tool for DFS, but don’t forget to enable backlog monitoring. If you don’t have monitoring software capable of monitoring DFSR, it’s good to have at least some simple script that will send you some scheduled reports. When looking for one script I found this one >> http://chris-nullpayload.rhcloud.com/2014/08/powershell-script-to-monitor-dfs-replication/, but this script has two problems, it didn’t work correctly when there is an error with replication and this older version is not capable to send e-mail report (Later I found that the author did make a newer version, but in that time I have tested my modified version).

I have modified this script, for weekly e-mail reports, and tried to fix the script in case DFSR replication is in error state. Added disk drive usage and you can use this script to save .TXT report to c:\DFSReports folder.

Understanding DFSR Backlog -> If you create, update, delete some file or folder it’s processed in staging folder and replicated to all partners. In case you have 5 replication partners a modify one file, the backlog count should be 5 and after successful replication with partner decrease by one after some time finish with 0 updates in backlog. Higher number files in Backlog may indicate problem with replication and needs to be investigated.

This is how email report is seen in e-mail client:

dfsr-email-report-2Email report when you have big replication problems 😉

Modified PowerShell script (DFSR.report.ps1):

#_Source http://chris-nullpayload.rhcloud.com/2014/08/powershell-script-to-monitor-dfs-replication/
#_Tested on WS2012R2, powershell 4.0
#_https://technet.microsoft.com/en-us/library/dn296583.aspx
#_MF 6/2016 v1.03
#Line breaks are removed in posts made in plain text format in Outlook https://support.microsoft.com/en-us/kb/287816 !!!
#to do Threshols variables
$RGroups = Get-WmiObject -Namespace "root\MicrosoftDFS" -Query "SELECT * FROM DfsrReplicationGroupConfig"
$ComputerName=$env:ComputerName
$Succ=0
$Warn=0
$Err=0
$ErrInfo=0
$ErrText=''
$EmailHint = ''
#Backlog files count warning
$EmailNotification = 0 #enable (1) or disable (0) e-mail notification
$ExportReporttoFile = 1 #enable (1) or disable (0) saving report to file
$ExportReporFolder = 'C:\DFSReports' #Export Path
$Last7days = (Get-Date).AddDays(-7) #last week date, for eventlog weekly reports</code>

$EmailText ="---------------------------------------------------------------------------------------------`r`nWeekly DFSR report $(get-date -format 'dd-MMMM-yyyy HH:mm')"
$EmailText +="`r`n---------------------------------------------------------------------------------------------`r`n"

Write-Host $EmailText

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)
{
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

#Hint Command example at the end of Email message
$EmailHint += "`r`ndfsrdiag Backlog /RGName:$RGName /RFName:$RFName /SendingMember:$SendingMember /ReceivingMember:$ReceivingMember"

$BackLogFilecount = 0
foreach ($item in $Backlog)
{

if (($item -ilike "[ERROR]*") -and ($item -inotlike "*Operation Succeeded*") )
{
$BacklogFileCount = "[ERROR]"
$Color="red"
$ErrInfo=1
$ErrText+= "$item `r`n"
$Err++
}
elseif ($item -ilike "*No Backlog*")
{
$BacklogFileCount = 0
$Color="white"
$Succ++
}
elseif ($item -ilike "*Backlog File count*")
{
$BacklogFileCount = [int]$Item.Split(":")[1].Trim()
if ($BacklogFileCount -lt 5)
{
$Color="white"
$Succ++
}
elseif ($BacklogFilecount -le 100)
{
$Color="yellow"
$Warn++
}
elseif ($BacklogFilecount -gt 100)
{
$Color="red"
$Err++
}
}
}

Write-Host "$BacklogFileCount updates in backlog $SendingMember-&gt;$ReceivingMember for $RGName" -ForegroundColor $Color
$EmailText += "$BacklogFileCount updates in backlog $SendingMember-&gt;$ReceivingMember for $RGName"
$EmailText += "`r`n"

} # Closing iterate through all folders
#} # Closing If replies to ping
} # Closing If Connection enabled
} # Closing iteration through all connections
} # Closing iteration through all groups

$ReplicationState = Invoke-Expression "dfsrdiag replicationstate -v"

Write-Host "$Succ successful, $Warn warnings and $Err errors from $($Succ+$Warn+$Err) replications.`n"
Write-Host "Updates can be new, modified, or deleted files and folders. Any files or folders listed`nin the DFS Replication backlog have not yet replicated from the source computer"
Write-Host "to the destination computer. This is not necessarily an indication of problems.`nA backlog indicates latency, and a backlog may be expected in your environment,`ndepending on configuration, rate of change, network, and other factors.`n`n"

$EmailText += "$Succ successful, $Warn warnings and $Err errors from $($Succ+$Warn+$Err) replications.`r`n`r`n"
$EmailText += "Updates can be new, modified, or deleted files and folders. Any files or folders`r`nlisted in the DFS Replication backlog have not yet replicated from the source`r`n"
$EmailText += "computer to the destination computer. This is not necessarily an indication of`nproblems.`r`nA backlog indicates latency, and a backlog may be expected in your environment,`r`ndepending on configuration, rate of change, network, and other factors.`r`n`r`n"

Write-Host "File System Free Space on $ComputerName ($(get-date)) `n---------------------------------------------------------------------------------------------"
$EmailText += "File System Free Space on $ComputerName ($(get-date)) `r`n---------------------------------------------------------------------------------------------"
$FreeSpace = psdrive -PSProvider FileSystem |Select-Object root, @{Name="Free (GB)";Expression={"{0:N1}" -f ($_.free / 1gb)}}, @{Name="Used (GB)";Expression={"{0:N1}" -f ($_.used / 1gb)}}, description | ft -AutoSize
$EmailText += $FreeSpace | Out-String
$FreeSpace | Out-String

if ($ErrInfo -eq "1" ) {
Write-Host "DFSR Backlog Errors ($(get-date)) `n---------------------------------------------------------------------------------------------`n"
Write-Host "$ErrText`n"
$EmailText +="DFSR Backlog Errors ($(get-date)) `r`n---------------------------------------------------------------------------------------------`r`n"
$EmailText += "$ErrText`r`n"
}

Write-Host "DFSR replication State ($(get-date)) `n---------------------------------------------------------------------------------------------`n"
$EmailText +="DFSR replication State ($(get-date)) `r`n---------------------------------------------------------------------------------------------`r`n"

$ReplicationState = invoke-expression "dfsrdiag replicationstate -v"
$ReplicationState

$EmailText += $ReplicationState | Out-String

Write-Host "Latest DFSR events (Error, Warning) from $Last7days to $(get-date) `n---------------------------------------------------------------------------------------------`n"
$EmailText += "Latest DFSR events (Error, Warning) from $Last7days to $(get-date) `r`n---------------------------------------------------------------------------------------------`r`n"

$DFSRError = (Get-EventLog -LogName "DFS Replication" -Newest 5 -EntryType Error -After $Last7days | fl timegenerated, entrytype, message | Out-String )
$DFSRError
$DFSRWarrning = (Get-EventLog -LogName "DFS Replication" -Newest 3 -EntryType warning -After $Last7days| fl timegenerated, entrytype, message | Out-String )
$DFSRWarrning

$EmailText += $DFSRError
$EmailText += $DFSRWarrning

$EmailText +="[Hint] You can allways check current DFS-R status with this commands:`r`n---------------------------------------------------------------------------------------"
$EmailText +="`r`ndfsrdiag replicationstate"
$EmailText += $EmailHint

#Send report to e-mail
If ($EmailNotification -eq '1') {

$EmailSubject = "Weekly DFSR report $(get-date -format 'dd-MMMM-yyyy') - ($Err Errors, $Warn Warrnings)"
$EmailRecipients = #"email@contoso.com","email2@contoso.com"
$EmailFrom = "server01@example.com"
$EmailSMTPServer = 'mail.example.com'
$EmailEncoding = [System.Text.Encoding]::UTF7 #UTF7,UTF8,ASCII

Send-MailMessage -To $EmailRecipients -Subject $EmailSubject -From $EmailFrom -Body $EmailText -SmtpServer $EmailSMTPServer -Encoding $EmailEncoding
#Send-MailMessage [-To] &lt;String[]&gt; [-Subject] [[-Body] ] [[-SmtpServer] ] -From [-Attachments &lt;String[]&gt; ] [-Bcc &lt;String[]&gt; ] [-BodyAsHtml] [-Cc &lt;String[]&gt; ] [-Credential ] [-DeliveryNotificationOption ] [-Encoding ] [-Port ] [-Priority ] [-UseSsl] [ ]
}

#save report to file
if ( $ExportReporttoFile -eq '1' )
{
if((Test-Path $ExportReporFolder) -eq $False) #If export directory doesn't exzist, create new directory
{
New-Item -ItemType Directory -Path $ExportReporFolder
}
$ExportFilePath = "$ExportReporFolder\DFSR_report_$(get-date -f yyyy-MM-dd).txt"
Out-File -InputObject $EmailText -FilePath $ExportFilePath -Encoding unicode
}

Download PowerShell Script >> dfsr-report-ps1
Tested with Windows Server 2012R2 + PowerShell 4.0, but it should work on older Windows Server, but it’s not tested ( in WS 2012 Microsoft changed WMI namespace for DFSR so this script need more testing) !!!

If you use MS Outlook it’s good to make this changes, because Outlook mess with line breaks >> https://support.microsoft.com/en-us/kb/287816

 

outlook-fix
Really helpful setting for plain text reports MS Outlook.