Exchange 2013 Reseeding Automation

Reseeding is a process of updating the failed mailbox database to be in sync with the Active mailbox database. This has been greatly improved in Exchange 2013. Some of the new and interesting features in Exchange 2013 is Automatic Reseed and multiple databases per volume.

AutoReseed is purposed to overcome the manual efforts of replacing the failed disk with a new disk and restoring the copy of the database on the spare disk ASAP when the disk failure occurs. It involves pre-configuration of the disk and databases using mount point. Auto reseeding has a built in algorithm to perform some basic check before the spare disk is configured. Algorithm uses MS Exchange Replication service to check for the FailedAndSuspended database. Once it finds the FailedAndSuspended DB, it performs some checks, like the number of copies available, disk space, etc. If the checks are successful, then it automatically maps the spare disk and reseeding is performed.

Multiple Databases per volume is the new design improvement when just a bunch of disks (JBOD) configurations is used for the mailbox database. This design allows hosting multiple databases on the same volume.As these days the size of the disks can be increased up to 8 TB, whereas the Exchange best practice guideline only mentions 2 TB, there could be a waste of additional 6 TB. To overcome this issue, Exchange 2013 allows multiple copies per disk. Figure 1 below illustrates the symmetrical design of a database. All four servers have the same four databases all hosted on a single disk per server. The key is that the number of copies of each database should be equal to the number of database copies per disk.

Figure 1. Exchange 2013 multiple databases per volume

When disk failure occurs and disk is reconfigured, then auto reseeding would be kicked from multiple source. This symmetrical design also increases the speed of reseeding from multiple source then the transitional reseeding method of single source. Figure 2 below shows the details of the reseeding from multiple source with the reseeding speed of 2 TB of data in approximately 9.7 hrs.

Figure 2. Improved reseeding using multiple databases per volume

Auto Reseeding and Multiple Databases per volume have greatly improved the seeding of failed database in Exchange 2013. If we do not have the configuration of spare disk and multiple database per volume and there is a database or server failure, then we have to perform the reseeding operation manually. Manual reseeding operations are tedious, cumbersome and require to be performed one by one. To overcome the manual reseeding problem, I have worked on the below script to automate the reseeding in multithread fashion.

function Createfolders()

{

remove-item -path “C:\DBs\bt” -force  -Recurse -confirm:$false -ErrorAction SilentlyContinue | out-null

remove-item -path “C:\DBs\ps” -force  -Recurse -confirm:$false -ErrorAction SilentlyContinue| out-null

remove-item -path “C:\DBs” -force  -Recurse -confirm:$false -ErrorAction SilentlyContinue| out-null

new-item -path “C:\DBs” -ItemType Directory -force | out-null

new-item -path “C:\DBs\bt” -ItemType Directory -force | out-null

new-item -path “C:\DBs\ps” -ItemType Directory -force | out-null

}

$strResponse = Read-Host  “`nPlease enter DAG Name to reseed the failed Databases”

write-host -f Magenta “Checking for Failed Database copies in the DAG : $strResponse”

$databases = Get-MailboxDatabaseCopyStatus $strResponse  |?{$_.status -like “Failed*”}

if($databases -ne $null)

{

write-host -f red “Following Databases are in failed state”

$databases

Write-host “`n”

foreach($database in $databases)

