Tag Archives: hybrid

Back to Basics: Creating new users in an Exchange Hybrid Deployment

Some of the most common questions I get from my clients are related to how to create new users in an Exchange Hybrid environment. I have seen users set up in an incorrect way in most Hybrid Environments. Some common problems resulting from this include missing Autodiscover functionality or bouncing emails from external users. The reason for these kind of problems is that your on-premises Exchange server doesn’t recognize the Exchange Online mailbox.

The best way of creating new users during the Hybrid is to use the New Remote Mailbox guide in Exchange Management Console (this can of course also be done in an on-premises Exchange 2013 server, the principle is the same). This will create both the AD account, and populate all necessary attributes for Office 365. It will also enable you to continue using Exchange Management Console for managing all Exchange attributes.

The key is to use the Mail Contact pane in Exchange Management Console. Start by right-clicking and select the New Remote Mailbox guide.


Select the type of mailbox you are creating, normally a User Mailbox.


Fill in all the information that you would normally fill in when creating a new AD user.


If you are not using Archive Mailboxes just click Next.


Review the summary and click New.


All done! Close the guide by clicking Finish.


If we right-click on our new user and check the Email Addresses tab, we will see that it is already populated with all addresses according to our E-mail Address Policy. We even have a Routing E-mail Address set, pointing to our Office 365 tenant.


This means that we are all set, our on-premises Exchange server is now aware of the Mailbox in Office 365! The final step is to wait for DirSync (or force a sync) then assign a license to the user.

/ Andreas


Office 365: Start hybrid migrations and inform users

Lately I’ve been doing quite a few Hybrid setups.
One of the things that cause quite a lot of pain when doing migrations in general is getting information out to your users.
Even if you have a good communication plan, only 20% of your users read the information and only 5% of them reflect and understand it. 🙂

To make this a bit easier, I’ve created a small script that starts Hybrid migration batches and sends out information to the end user.
This is of course just an example, but gives you a good idea of what you are able to do with quite simple means.


Getting started:

  • Review all relevant variables in the script
  • Change the text in BodyHybrid.txt to fit in to your needs, the html in that file will be the information sent in the email. The words ActiveSyncDevices,OWAAddress,EmailAddress and Firstname will automatically be replaced by its corresponding variables. (and no the css is not the best 🙂 )
  • Create the PDF Office365Info.pdf and put it in the same folder as the script, that file will be attached to the email.
  • Create input file Prepare-Mailboxes.csv with samAccountNames of the users that you want to migrate. (Note that I am assuming that the users Email Address and UserPrincipalName are the same in the script)
    Also note that the MoveRequest settings in the script might not fit your needs (Baditemlimit, Largeitemlimit).

As we are using the switch -SuspendWhenReadytoComplete in the script, the batches will autosuspend at 95% completion.
That means you’ll have to complete them manually with for example the following line:

Get-CloudMoveRequest | Where-Object {$_.Status -eq "AutoSuspended"} | Resume-CloudMoveRequest. 

Another good option to get in better control of your remote mailbox moves is to use Michael Halls excellent tool based on PowerShell and Excel that does that for you.


    Starts hybrid migrations based on input (samAccountName) from a csv file.
    The script starts hybrid migrations and sends out information emails based on the file "BodyHybrid.txt".
    PowerShell V3.0 required
    File Name: Start-HybridMigrations.ps1
    Author   : Johan Dahlbom, johan[at]dahlbom.eu
    The script are provided “AS IS” with no guarantees, no warranties, and they confer no rights.

#Import Required Modules
Import-Module ActiveDirectory

#Define Mail Information and Logging
$Users = Get-Content Prepare-MailboxMoves.csv
$BodyHybrid = Get-Content BodyHybrid.txt -Raw
$OWAAddress = 'http://outlook.com/365lab.net'
$Attachment = Get-Childitem .\Office365Info.pdf
$PSScriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
$Logfile = ($PSScriptRoot + "\HybridMigrations.log")

#Define Exchange Online Variables
$ExchServ = "exchangecas.corp.365lab.net"
$HybridServer = "webmail.365lab.net"
$DeliveryDomain = "365lab.mail.onmicrosoft.com"
$OnPremiseUsername = "cloud\svc_mailmigration"
$OnPremisePassword = ConvertTo-SecureString "password" -AsPlainText -Force
$CloudUsername = "svc-cloudmigration@365lab.onmicrosoft.com"
$CloudPassword = ConvertTo-SecureString "password" -AsPlainText -Force
$CloudCred = New-Object System.Management.Automation.PSCredential $CloudUsername, $CloudPassword
$OnPremCred = New-Object System.Management.Automation.PSCredential $OnPremiseUsername, $OnPremisePassword

