Even so, Exchange 2007 requires that both nodes of the CCR cluster must reside in the same Active Directory site. Best practice says that there should be redundant Global Catolog servers in each location, in case of an outage in either location. The trouble is that if each node of the CCR cluster and all the Global Catalogs reside in the same AD site, Exchange servers may (probably will) bind to a GC that is not in the same geographic location as the server, which can lead to problems.
Consider the following example:
A CCR geo-cluster called EXCCR exists in an Active Directory site called E2K7. NODE1 is in San Francisco and NODE2 is in Las Vegas. There are two Global Catalog servers in each site, SFDC1 and SFDC2 in San Francisco and LVDC1 and LVDC2 in Las Vegas. Because all six servers reside in the same AD site, Exchange will bind to any one of the four GCs. In this example, NODE1 is active and NODE2 happens to be using SFDC1 for Global Catalog and Configuration Domain Controller services. During this time, NODE2 is reaching across the WAN for GC services, which is not very efficient.
If there is a location specific outage in San Francisco (earthquake, power interruption, or some yahoo takes out a fiber trunk with a backhoe) the CCR cluster will fail over to Las Vegas, but the GC NODE2 is using (SFDC1) is unavailable, too. Exchange services will not fail over correctly and an outage occurs -- something that the CCR cluster is supposed to prevent.
This condition affects all Exchange servers in the E2K7 site, including all Hub Transport and Client Access Servers.
The way to design around this problem is to configure the CCR node in each location to exclude the GCs in the remote location. This is done using the following command from the Exchange Management Console, as shown for the Hub Transport server, EXHUB1:
Set-ExchangeServer -id EXHUB1 -StaticExcludedDomainControllers:sfdc1.domain.com,sfdc2.domain.com
Note that the Domain Controllers specified must be in FQDN form, separated by commas, with no spaces.
You would do the same for NODE1, specifying LVDC1 and LVDC2.
The result is that each node will always use the local GCs for that node. If both of those local GCs are unavailable for some reason, Exchange will temporarily bind to any GC in a remote site in the domain. This binding will occur automatically within 15 minutes. When the local GCs become available again, Exchange will re-bind to them within 15 minutes. Perfect!
It's a little different for the CCR mailbox server since the Set-ExchangeServer cmdlet runs against the CMS name. The cmdlet configures the registry of the active node, so you need to run it twice, as shown (assuming that NODE1 is the active node in San Francisco):
Set-ExchangeServer -id EXCCR -StaticExcludedDomainControllers:lvdc1.domain.com,lvdc2.domain.com
Then fail the CCR cluster over to NODE2 and run:
Set-ExchangeServer -id EXCCR -StaticExcludedDomainControllers:sfdc1.domain.com,sfdc2.domain.com
After this has been configured on both nodes the StaticExcludedDomainControllers value will be different, depending on which node is active.
While researching this article, I came across something unexpected. I set the StaticExcludedDomainControllers value using the Set-ExchangeServer cmdlet and it works as expected. But when I try to view the configuration using the Get-ExchangeServer cmdlet, the value appears empty, as shown:
The reason it shows null is because the StaticDomainControllers, StaticGlobalCatalogs, StaticConfigDomainController, and StaticExcludedDomainControllers variables are stored in the Exchange server's registry, not in Active Directory. According to Microsoft, this is "by design" to prevent performance issues caused by the Remote Registry call needed to retrieve the values. I'm not aware of any other cmdlet that has this behavior.
In any event, to view the configuration of these variables you must use the -Status switch, as shown:
The registry key where these values are stored is HKLM\System\CurrentControlSet\Services\MSExchange ADAccess\Profiles\Default. The value is a Multi-String Value (REG_MULTI_SZ) called ExcludedDCs.