Walking through Exchange 2013’s Hybrid Configuration Wizard steps

Recently the Hybrid Configuration Wizard in Exchange Server 2013 stopped working abruptly due to an issue in Exchange Online. Unlucky people who ran the Hybrid Configuration Wizard would have been confronted with the following error:


Whilst the error Subtask CheckPrereqs execution failed was reported in the Office 365 portal, it has taken a few weeks to get a fix; and at the time of writing the fix – an Interim Update for Exchange 2013 Service Pack 1 and Cumulative Update 5 is in the process of being issued to customers. You can read more about the error on the KB article here.

Potentially, you can run the steps in the Hybrid Configuration Wizard yourself, especially if you plan on re-running the Hybrid Configuration Wizard once you have the update and are willing to take on the risk and support for doing so yourself. Remember not that long ago the Hybrid steps were all configured manually and the steps it performs are not magic.

In this post I’ll walk through the steps to create the configuration. If you are planning to follow these steps, remember firstly – you can raise a Support Request for free in your Office 365 tenant and get the Interim Update. You don’t need to do this, if this isn’t something you could/would figure out for yourself given a successful HCW log, then don’t try this at home.

Secondly, this is all on you. You need to run through each line one by one and check that the configuration is correct. the HCW doesn’t blindly run through these steps, it checks pre-requisites (hell, that’s the error above) and so should you.

Creating the Federation Trust

First things first – and this is sometimes worth doing if you want to pre-register the Domain Proof TXT records we will create a Federation Trust. It’s easy enough to create this in the Exchange Admin Center – just navigate to Organization>Sharing and then under the heading Federation Trust choose Enable:


After choosing enable, grab the domains you will be federating (i.e. the ones that are both on-premises Accepted Domains and Custom Domain in Office 365) and use the following command at the Exchange Management Shell to get the proof record

Get-FederatedDomainProof -DomainName domainname

Make sure those are registered in DNS and the records have correctly propagated.

Performing the Hybrid Configuration

We’ll now be ready to walk through the Hybrid Configuration itself. We’ll do this from a single Exchange Management Shell session, registering some variables first that will make it easier to apply the config. You’ll see in my example I’ve specified my own domains, tenant name, servers and EWS URLs. I have put these in variables so that I don’t need to specify them multiple times in the script. The TLS Certificate name is the Issuer () and Subject () concatenated.

# Variables for HCW
# Variables for HCW
$Credential = Get-Credential
$TenantDomain = "tenant.mail.onmicrosoft.com"
$Features = "FreeBusy", "MoveMailbox", "Mailtips", "MessageTracking", "OwaRedirection", "OnlineArchive", "SecureMail", "Photos"
$Domains = @("contoso.com")
$OnPremisesSmartHost = "mail.contoso.com"
$ClientAccessServers = @("EXL-E1501")
$ReceivingTransportServers = @("EXL-E1501")
$SendingTransportServers = @("EXL-E1501")
# This is .Issuer and .Subject from Get-ExchangeCertificate combined using issuer..subject...
$TlsCertificateName = "CN=DigiCert Secure Server CA, O=DigiCert Inc, C=USCN=*.contoso.com, OU=IT,O=Steve, L=Nuneaton, S=Warwickshire, C=GB"
$EWSExternalURL = "https://mail.contoso.comk/EWS/Exchange.asmx"
$OrganizationName = (Get-OrganizationConfig).Name
$OrganizationGuid = (Get-OrganizationConfig).Guid.Guid.ToString()

My next step is to make sure that the relevant configuration specified above makes it into the Hybrid Configuration Object.

Set-HybridConfiguration -ClientAccessServers $ClientAccessServers -ReceivingTransportServers $ReceivingTransportServers -SendingTransportServers $SendingTransportServers -OnPremisesSmartHost $OnPremisesSmartHost -Domains $Domains -Features $Features -TlsCertificateName $TlsCertificateName

Our final piece of setup is to connect to Exchange Online PowerShell as well. We’ll want to do this from the same session, therefore we’ll prefix the Exchange Online PowerShell commands with the Cloud prefix, so that “Get-Mailbox” becomes “Get-CloudMailbox”:

# Import Office 365 session
$session = New-PSSession -ConfigurationName Microsoft.Exchange -Authentication Basic -ConnectionUri https://ps.outlook.com/powershell -AllowRedirection:$true -Credential $Credential
Import-PSSession $session -Prefix Cloud

Our first piece of Hybrid Configuration is the recipient related settings. We’ll be adding an additional proxy address to each recipient, so we will add an accepted domain using the tenant service domain (tenant.mail.onmicrosoft.com) and updating the Default Email Address Policy:

# Configure Recipient Settings
New-RemoteDomain -Name "Hybrid Domain - $($TenantDomain)" -DomainName $TenantDomain
Set-RemoteDomain -TargetDeliveryDomain:$true -Identity "Hybrid Domain - $($TenantDomain)"
New-AcceptedDomain -DomainName $TenantDomain -Name $TenantDomain
$EmailAddressPolicy = Get-EmailAddressPolicy "Default Policy"
$NewTemplates = $EmailAddressPolicy.EnabledEmailAddressTemplates+="smtp:%m@$($TenantDomain)"
Set-EmailAddressPolicy -Identity "Default Policy" -ForceUpgrade:$true -EnabledEmailAddressTemplates:$NewTemplates
Update-EmailAddressPolicy -Identity "Default Policy" -UpdateSecondaryAddressesOnly:$true

We’ll next configure the Organization Relationship. This is used primarily for Free/Busy and Calendar sharing and relies on the Federated Domain Proof registered earlier:

