Showing posts with label DAG. Show all posts
Showing posts with label DAG. Show all posts

Saturday, March 11, 2017

Exchange DAG Replication Port

Have you ever wondered what TCP port Exchange 2010/2013/2016 uses for database replication (log shipping and seeding)? That would be 64327 by default.

This can be checked using the Get-DatabaseAvailabilityGroup cmdlet:

Administrators can also change this default port is they so desire by using the Set-DatabaseAvailabilityGroup cmdlet with the -ReplicationPort parameter.
If you decide to do so, it is recommended to create a new Windows Firewall rule for the new port on all DAG members before the actual change to avoid any disruption to database replication. After the change, the existing firewall rule can then be deleted or updated (depending on the approach taken):

Monday, February 22, 2016

Create Shadow Copies on the same Active Directory Site

In the Transport High Availability in Exchange 2013 article we discussed, amongst other topics, Exchange’s Shadow Redundancy feature and how it generates redundant copies of e-mails before these being delivered to mailboxes and before Exchange acknowledging to the sending server successfully receiving them.

We also saw that in DAG environments, Exchange gives preference to creating a shadow copy of an email on a DAG member that is located in a different Active Directory (AD) site, if any. But what if we have a DAG that extends one or more AD sites but we want shadow copies to be created only within the same site? If we look at our Transport Config, we will see a ShadowMessagePreferenceSetting parameter (the following output has been truncated):
[PS] C:\> Get-TransportConfig | FL

MaxRetriesForLocalSiteShadow       : 2
MaxRetriesForRemoteSiteShadow      : 4
ShadowHeartbeatFrequency           : 00:02:00
ShadowMessageAutoDiscardInterval   : 2.00:00:00
ShadowMessagePreferenceSetting     : PreferRemote
ShadowRedundancyEnabled            : True
ShadowResubmitTimeSpan             : 03:00:00

The ShadowMessagePreferenceSetting parameters has three possible settings:
  • PreferRemote: Exchange tries to make a shadow copy of the message on a server in a different AD site. If the operation fails, it tries a server in the local AD site;
  • LocalOnly: a shadow copy of the message should only be made on a server in the local AD site;
  • RemoteOnly: a shadow copy of the message should only be made on a server in a different AD site.

Please have in mind that this parameter is only meaningful when the primary server that is trying to make a shadow copy of the message is a Mailbox server that is a member of a DAG that spans multiple AD sites.

As such, if we want our shadow copies to be created within the same site, all we have to do is update the parameter to LocalOnly. However, when we try to do so we might get the following error depending if the other parameters still have their default values:
[PS] C:\> Set-TransportConfig -ShadowMessagePreferenceSetting LocalOnly

The value for MaxRetriesForRemoteSiteShadow must be set to zero for the LocalOnly shadow redundancy preference setting.

So what we need to do is to also update the MaxRetriesForRemoteSiteShadow parameter:
[PS] C:\> Set-TransportConfig -ShadowMessagePreferenceSetting LocalOnly -MaxRetriesForRemoteSiteShadow 0

Wednesday, August 27, 2014

Exchange 2013 Loose Truncation

Loose Truncation is a new feature that was introduced in Exchange 2013 Service Pack 1. Its purpose is to prevent possible disk space issues that can occur in environments with DAGs when one or more copies of a database is offline for an extended period of time. When enabled, loose truncation changes the “normal” truncation behavior. Each database copy tracks its own free disk space and starts to truncate transaction log files independently if the available disk space falls behind a set threshold configurable by the administrator.

To continue reading, please check the full Exchange 2013 Loose Truncation article at MSExchange.org.

Thursday, July 10, 2014

Database Availability Group Failover during a Mailbox Move

During a mailbox move operation if the active database becomes unavailable then the Mailbox Replication Service [MRS] contacts the active manager to see which copy will take over. MRS then logs on to the mailbox on the new database and continues with the move process from where it left off. This as long as the DataMoveReplicationConstraint setting for the database is set to something else other than None and as long as the database was not down for longer than 30 minutes (or there is another copy satisfying the constraint).
 
Let us assume the database has 3 copies. It is entirely possible that MRS will just continue working after a failover even if the original server is down.
 
If DataMoveReplicationConstraint is set to None then MRS will try to connect to the same database every 30 seconds for the next 30 minutes. The 30 minute is from the maximum retry of 60 times every 30 seconds. This value can be changed in the in the msExchMailboxReplication.exe.config file.
 