#Connect to OnPremise Exchange
    if (!(Get-Command Get-ActiveSyncDeviceStatistics -ErrorAction SilentlyContinue)) {
    try {
        Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
    } catch {
            $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://$ExchServ/powershell" -Authentication Kerberos
            Import-PSSession -Session $Session -CommandName  Get-ActiveSyncDeviceStatistics -FormatTypeName * | Out-Null
#Connect to Exchange Online
    if (!(Get-Command New-CloudMoveRequest -ErrorAction SilentlyContinue))
	    $session = New-PSSession -ConfigurationName Microsoft.Exchange -Authentication Basic -ConnectionUri https://ps.outlook.com/powershell -AllowRedirection:$true -Credential $CloudCred
	    Import-PSSession $session -Prefix Cloud

function LogWrite {
Param ([string]$Logstring)
Add-Content $Logfile -value $logstring -ErrorAction Stop
Write-Host $logstring

function Send-MigrationMail {
    $emailFrom = "Office 365 Migration <office365@365lab.net>"
    $smtpserver = "smtpyrelay.365lab.net"
    $subject = "Email Migration Started"
    $cc = "migrator@365lab.net"

    Send-MailMessage -From $emailfrom -To $Recipient -Cc $cc -SmtpServer $smtpserver -Subject $subject -Body $Message -BodyAsHtml -Attachments $Attachment

LogWrite "$(get-date -Format u)"
foreach($aduser in $users) {
	$emailAddress = (Get-ADuser $aduser -properties UserPrincipalName).UserPrincipalName
	$firstname = (Get-ADuser $aduser).givenname
        #Find the number of Active ActiveSyncDevices that the user have in the local Exchange solution. If not, set to 0.
		$ActiveSyncDevices = (Get-ActiveSyncDeviceStatistics -Mailbox $aduser | Where-Object {$_.LastSuccessSync -gt (Get-Date).AddDays(-30)}).count
        if (!($ActiveSyncDevices)) {
            $ActiveSyncDevices = "0"
	    #Start Email Migration for user
        try {
            New-CloudMoveRequest -Identity $emailaddress -Remote -RemoteHostName $HybridServer -RemoteCredential $OnPremCred -TargetDeliveryDomain $DeliveryDomain -BatchName $emailAddress -SuspendWhenReadyToComplete -BadItemLimit 50 -LargeItemLimit 50
	} catch {
            $err = $_
            Logwrite "ERROR: Failed to start migration on $($emailAddress)`r`n$($err)"

        #Verify that the move request was successful and send information email
        if ((Get-CloudMoveRequest | Where-Object {$_.BatchName -eq $emailAddress} -ErrorAction SilentlyContinue)) {
            LogWrite "INFO: Started migration of user $($emailAddress) $(get-date -format u)"
            Send-MigrationMail -Recipient $emailAddress -Message $BodyHybrid.Replace('firstname',"$firstname").Replace('ActiveSyncDevices',"$ActiveSyncDevices").Replace("emailaddress","$emailaddress").Replace("OWAAddress","$OWAAddress")
            LogWrite "ERROR: Could not start migration for user $($emailAddress), please verify that user exists"

The script would of course be possible to extend with lots of things like license assignment, watching the mailboxes as they move and lots and lots of other things, but that’s for another day.
Just let me know if you have suggestions on improvements or other things that should be changed.
Download the script complete with the HTML-template and example csv file from here.

Happy migrations!


Emails from Messagelabs(Symantec) blocked after running HCW (Hybrid Configuration Wizard)

A couple of my customers have been running in to this issue lately, so I thought it was a good idea to share the issue with you guys.

Note: the issue only applies to those that are using Messagelabs/Symantec as their current spam-provider. (MX-record pointing to messagelabs)

After running Hybrid Configuration Wizard in Exchange 2010/2013 you experience intermittent issues with incoming emails from the internet (Messagelabs). If you dig further down to the issue you come to the conclusion that it only happens when you receive emails from certain ip subnets that Messagelabs are using.

As part of the Hybrid Configuration Wizard process, a receive connector named “Inbound from Office 365” is created. The purpose of that receive connector is to enable a secure mail flow directly from Office 365.
For that reason, the connector is configured with the setting RequireTLS set to True .
It also configures a set of remote ip ranges that the connector accepts (public Office 365 IP-ranges).

And it was here I came across the actual cause to this issue.
HCW are adding a remote ip range that overlaps with the public IP-ranges Messagelabs are using. This in combination with the fact that Messagelabs obviously doesn’t fully support TLS, makes this issue happen.
I confirmed this both with the transport logs and in Messagelabs documentation (http://images.messagelabs.com/EmailResources/ImplementationGuides/Subnet_IP.pdf).
The overlapping subnet is

See screenshot from the Exchange Server and Symantecs documentation below:
2013-12-25 22-34-08

2013-12-25 22-34-55

Looking further into the documentation Microsoft have on this at http://help.outlook.com/en-us/140/gg263350.aspx, you find out that the subnet isn’t there.
That is also confirmed by doing a whois on the subnet (http://www.whois.net/ip-address-lookup/ – this subnet does not belong to Microsoft.

That means it should be perfectly safe to remove that subnet from the receive connector, and I can confirm that it hasn’t created any problems in the cases I bumped in to.

Solution(or workarounds…)
The quick and dirtly solution to this issue is to to turn off the TLS requirements on the receive connector “Inbound from Office 365” with the PowerShell command as below

Get-ReceiveConnector "Inbound from Office 365" | Set-ReceiveConnector -RequireTLS $false

The better solution is to just remove the subnets from the receive connector, and it should be perfectly safe to do this since no emails from Office 365 will arrive that way.

Hope this helps you out if you are running in to this issue!