# Configure Organization Relationship
Set-Federationtrust -Identity 'Microsoft Federation Gateway' -RefreshMetadata:$false
Set-FederatedOrganizationIdentifier -AccountNamespace $Domains[0] -DelegationFederationTrust 'Microsoft Federation Gateway' -Enabled:$true -DefaultDomain $null
Set-CloudFederatedOrganizationIdentifier -DefaultDomain $TenantDomain -Enabled:$true
$FederationInfo = Get-FederationInformation -DomainName $TenantDomain -BypassAdditionalDomainValidation:$true 
New-OrganizationRelationship -Name "On-premises to O365 - $($OrganizationGuid)" -TargetApplicationUri 'outlook.com' -TargetAutodiscoverEpr $FederationInfo.TargetAutodiscoverEpr.ToString() -Enabled:$true -DomainNames $TenantDomain
New-CloudOrganizationRelationship -Name "O365 to On-premises - $($OrganizationGuid)" -TargetApplicationUri "FYDIBOHF25SPDLT.$($Domains[0])" -TargetAutodiscoverEpr "https://autodiscover.$($Domains[0])/autodiscover/autodiscover.svc/WSSecurity" -Enabled:$true -DomainNames $Domains
Set-OrganizationRelationship -MailboxMoveEnabled:$true -FreeBusyAccessEnabled:$true -FreeBusyAccessLevel 'LimitedDetails' -ArchiveAccessEnabled:$true -MailTipsAccessEnabled:$true -MailTipsAccessLevel 'All' -DeliveryReportEnabled:$true -PhotosEnabled:$true -TargetOwaURL "http://outlook.com/owa/$Domains[0]" -Identity "On-premises to O365 - $($OrganizationGuid)"
Set-CloudOrganizationRelationship -FreeBusyAccessEnabled:$true -FreeBusyAccessLevel 'LimitedDetails' -MailTipsAccessEnabled:$true -MailTipsAccessLevel 'All' -DeliveryReportEnabled:$true -PhotosEnabled:$true -Identity "O365 to On-premises - $($OrganizationGuid)"
Add-AvailabilityAddressSpace -ForestName $TenantDomain -AccessMethod 'InternalProxy' -UseServiceAccount:$true -ProxyUrl $EWSExternalURL

We’ll then continue by enabling the MRS Proxy. This is used for Remote Mailbox moves – the mechanism for moving mailboxes to and from the cloud in Exchange 2010 and 2013:

# Configure MRS Proxy
foreach ($ClientAccessServer in $ClientAccessServers)
    Get-WebServicesVirtualDirectory -Server $ClientAccessServer | Set-WebServicesVirtualDirectory -MRSProxyEnabled:$True

Then we’ll complete our last undocumented steps, configuring mail flow between Office 365 and on-premises Exchange:

# Configure Mail Flow
New-SendConnector -Name 'Outbound to Office 365' -AddressSpaces $TenantDomain -SourceTransportServers $SendingTransportServers -DNSRoutingEnabled:$true -TLSDomain 'mail.protection.outlook.com' -RequireTLS:$true -TLSAuthLevel 'DomainValidation' -ErrorPolicies 'Default' -TLSCertificateName $TlsCertificateName -CloudServicesMailEnabled:$true -Fqdn $null
foreach ($ReceivingTransportServer in $ReceivingTransportServers)
    Set-ReceiveConnector -Identity "$($ReceivingTransportServer)\Default Frontend $($ReceivingTransportServer)" -TLSCertificateName $TlsCertificateName -TLSDomainCapabilities 'CN=MSIT Machine Auth CA 2, DC=redmond, DC=corp, DC=microsoft, DC=comCN=mail.protection.outlook.com, OU=Forefront Online Protection for Exchange, O=Microsoft, L=Redmond, S=WA, C=US:AcceptCloudServicesMail'
New-CloudInboundConnector -Name "Inbound from $($OrganizationGuid)" -ConnectorType 'OnPremises' -RequireTLS:$true -SenderDomains "*" -TLSSenderCertificateName $TlsCertificateName -CloudServicesMailEnabled:$true
New-CloudOutboundConnector -Name "Outbound to $($OrganizationGuid)" -RecipientDomains $Domains -SmartHosts $OnPremisesSmartHost -ConnectorType 'OnPremises' -TLSSettings 'DomainValidation' -TLSDomain $OnPremisesSmartHost -CloudServicesMailEnabled:$true -RouteAllMessagesViaOnPremises:$false -UseMxRecord:$false
New-CloudOnPremisesOrganization -HybridDomains $Domains -InboundConnector "Inbound from $($OrganizationGuid)" -OutboundConnector "Outbound to $($OrganizationGuid)" -OrganizationRelationship "O365 to On-premises - $($OrganizationGuid)" -OrganizationName $OrganizationName -Name $($OrganizationGuid) -OrganizationGuid $($OrganizationGuid)

With that, the Hybrid Configuration is complete and ready to be tested. If you did run through these steps manually, then I can’t stress enough – these are not supported, and you would definitely need to run the Hybrid Configuration Wizard afterwards to ensure it is exactly the way Exchange does it and it’s own checks and balances pass.

With the Hybrid Complete the next step is to configure OAuth. I won’t go through the manual steps to configure this here though as the instructions are still available on TechNet.

As you can see, performing a Hybrid Configuration isn’t particularly tough if you need to do it manually. It’s actually simpler in Exchange 2013 than it was if you were to do it manually in Exchange 2010.

However, whether it’s actually supported if you do the steps manually is another matter.