The DataMoveReplicationConstraint parameter specifies the throttling behavior for high availability mailbox moves. The possible values are:
  • None: moves should not be throttled to ensure high availability. Use this setting if the database is not part of a DAG;
  • SecondCopy (default): at least one passive mailbox database copy must have the most recent changes synchronized. Use this setting to indicate that the database is replicated to one or more mailbox database copies;
  • SecondDatacenter: at least one passive mailbox database copy in another AD site must have the most recent changes replicated. Use this setting to indicate that the database is replicated to database copies in multiple AD sites;
  • AllDatacenters: at least one passive mailbox database copy in each AD site must have the most recent changes replicated. Use this setting to indicate that the database is replicated to database copies in multiple AD sites;
  • AllCopies: all copies of the database must have the most recent changes replicated. Use this setting to indicate that the database is replicated to one or more mailbox database copies.
 Note: any value other than None enables MRS to coordinate with Active Manager.

Monday, November 4, 2013

Exchange 2013 DAG with Dynamic Quorum

Windows Server 2012 introduced a new quorum model called Failover Clustering Dynamic Quorum, which we can use with Exchange. When using Dynamic Quorum, the cluster dynamically manages the vote assignment to nodes based on the state of each node. When a node shuts down or crashes, it loses its quorum vote. When a node successfully re-joins the cluster, it regains its quorum vote. By dynamically adjusting the assignment of quorum votes, the cluster can increase or decrease the number of quorum votes that are required to keep it running. This enables the cluster to maintain availability during sequential node failures or shutdowns.
 
With a dynamic quorum, the cluster quorum majority is determined by the set of nodes that are active members of the cluster at any time. This is an important distinction from the cluster quorum in Windows Server 2008 R2 where the quorum majority is fixed, based on the initial cluster configuration.
 
The advantage this brings, is that it is now possible for a cluster to run even if the number of nodes remaining in the cluster is less than 50%! By dynamically adjusting the quorum majority requirement, the cluster can sustain sequential node shutdowns down to a single node and still keep running. It does not allow the cluster to sustain a simultaneous failure of a majority of voting members though. To continue running, the cluster must always have a quorum majority at the time of a node shutdown or failure.
 
 
The following picture shows a DAG still operational even though two out of three servers are offline:
 
 
To read more about this feature, including tests with an Exchange 2013 DAG, please check my Exchange 2013 DAGwith Dynamic Quorum article on MSExchange.org.

Thursday, June 13, 2013

Update-MailboxDatabaseCopy in Exchange 2013 CU1

The Update-MailboxDatabaseCopy cmdlet is used to seed or reseed a mailbox database copy. Seeding is the process in which a copy of a mailbox database is added to another Mailbox server, thus becoming the database copy into which copied log files and data are replayed. This cmdlet can also be used to seed a content index catalog for a mailbox database copy.

In Exchange 2013 CU1 this cmdlet includes some new parameters that are designed to aid with automation of seeding operations. These parameters include:
  • BeginSeed – this is useful for scripting reseeds. With this parameter, the task asynchronously starts the seeding operation and then exits the cmdlet;
  • MaximumSeedsInParallel – this is used with the Server parameter to specify the maximum number of parallel seeding operations that should occur across the specified server during a full server reseed operation. The default value is 10;
  • SafeDeleteExistingFiles – this is used to perform a seeding operation with a single copy redundancy pre-check prior to the seed. Because this parameter includes the redundancy safety check, it requires a lower level of permissions than the DeleteExistingFiles parameter, enabling a limited permission administrator to perform the seeding operation;
  • Server – this is used as part of a full server reseed operation to reseed all database copies in a Failed and Suspended state. It can be used with the MaximumSeedsInParallel parameter to start reseeds of database copies in parallel across the specified server in batches of up to the value of the MaximumSeedsInParallel parameter copies at a time.

Remember that you must suspend a database copy before you can update it using the Update-MailboxDatabaseCopy cmdlet.

Monday, February 11, 2013

Moving the Primary Active Manager

If, for some reason, the server currently hosting the Active Manager role of Primary Active Manager [PAM] fails, this role should automatically move to a surviving server of the Database Availability Group [DAG] which then takes ownership of the cluster quorum resource.

However, you might face a (rare) scenario where this doesn’t happen and you end up with a failed server and with Exchange still thinking that server is the PAM. Among other things, you will not be able to add/remove members to/from the DAG...

