DAG Replication Network

Setting up DAG replication is extremely important as outlined in Tim McMichael’s TechNet post, Exchange 2010: Collapsing DAG Networks.  Even when you correctly disable the MAPI network from log shipping, Exchange 2010 will still resort to log shipping on the MAPI network if there is a communication problem on the replication network.  Once you become aware that there has been a communications problem between DAG nodes on the DAG replication network, the next thing you should do is to check a few things out.



The script below should run as a scheduled task.  If any of the mailbox databases are replicating on the wrong network, you’ll get a simple email report.  The script is only looking at databases with a status of “Mounted” or “Healthy”.  I’ve found this script necessary when using SCOM as a monitoring solution since SCOM does not make a determination on which network should be used for log shipping replication.

The script executes the following:

  1. Defines variable and collects targeted DAG databases.
  2. Defines a datatable for reporting and an array for logic testing.
  3. Checks the replication properties.
  4. Builds datatable with replication information.
  5. If necessary, builds and sends an HTML email.

[powershell]
# Define the MAPI network name.
$ReplNet = "MAPINetwork"
# Collect all databases and pipe into database copy status with the connectionstatus switch.
$AllDBs = Get-MailboxDatabase
| where {$_.mastertype -eq "DatabaseAvailabilityGroup" -and $_.recovery -ne "true"}

| Get-MailboxDatabaseCopyStatus -ConnectionStatus

# Create the master data table to hold all the collected mailbox data.
$ReplData = New-Object System.Data.DataTable “ReplData”
# Create columns in the data table by specifying their name and attribute type.
$ReplData.Columns.Add("Name",[String]) | Out-Null
$ReplData.Columns.Add("Status",[String]) | Out-Null
$ReplData.Columns.Add("IncomingLogCopyingNetwork",[String]) | Out-Null
$ReplData.Columns.Add("OutgoingConnections0",[String]) | Out-Null
$ReplData.Columns.Add("OutgoingConnections1",[String]) | Out-Null
# Create an empty hashtable
$DBCheck = @()
# Take each database and look at the relevant log shipping
# network being used.
ForEach ($DB in $AllDBs){
# If MailboxDatabaseCopyStatus is Healthy and the log shipping
# network matches the public network, write a line into the
# array. Otherwise do nothing and move on.
if ($DB.Status -eq "Healthy" -and $DB.IncomingLogCopyingNetwork -match $ReplNet){
$DBCheck += $DB
}Else{
}
# If MailboxDatabaseCopyStatus is Mounted and the log shipping
# network matches the public network, write a line into the
# array. OutgoingConnections is itself an array and the code
# must index into each outgoing connections. Adjust if you have
# more than two database copies. If no match then do nothing.
if ($DB.Status -eq "Mounted" -and $DB.OutgoingConnections[0].Status -match $ReplNet){
$DBCheck += $DB
}elseif($DB.Status -eq "Mounted" -and $DB.OutgoingConnections[1].Status -match $ReplNet){
$DBCheck += $DB
}else{
}
}
# Rewrite the DBcheck variable with selected data for reporting.
$DBCheck = $DBCheck | select name,status,incominglogcopyingnetwork,outgoingconnections
# Loop through the lines in DBCheck using if else to customize the
# datatable based on database replication.
foreach($DBnoted in $DBCheck){
if($DBnoted.OutgoingConnections -eq $null){
$NewTBRow = $ReplData.NewRow()
$NewTBRow.Name = $DBnoted.Name
$NewTBRow.Status = $DBnoted.Status
$NewTBRow.IncomingLogCopyingNetwork = $DBnoted.IncomingLogCopyingNetwork
$NewTBRow.OutgoingConnections0 = $null
$NewTBRow.OutgoingConnections1 = $null
$ReplData.Rows.Add($NewTBRow)
}Else{
$NewTBRow = $ReplData.NewRow()
$NewTBRow.Name = $DBnoted.Name
$NewTBRow.Status = $DBnoted.Status
$NewTBRow.IncomingLogCopyingNetwork = $DBnoted.IncomingLogCopyingNetwork
$NewTBRow.OutgoingConnections0 = $DBnoted.OutgoingConnections[0]
$NewTBRow.OutgoingConnections1 = $DBnoted.OutgoingConnections[1]
$ReplData.Rows.Add($NewTBRow)
}
}
# If everything is replicating as expected, then DBcheck will be
# null, do nothing. Else build HTML table with data.
if($null -eq $DBCheck){
}else{
$EmailSubject = "Replication Alert: Databases are replicating on the wrong network"
#Prep the body of the email message with table styles to control the formatting of any tables presented in it.
$EmailBody = "rn" $EmailBody += "rn"
$EmailBody += "</pre>
<style><!–
rn"
$EmailBody += "TABLE{border-width: 1px;border-style: outset;border-color: black;border-spacing: 1px;border-collapse: separate;}rn"
$EmailBody += "TH{border-width: 1px;padding: 1px;border-style: inset;border-color: black;}rn"
$EmailBody += "TD{border-width: 1px;padding-left: 3px;padding-right: 3px;border-style: inset;border-color: black;}rn"
$EmailBody += "TABLE.First{border-style: none;}rn"
$EmailBody += "TD.First{border-style: none;}rn"
$EmailBody += "
–></style>
<pre>
rn"
$EmailBody += "rn" $EmailBody += "rn"
$EmailBody += $ReplData | convertto-html -Fragment @{Label="Name";Expression={$_.Name}},
@{Label="Status"; Expression = {$_.Status}},@{Label="IncomingLogCopyingNetwork"; Expression={$_.IncomingLogCopyingNetwork}},

@{Label="OutgoingConnections0";Expression={$_.OutgoingConnections0}},@{Label="OutgoingConnections1";Expression={$_.OutgoingConnections1}}
$EmailBody += "
"
$EmailBody += "</pre>

<hr />

<pre>
"
$EmailBody += "Please do not reply to this email address as it is not monitored."
#Close out the HTML content in the body of the email message.
$EmailBody += "rn" $EmailBody += "rn"
# Send email alert
Send-MailMessage -to YourEmailAddress -from SomeAddress -subject $EmailSubject -BodyAsHtml $EmailBody -smtpserver "SomeRelay"
}
[/powershell]

Leave a Reply