{

$filename = $database.name

$dbname = $database.name

$filename = $filename.Replace(“\”, “_”)

$DBcopyReport1 = “C:\DBs\bt\$filename.bat”

$DBcopyReport2 = “C:\DBs\ps\$filename.ps1”

New-item -ItemType file -path $DBcopyReport1 -force | out-null

New-item -ItemType file -path $DBcopyReport2 -force | out-null

“Powershell.exe `”C:\DBs\bt\$filename.ps1`”” |  Out-File -filepath $DBcopyReport1 -encoding ASCII -append

“Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue”| Out-file $DBcopyReport2 -encoding ASCII -append

“Suspend-MailboxDatabaseCopy -Identity `”$dbname`” -confirm:” + “$” + “false”| Out-file $DBcopyReport2 -encoding ASCII -append

“Update-MailboxDatabaseCopy -Identity `”$dbname`”  -DeleteExistingFiles -confirm:” + “$” + “false -ErrorAction:Stop -WarningAction:SilentlyContinue” | Out-file $DBcopyReport2 -encoding ASCII -append

$files = [IO.Directory]::GetFiles(“C:\DBs\bt\”)

$cmdprocess = @()

Write-host -f yellow “`nReseeding the following databases”

for ($i=0; $i -lt $files.count; $i++)

{

$DBDName = $files[$i]

$DBDName =$DBDName.split(“\”)[3]

$DBDName =$DBDName.split(“.”)[0]

$DBDName = $DBDName.Replace(“_”,”\”)

Write-host -f yellow “$DBDName”

$cmdprocess =$cmdprocess+ [diagnostics.process]::Start($files[$i])

do

{

$cmdp = @()

$continue = 0

foreach($cmdproces in $cmdprocess)

{

$cmdp = $cmdp + $cmdproces.id

}

$processid = Get-Process | %{$_.id}

foreach($cmd in $cmdp)

{

if($processid -contains $cmd)

{

$continue = $continue + 1

}

}

start-sleep(10)

}until($continue -lt 10)

}

do

{

$processid = Get-Process | %{$_.id}

$Loopexit = 0

foreach($cmd in $cmdp)

{

if($processid -contains $cmd)

{

$Loopexit = 1

start-sleep(10)

}

}

}until($Loopexit -eq 0)

Write-host -f Green “`nReseeding of Failed DB’s has been completed”

}

Else

{

Write-host -f Green “All the mailbox Database copy are in Healthy state”

}

Createfolders

Write-host -f Magenta “`nChecking for failed Catalog or Content Index in the DAG :$strResponse”

$databases = Get-MailboxDatabaseCopyStatus $strResponse  |?{$_.ContentIndexState -match “Fail” }

if($databases -ne $null)

{

write-host -f red “Following Databases are in failed state”

$databases

Write-host “`n”

foreach($database in $databases)

{

$filename = $database.name

$dbname = $database.name

$filename = $filename.Replace(“\”, “_”)

$DBcopyReport1 = “C:\DBs\bt\$filename.bat”

$DBcopyReport2 = “C:\DBs\ps\$filename.ps1”

New-item -ItemType file -path $DBcopyReport1 -force | out-null

New-item -ItemType file -path $DBcopyReport2 -force | out-null

“Powershell.exe `”C:\DBs\bt\$filename.ps1`”” |  Out-File -filepath $DBcopyReport1 -encoding ASCII -append

“Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue”| Out-file $DBcopyReport2 -encoding ASCII -append

“Suspend-MailboxDatabaseCopy -Identity `”$dbname`” -confirm:” + “$” + “false”| Out-file $DBcopyReport2 -encoding ASCII -append

“Update-MailboxDatabaseCopy -Identity `”$dbname`”  -DeleteExistingFiles -confirm:” + “$” + “false -ErrorAction:Stop -WarningAction:SilentlyContinue” | Out-file $DBcopyReport2 -encoding ASCII -append

$files = [IO.Directory]::GetFiles(“C:\DBs\bt\”)

$cmdprocess = @()

Write-host -f yellow “`nReseeding the following databases”

for ($i=0; $i -lt $files.count; $i++)

{

$DBDName = $files[$i]

$DBDName =$DBDName.split(“\”)[3]

$DBDName =$DBDName.split(“.”)[0]

$DBDName = $DBDName.Replace(“_”,”\”)

Write-host -f yellow “$DBDName”

$cmdprocess =$cmdprocess+ [diagnostics.process]::Start($files[$i])

do

{

$cmdp = @()

$continue = 0

foreach($cmdproces in $cmdprocess)

{

$cmdp = $cmdp + $cmdproces.id

}

$processid = Get-Process | %{$_.id}

foreach($cmd in $cmdp)

{

if($processid -contains $cmd)

{

$continue = $continue + 1

}

}

start-sleep(10)

}until($continue -lt 10)

}

do

{

$processid = Get-Process | %{$_.id}

$Loopexit = 0

foreach($cmd in $cmdp)

{

if($processid -contains $cmd)

{

$Loopexit = 1

start-sleep(10)

}

}

}until($Loopexit -eq 0)

Write-host -f Green “`nReseeding of Failed DB’s has been completed”

}

Else

{

Write-host -f Green “All the mailbox Database copy Index are in Healthy state”

}

We hope, you find this helpful. In case you want to share your opinion, feel free to use the comments section below!