PAM decides which database copies will be active and passive, is responsible for getting topology change notifications and reacting to server failures. The DAG member that holds the PAM role is always the member that currently owns the cluster quorum resource (default cluster group).

So how do we move the PAM to one of the surviving servers? To achieve this, we need to use the command line and use the following Windows Clustering command to move the cluster quorum resource:
cluster.exe “DAG Name” /MoveTo:NewDAG
where “DAG Name” is your DAG Cluster Name and NewDAG is the node where you want to move the PAM to.

Sunday, February 3, 2013

Exchange 2013 Automatic Reseed

Microsoft has made great improvements in Exchange 2013, some of these around Database Availability Groups [DAGs]. For example, it is now possible to reseed a database from multiple sources, greatly reducing the overall time this operation usually takes. Another improvement, in this case a new feature, is called Automatic Reseed, or simply AutoReseed.

With Exchange 2010, if you lose the disk where your database is (either active or passive), Exchange will failover that database to another server (assuming it is part of a DAG with multiple copies). After that, an administrator will typically replace the faulted disk and reseed the database back to that server. This, of course, in scenarios where resilience through RAID or enterprise-level storage is not provided, which would cater for disk failures.

The purpose of AutoReseed is to overcome this situation and automatically restore database redundancy by using spare disks provisioned specifically for this. All it involves is pre-mapping volumes and databases using mount points that will be used for the databases and the reseed operation. In a simplistic way:
  1. Mount all volumes (used for databases and as spares) under a single mount point, C:\ExchangeVolumes for example;
  2. Mount the root directory of mailbox databases as another mount point under C:\ExchangeDatabases for example. Next, create two directories for each database: one for the database itself and another for the log files;
  3. Finally create the database(s).

 
Here is AutoReseed process flow:
  1. The Exchange Replication service periodically scans for database copies that have a status of FailedAndSuspended;
  2. If one is found, it does pre-requisite checks like checking if spare drives are available and ensuring nothing might prevent Exchange from automatic reseeding the database;
  3. If all the checks pass, the Replication service allocates and remaps a spare drive;
  4. Seeding is performed;
  5. Once seeding is complete, the Replication service checks if the seeded copy is healthy.

All an administrator needs to do now is simply replace the faulty disk and reconfigure it as a spare for the DAG!

To read all about this new feature and how to implement it, please check the article at MSExchange.org.

 

Thursday, January 17, 2013

Exchange 2013 Database Mount Limit

A change introduced in Exchange 2013 that many administrators are not aware is the fact that with the Enterprise Edition of Exchange, you can now only mount up to 50 mailbox databases per server, a reduction in 50% from the 100 with Exchange 2010! The limit of the Standard Edition remains at 5 databases.

Highly available and resilient environments might have some problems when migrating from Exchange 2010 if they have servers with more than 50 databases (in big environments with 3 or 4 copies of each database it is not that uncommon). Therefore, a complete review of the current database layout might have to happen.

But why this change?! Basically it was introduced in order to ensure a good performance from the mailbox servers. Some of the reasons behind this change are the improvements made in some areas, which mean the mailbox servers consume more memory now... For example, Exchange 2013 uses Search Foundation instead of MSSearch in order to be consistent with SharePoint and to allow discovery searches across e-mail and documents. Search Foundation uses more memory and it seems it can take between 10 to 15% of available memory on a mailbox server.
Another change is the move of protocol handling from the Client Access Server [CAS] to the Mailbox server. It helps make the CAS more stateless and not so dependent on a particular mailbox server but it also increases the memory use on the mailbox server...

Note: the limit of 16 mailbox servers per DAG remains in Exchange 2013.

Monday, December 31, 2012

Check DAG Status

With Exchange 2010 and Database Availability Groups [DAGs], Microsoft greatly increases high availability and resilience in Exchange. But now, it is not only important to make sure your active mailbox databases are healthy and working fine, but it is also crucial to ensure your passive databases are healthy and ready to be mounted in case of necessity.

Microsoft System Center Operations Manager does a great job monitoring Exchange, but if you simply like to check for yourself, there are many cmdlets available. Two of the most important ones and most frequently used, in my opinion are the Get-MailboxDatabaseCopyStatus and Test-ReplicationHealth cmdlets.

Get-MailboxDatabaseCopyStatus will show status information about your databases that are part of a DAG. Using the following cmdlet, you can check all the databases in all the DAGs present in your environment:
(Get-DatabaseAvailabilityGroup) | ForEach {$_.Servers | ForEach {Get-MailboxDatabaseCopyStatus -Server $_}}

Using the Test-ReplicationHealth cmdlet will allow you to check all aspects of the replication and replay status, providing you with a complete overview of a Mailbox server in a DAG. This way, administrators can proactively monitor the continuous replication and the continuous replication pipeline, the availability of the Active Manager and the health and status of the underlying cluster service, quorum and network components.
(Get-DatabaseAvailabilityGroup) | ForEach {$_.Servers | ForEach {Test-ReplicationHealth -Server $_}}

Friday, October 26, 2012

Exchange 2013 DAG CreateCluster() Failed Error

So far I have encountered the following problem in two completely separate Exchange 2013 Preview environments when creating a Database Availability Group [DAG].

Started by creating a simple DAG without any problems, only specifying its IP address and letting Exchange decide which server to use as the Witness Server. However, whenever I tried to add any of the mailbox servers to this DAG, I would get the following error:
 
Note the "CreateCluster() failed with 0x5. Error: Access is denied" part of the error message.


If we look at the dagtask log mentioned in the error above, we will see all the tasks Exchange performs when adding a server to the DAG and where it failed:
[2012-10-26T18:23:18] ClusterSetupProgressCallback( eSetupPhase = ClusterSetupPhaseConfigureClusterAccount, ePhaseType = ClusterSetupPhaseStart, ePhaseSeverity = ClusterSetupPhaseInformational, dwPercentComplete = 94, szObjectName = DAG1 in organizational unit CN=Computers,DC=letsexchange,DC=com, dwStatus = 0x0 )

[2012-10-26T18:23:18] ClusterSetupProgressCallback( eSetupPhase = ClusterSetupPhaseConfigureClusterAccount, ePhaseType = ClusterSetupPhaseEnd, ePhaseSeverity = ClusterSetupPhaseFatal, dwPercentComplete = 94, szObjectName = DAG1 in organizational unit CN=Computers,DC=letsexchange,DC=com, dwStatus = 0x5 )

When dwStatus is 0x0, it means “success” but 0x5 means “access denied” just like the error we received in the Shell.
After some troubleshooting, I found out that the DAG’s Cluster Name Object [CNO] wasn’t created properly! There were two problems with the CNO:
1. The Exchange Trusted Subsystem universal security group didn’t have Full Access permissions to it;
2. The CNO was enabled in Active Directory:


After assigning full control to DAG1 AD object to the Exchange Trusted Subsystem and then disabling it, everything worked just fine:

Monday, September 17, 2012

How to Determine Continuous Replication Mode (Block Mode or File Mode)?

In Exchange 2007 and 2010, Continuous Replication operates by shipping copies of the logs created by the active database copy to the passive database copies. With Exchange 2010 SP1, this is known as Continuous Replication - File Mode as the log file is only copied once it is full (1MB). But SP1 introduces a new form of continuous replication known as Continuous Replication - Block Mode. In block mode, when an update is written to the active database log file it is immediately copied to the passive mailbox copies, thus reducing the latency between the time a change is made on the active copy and the time that same change is replicated to a passive copy. This way, if a failure occurs on the active copy, the passive copies will have been updated with most or all of the latest updates.

However, Block Mode is only active when continuous replication is up-to-date in file mode. The Log Copier component monitors the copy and replay queue lengths of databases as transaction logs are generated and takes care of transitioning into and out of block mode automatically.

To determine if continuous replication is operating in block mode or file mode, use the following cmdlet:
Get-Counter -ComputerName <<DAG_Member_Name>> -Counter “\MSExchange Replication(*)\Continuous replication - block mode Active”

The output will be something similar to:
Timestamp                 CounterSamples
---------                 --------------
04/09/2012 11:39:46       \\MBX1\\msexchange replication(mdb31)\continuous replication - block mode active : 1
                          \\ MBX1\\msexchange replication(mdb32)\continuous replication - block mode active : 1
                          \\ MBX1\\msexchange replication(mdb33)\continuous replication - block mode active : 0

Here, the “1” means that block mode is active while a “0” means it is not. However, note that your active databases will always show “0”, we are just interested in the passive copies!

Sunday, July 8, 2012

Suspend Multiple Database Copies

If you are doing maintenance on a server and want to suspend all passive database copies on that server it is very simple and all you have to do is run:
Get-MailboxDatabaseCopyStatus -Server "server_name" | Suspend-MailboxDatabaseCopy -Confirm:$False

Because we are not excluding the current mounted DBs (if any), the script will throw an error stating that “The suspend operation can't proceed because database "db_name" on Exchange Mailbox server "server_name" is the active mailbox database copy” - which is fine because it’s what we want.

If you want to suspend all passive copies of a particular database across all servers you can simply run:
Get-MailboxDatabaseCopyStatus "db_name" | Suspend-MailboxDatabaseCopy -Confirm:$False

But what if you are reducing the number of database copies in your environment and just want to suspend the 4th copy of all your DBs across all your servers? In this case, we will have to use the following script:
$dbs = Get-MailboxDatabase

ForEach ($db in $dbs) {
  ForEach ($dbCopy in $db.DatabaseCopies) {
    If ($dbCopy.ActivationPreference -eq 4) {
      Suspend-MailboxDatabaseCopy $dbCopy.Identity -Confirm:$False
    }
  }
}

Hope this helps!

Wednesday, November 30, 2011

Disable iSCSI Networks for DAGs


If you have Exchange 2010 DAGs and you use iSCSI to present those servers with storage for the databases, you must ensure the DAG does not use this network.

When a DAG is configured, it tries to discover all networks configured on the server and configure them to be used by the underlying cluster, which includes any iSCSI networks... If you have a problem with your MAPI and Replication networks, Exchange will try to use the iSCSI network for normal DAG and user traffic which, obviously, will not work and generate loads of errors (such as cluster.exe trying to communicate with other nodes over this network).

As a best practice, iSCSI storage should use dedicated networks and network adapters. These networks shouldn't be managed by the DAG or its cluster, or used as DAG networks (MAPI or replication).


You can check what networks your DAG is currently using by running the following cmdlet in EMS:
Get-DatabaseAvailabilityGroup -Status | Select Name, NetworkNames

or get a more detailed view with which networks were detected, what are they used for and if they are excluded from the DAG:
Get-DatabaseAvailabilityGroupNetwork -Server MBX1 | Select Name, MapiAccessEnabled, ReplicationEnabled, IgnoreNetwork


Disabling it/them, is a two-step process:

1. DAG

Configure the DAG to ignore your iSCSI networks (replace with the correct name):
Set-DatabaseAvailabilityGroupNetwork <MbxDAG1\iSCSInetwork> –ReplicationEnabled $False –IgnoreNetwork $True


2. Cluster

To disable the network for use by the cluster you can use the GUI. However, there was a bug in a certain Windows 2008 R2 version (apologies, not sure which one) where you would select the following option:



You would then click ok but when you went back to the same screen, the Allow cluster network communication on this network was still selected...


So, the best option is to use the Cluster Network command. You can check what the network is currently configured for:




  • Role 0 (0x0) tells the cluster not to use the network;
  • Role 1 (0x1) tells the cluster that this is a private network;
  • Role 3 (0x3) tells the cluster that this is a public network.


And set the Role to 0:
Cluster network ClusterNetworkName /prop Role=0

To check if the command worked properly, run the Cluster network ClusterNetworkName /prop again.


After disabling all iSCSI networks for use by the DAG and its cluster, you can optionally force network discovery by running the Set-DatabaseAvailabilityGroup cmdlet with the DiscoverNetworks parameter.

Hope this helps!

Thursday, August 18, 2011

Monitor Databases in DAGs

A few days ago, someone at the Microsoft Forums asked if there was a script to alert an administrator of when Exchange performs a failover of databases in a DAG.

This was something that I have wanted to do for a long time, but never actually got to do it... So here is my current solution (might get improved in the future).


With Exchange 2010 and DAGs, it is important to monitor whenever a database automatic fails over to another server. Although everything keeps working without any problems for end users (hopefully), administrators still have to investigate why a failover happened.

In case you have Exchange deployed across multiple AD sites and a database fails over to a server on another site, this will probably impact the way your users access OWA, for example.

Databases in a DAG, and therefore with multiple copies, have the ActivationPreference attribute that shows which servers have preference over the others to mount the database in case of a disaster or a manual switchover.

The following output is just an example of what you will get if you run the following command in an environment with at least a DAG and multiple copies:

Get-MailboxDatabase | Sort Name | Select Name, ActivationPreference


Name    ActivationPreference
----    --------------------
ADB1    {[MBXA1, 1], [MBXA2, 2]}
ADB2    {[MBXA1, 1], [MBXA2, 2]}
ADB3    {[MBXA1, 1], [MBXA2, 2]}
...
MDB1    {[MBX1, 1], [MBX2, 2], [MBX3, 3], [MBX4, 4]}
MDB2    {[MBX1, 1], [MBX2, 2], [MBX3, 3], [MBX4, 4]}
MDB3    {[MBX1, 1], [MBX2, 2], [MBX3, 3], [MBX4, 4]}
...

Based on the ActivationPreference attribute, we can monitor if databases are currently active on the servers that they should be, i.e., on servers with an ActivationPreference of 1.

To check this, we can use the following script:



Get-MailboxDatabase | Sort Name | ForEach {
 $db = $_.Name
 $curServer = $_.Server.Name
 $ownServer = $_.ActivationPreference | ? {$_.Value -eq 1}

 Write-Host "$db on $curServer should be on $($ownServer.Key) - " -NoNewLine

 If ($curServer -ne $ownServer.Key)
 {
  Write-Host "WRONG" -ForegroundColor Red
 }
 Else
 {
  Write-Host "OK" -ForegroundColor Green
 }
}



Which basically compares the server where the database is currently active with the server that has an ActivationPreference of 1. If they differ, then write WRONG in red to let the administrator know.

But since we are at it, why not also check for the status of the database and the state of its content index? This can be checked using the Get-MailboxDatabaseCopyStatus cmdlet.

According to the Monitoring High Availability and Site Resilience TechNet article, here are all the possible values for the database copy status:


Database Copy Status
Failed - The mailbox database copy is in a Failed state because it isn't suspended, and it isn't able to copy or replay log files. While in a Failed state and not suspended, the system will periodically check whether the problem that caused the copy status to change to Failed has been resolved. After the system has detected that the problem is resolved, and barring no other issues, the copy status will automatically change to Healthy;

Seeding - The mailbox database copy is being seeded, the content index for the mailbox database copy is being seeded, or both are being seeded. Upon successful completion of seeding, the copy status should change to Initializing;

SeedingSource - The mailbox database copy is being used as a source for a database copy seeding operation;

Suspended - The mailbox database copy is in a Suspended state as a result of an administrator manually suspending the database copy by running the Suspend-MailboxDatabaseCopy cmdlet;

Healthy - The mailbox database copy is successfully copying and replaying log files, or it has successfully copied and replayed all available log files;

ServiceDown - The Microsoft Exchange Replication service isn't available or running on the server that hosts the mailbox database copy;

Initializing - The mailbox database copy will be in an Initializing state when a database copy has been created, when the Microsoft Exchange Replication service is starting or has just been started, and during transitions from Suspended, ServiceDown, Failed, Seeding, SinglePageRestore, LostWrite, or Disconnected to another state. While in this state, the system is verifying that the database and log stream are in a consistent state. In most cases, the copy status will remain in the Initializing state for about 15 seconds, but in all cases, it should generally not be in this state for longer than 30 seconds;

Resynchronizing - The mailbox database copy and its log files are being compared with the active copy of the database to check for any divergence between the two copies. The copy status will remain in this state until any divergence is detected and resolved;

Mounted - The active copy is online and accepting client connections. Only the active copy of the mailbox database copy can have a copy status of Mounted;

Dismounted - The active copy is offline and not accepting client connections. Only the active copy of the mailbox database copy can have a copy status of Dismounted;

Mounting - The active copy is coming online and not yet accepting client connections. Only the active copy of the mailbox database copy can have a copy status of Mounting;

Dismounting - The active copy is going offline and terminating client connections. Only the active copy of the mailbox database copy can have a copy status of Dismounting;

DisconnectedAndHealthy - The mailbox database copy is no longer connected to the active database copy, and it was in the Healthy state when the loss of connection occurred. This state represents the database copy with respect to connectivity to its source database copy. It may be reported during DAG network failures between the source copy and the target database copy;

DisconnectedAndResynchronizing - The mailbox database copy is no longer connected to the active database copy, and it was in the Resynchronizing state when the loss of connection occurred. This state represents the database copy with respect to connectivity to its source database copy. It may be reported during DAG network failures between the source copy and the target database copy;

FailedAndSuspended - The Failed and Suspended states have been set simultaneously by the system because a failure was detected, and because resolution of the failure explicitly requires administrator intervention. An example is if the system detects unrecoverable divergence between the active mailbox database and a database copy. Unlike the Failed state, the system won't periodically check whether the problem has been resolved, and automatically recover. Instead, an administrator must intervene to resolve the underlying cause of the failure before the database copy can be transitioned to a healthy state;

SinglePageRestore - This state indicates that a single page restore operation is occurring on the mailbox database copy;



Based on these values, we want the Status attribute to be either Mounted (true for the server where the database is mounted) or Healthy (for the servers that hold a copy of it). For the ContentIndexState attribute, we want it to be always Healthy.

To monitor both these attribute, we can use the following command:


Get-MailboxDatabase | Sort Name | Get-MailboxDatabaseCopyStatus | ForEach {
 If ($_.Status -notmatch "Mounted" -and $_.Status -notmatch "Healthy" -or $_.ContentIndexState -notmatch "Healthy")
 {
  Write-Host "`n$($_.Name) - Status: $($_.Status) - Index: $($_.ContentIndexState)" -ForegroundColor Red
 }
}



Now, let’s put everything together and tell the script that if something is wrong with any database, to send an e-mail to the administrator! This way, we can create a schedule task to run this script every 2 minutes, for example.

Let’s also compare the AD sites where the current server hosting the database is against the AD site where the server that should be hosting the database is. As I mentioned before, this is important as it can change the way users access OWA.

You can also download the entire script from here.

Function getExchangeServerADSite ([String] $excServer)
{
 # We could use WMI to check for the domain, but I think this method is better
 # Get-WmiObject Win32_NTDomain -ComputerName $excServer

 $configNC =([ADSI]"LDAP://RootDse").configurationNamingContext
 $search = new-object DirectoryServices.DirectorySearcher([ADSI]"LDAP://$configNC")
 $search.Filter = "(&(objectClass=msExchExchangeServer)(name=$excServer))"
 $search.PageSize = 1000
 [Void] $search.PropertiesToLoad.Add("msExchServerSite")

 Try {
  $adSite = [String] ($search.FindOne()).Properties.Item("msExchServerSite")
  Return ($adSite.Split(",")[0]).Substring(3)
 } Catch {
  Return $null
 }
}



[Bool] $bolFailover = $False
[String] $errMessage = $null

Get-MailboxDatabase | Sort Name | ForEach {
 $db = $_.Name
 $curServer = $_.Server.Name
 $ownServer = $_.ActivationPreference | ? {$_.Value -eq 1}

 # Compare the server where the DB is currently active to the server where it should be
 If ($curServer -ne $ownServer.Key)
 {
  # Compare the AD sites of both servers
  $siteCur = getExchangeServerADSite $curServer
  $siteOwn = getExchangeServerADSite $ownServer.Key
  
  If ($siteCur -ne $null -and $siteOwn -ne $null -and $siteCur -ne $siteOwn)
  {
   $errMessage += "`n$db on $curServer should be on $($ownServer.Key) (DIFFERENT AD SITE: $siteCur)!" 
  }
  Else
  {
   $errMessage += "`n$db on $curServer should be on $($ownServer.Key)!"
  }

  $bolFailover = $True
 }
}

$errMessage += "`n`n"

Get-MailboxDatabase | Sort Name | Get-MailboxDatabaseCopyStatus | ForEach {
 If ($_.Status -notmatch "Mounted" -and $_.Status -notmatch "Healthy" -or $_.ContentIndexState -notmatch "Healthy")
 {
  $errMessage += "`n$($_.Name) - Status: $($_.Status) - Index: $($_.ContentIndexState)"
  $bolFailover = $True
 }
}

If ($bolFailover)
{
 Send-MailMessage -From "admin_nuno@letsexchange.com -To "exchange.alerts@letsexchange.com" -Subject "DAG NOT Healthy!" -Body $errMessage -Priority High -SMTPserver "mail.letsexchange.com"
 Schtasks.exe /Change /TN "MonitorDAG" /DISABLE
}




As always, sorry for the format of the code...
At the end of the script, if an e-mail is sent, you might want to disable the schedule task, otherwise you will receive an e-mail every two minutes until you resolve the issue...

Please note that there are more attributes that can and should be monitored! For example, you could run the Test-ReplicationHealth to view replication status information about mailbox database copies.

Hope this helps!