Category Archives: Exchange Online

Creating a Catch-all Mailbox using Transport Rules

There are as many reasons to use catch-all mailboxes as there are against, and of course spam is one of the biggest concern. Nevertheless people are still asking for this feature, and therefore I want to show that it is possible also using Exchange Online in Office 365.

I will achieve this by using Transport Rules to control our mail flow. Transport Rules are a very flexible and powerful solution, yet easy to maintain. We have previously here at written a few posts of Transport Rules, but I still think that they deserve a little more attention.

Now to my demo. After establishing a PowerShell session to Exchange Online the first thing we have to do is to change our domain type to Internal Relay.

$domain = ''
Set-AcceptedDomain -Identity $domain -DomainType InternalRelay

Next we need a distribution list that contains all our mailboxes. The idea is to redirect all messages sent to unknown addresses, and this distribution list will contain all known addresses, which mean we have something to use in our Transport Rule. Here I prefer to use a Dynamic Distribution List since they don’t require any maintenance after the initial configuration. Maybe you already have a distribution list that you want to re-use instead. If you want to this distribution list can be hidden from the Global Address List.

New-DynamicDistributionGroup `
	-Name 'Everyone' `
	-PrimarySmtpAddress "everyone@$domain" `
	-IncludedRecipients AllRecipients

Finally we create the Transport Rule that will do the actual redirection of the Mail Flow. In my example I want to redirect all emails to an already existing mailbox, $targetAddress.

$targetAddress = "contact@$domain"
New-TransportRule `
	-Name "Catch-all $domain" `
	-RecipientDomainIs $domain `
	-ExceptIfSentToMemberOf "everyone@$domain" `
	-RedirectMessageTo $targetAddress

All emails sent to the domain $domain is hit by this rule, as specified by the RecipientDomainIs parameter. I am also using the Everyone Distribution List in the ExceptIfSentToMemberOf parameter, so that my rule doesn’t hit existing mailboxes. It would also create a loop if messages addressed to the target mailbox were processed, they would be forwarded to the mailbox itself infinitely.

Now we are all set. All messages sent to non-existent addresses in the domain $domain will now be delivered to the mailbox $targetAddress.

/ Andreas


Troubleshooting TLS in an Exchange Online Hybrid Deployment

One of the prerequisites for having a Hybrid relationship established between your on-prem Exchange environment and Office 365 is to have a functioning mail flow using TLS. The Hybrid Configuration Wizard automatically creates the inbound and outbound connectors required both in your on-prem environment and in Office 365 as a part of the setup, and this is used for secure mail transfer between the two environments.

If TLS fails your mail flow will suddenly stop, and outgoing emails are stuck in the queue with error message 451 4.4.0 Primary target IP address responded with: “451 5.7.3 Must issue a STARTTLS command first.”. You may not even be able to complete the Hybrid Configuration Wizard, you just get an error message stating that Subtask ValidateConfiguration execution failed: Configure Mail Flow.

Several blogs on the Internet addresses these problems, but must of them show you the commands how to turn TLS off. This is not something that I recommend! A problem is not solved by hiding it’s symptoms, always try to find the root cause.

There are several possible reasons for malfunctioning TLS. A good start in the troubleshooting is to use good old telnet.exe and connect to on port 25. By simply sending the ehlo command you can easily see if the server is accepting TLS connections. If you get a 250-STARTTLS response the problem is most likely with your certificate. It may not be configured to be used with SMTP, or is longer valid. Also make sure that you have installed the latest Root Certificate Updates from Windows Update.


A response from the SMTP server without the STARTTLS extension listed might indicate that your IP address is on a blacklist. Use one of the online tools available for free to check the status of your IP address. In your telnet session you will find the IP address you are connecting from.

This IP address must also be in list of Sender IP Addresses in the Hybrid Mail Flow Inbound Connector in Office 365 created by the Hybrid Configuration Wizard. If it isn’t there it must be added. If the IP is incorrect the connector will not be used, and the mail flow will use the MX record instead, without enforcing TLS.


Another result from your telnet session could be this:


In this case a firewall is configured to filter some protocols, which effectively stops all TLS communication. In for example Cisco firewalls the solution is to turn off ESMTP inspection.

This is not a complete guide on how to solve your TLS problems, but it shows some common solutions, and hopefully it gives you some input to start your troubleshooting.

/ Andreas

Exchange Online: How to create a dirsynced Resource Mailbox

The idea with DirSync is to keep your user administration on-prem. A problem arise when you decomission the on-premises Exchange server and want to create a Shared Mailbox or a Resource Mailbox. There is no simple way to create such mailbox without assigning a license. It is possible to create a new regular user, assign a license, and then convert it to a Shared Mailbox or a Resource Mailbox, but the drawback with this method is that it requires a license during the process. On the other hand your user account will be fully managed in your on-prem environment, and the goal is achieved.

Another possibility is to create a Resource Mailbox with a Cloud Identity, and then connect it to an account synced from your Active Directory. This is what I will show you now. Lets start with disabling DirSync. This step is not necessary, but we might get some problems if our accounts are synced before they are ready.

Stop-Service MSOnlineSyncScheduler

Then we create a user account in Active Directory that we will later sync to Office 365:

Import-Module ActiveDirectory
$ADUserProperties = @{
    Name =               'Meeting Room 1'
    Path =               'CN=Users,DC=365lab,DC=net'
    SamAccountName =     'room1'
    UserPrincipalName =  ''
    DisplayName =        'Meeting Room 1'
    EmailAddress =       ''
    OtherAttributes = @{
        ProxyAddresses = ''
$ADUser = New-ADUser @ADUserProperties -PassThru

The next step is to create a new Resource Mailbox in Office 365. This can be done either with GUI or PowerShell, I prefer PowerShell.

$O365cred = Get-Credential
$O365sess = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $O365cred -Authentication Basic -AllowRedirection
$importcmd = Import-PSSession $O365sess

$O365UserProperties = @{
    DisplayName =        'Meeting Room 1'
    Name =               'room1'

$RoomMailbox = New-Mailbox @O365UserProperties -Room

Now we have two separate accounts, one in Active Directory with the managed attributes, and one in the cloud that we want to connect to our on-prem identity. The connection is done by populating the ImmutableID attribute with the corresponding ObjectGuid from Active Directory. Also, we change the UserPrincipalName in Office 365 to match our domain account.

$ObjectGuid = $ADUser.objectGuid
$ImmutableId = [System.Convert]::ToBase64String($ObjectGuid.ToByteArray())

Import-Module MSOnline

Set-MsolUserPrincipalName -UserPrincipalName $RoomMailbox.UserPrincipalName -NewUserPrincipalName $ADUser.UserPrincipalName -ImmutableId $ImmutableId

Now our UserPrincipalNames are the same in both our Active Directory and in Office 365, and we have linked then together using the ObjectGuid/ImmutableId. Time to start our DirSync service again and force a synchronization to run.

Start-Service MSOnlineSyncScheduler

Import-Module DirSync
Start-OnlineCoexistenceSync -FullSync

Now the Cloud Identity is converted to a DirSynced Identity, and the attributes in Active Directory are syned to our new Resource Mailbox. From now on all user administration tasks for this account can be managed in our on-prem Active Directory.

/ Andreas

How to handle SMTP Relay after migrating to Exchange Online

When decomissioning your on-premises Exchange server after moving to Office 365 you need a new solution for SMTP relay to use with for example multi-functional printers. In some cases your internet provider can offer this service, but if you want control over your mail flow I recommend using Office 365 also for outgoing e-mail.

Normally you need a licensed user to be able to send e-mails using SMTP with Office 365. Your applications also need support for TLS encryption. If your application doesn’t support TLS, or if you need to send e-mails from another address than the licensed user’s address you need another solution. Luckily Office 365 can help you. The solution is to set up an inbound connector in Exchange Online Protection.

Setting up an Inbound Connector

An Inbound Connector is easily set up with just a few lines of PowerShell code. First we have to connect to Exchange Online.

$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange `
    -ConnectionUri '' `
    -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session -CommandName 'New-InboundConnector'

Now we can create the Inbound Connector. All we have to specify is a Name for our connector, SenderIPAddresses which is the IP addresses to allow relaying from (your external IP address), and SenderDomains which is the domains to accept messages from.

You can also get your external IP address with PowerShell, here I will use a free IP detection tool from Dyn.

$ip = (Invoke-WebRequest -Uri `
    -replace '[^\d\.]'
New-InboundConnector `
    -Name 'SMTP Relay' `
    -SenderIPAddresses $ip `
    -SenderDomains ''

The settings for Mail Flow are also found in Exchange admin center, navigate to mail flow, and then go to the connectors section. Of course you can also use the GUI to create your connector.


When configuring your application to connect to this SMTP server, use your MX server name as SMTP server and connect using port 25. The server name can be found in Office 365 admin center, and looks something like

Increasing security

With this method all computers on your network sharing the same external IP address can use your Inbound Connector. To strengthen the security I recommend only opening port 25 in the firewall from your devices that actually sends email. An even better alternative would be to set up an internal SMTP server that only accept connections from approved devices, and then uses your Inbound Connector as smart host. This can be achieved with the SMTP Service provided with Internet Information Services (IIS) in Windows Server.

Configuring IIS SMTP Service

First we have to install the SMTP Service in Windows. This can be done with PowerShell.

Note that the Add-WindowsFeature cmdlet in Windows Server 2012 is called Install-WindowsFeature, but Add-WindowsFeature still exists as alias for backward compatibility.

Import-Module ServerManager
Add-WindowsFeature SMTP-Server

This will also install the required dependencies for example the IIS 6 Management Console. When the installation is done we are ready to start configuring the service. Let’s set the service to start automatically when Windows starts:

Set-Service SMTPSVC -StartupType Automatic

The next step is to set Office 365 as Smart Host. Replace the Smart Host name with your own MX server.

$smtpsvc = [ADSI]'IIS://localhost/smtpsvc/1'
$smtpsvc.SmartHost = ''

We also have to set a Fully Qualified Domain Name to identify our SMTP Server.

$hostname = (Resolve-DnsName $ip).NameHost
$smtpsvc.FullyQualifiedDomainName = $hostname

Finally we have to add our internal IP addresses that are allowed to use the SMTP Service. I prefer using the GUI for this. You will find these settings in the Internet Information Services (IIS) 6.0 Manager. Expand the local computer node, and right click on “SMTP Virtual Server #1” and choose Properties. On the Access tab click on Relay restrictions, and then add your local IP addresses that are allowed to use the SMTP Server. While in the GUI settings I also suggest having a look at the message size limits and logging settings.

Now we are all set. Don’t forget to configure your perimeter firewall to block outgoing SMTP traffic from all your computers except the SMTP Server.

/ Andreas

Conditional mail routing in Exchange Online Protection

In this post we will go through how to achieve conditional mail routing in Exchange Online Protection, without the need of having forwarding addresses per user. This means we can deliver incoming emails sent to the same domain to different back end servers, based on other criterias than forwarding addresses, like certain attributes or group membership.

If interested in how to do this using the mail users and forwarding addresses method, Andreas wrote a post a while ago about using Exchange Online as a mail gateway for decentalized email domains.


  • Exchange Online Protection is in place for all incoming emails.
  • You have a single Exchange organization, but different servers across the globe. You want to have external incoming emails directly to the correct mailbox server without transferring them trough your WAN connection.
  • DirSync from your tenant to EOP is already activated and in place, which means all users and Groups are already in WAAD.
  • Our incoming email routing will look like in the sketch below, based on AD Group membership.


As we in this case already have decided to base our email routing on AD groups which is already in sync with WAAD, the things we need to configure in EOP for each target server are following:

1. Create an outbound connector with support for Criteria Based Routing (CBR). Of course more than one smart host can be added for redundancy purposes. cbr

New-OutboundConnector -Name "CBR -" `
                      -ConnectorType OnPremises `
                      -SmartHosts "" `
                      -UseMXRecord $false `
                      -IsTransportRuleScoped $true 

2. Create a mail flow/transport rule for each destination connector/ad group.cbr-transport

New-TransportRule -Name "CBR -" ` 
                  -SentToMemberOf "" `
                  -RouteMessageOutboundConnector "CBR -"

To avoid mail flow issues for users that are not in any of the groups, make sure you keep your existing default outbound connector.


Using Exchange Online as mail gateway for decentralized email domains

In some scenarios it is useful to have a central email server that forwards messages to different email servers. You might for example have a company with different business units, each having an email server of their own. In this post I will show you how to get started with the mail flow using one domain, but with several different email servers in Exchange Online.

Consider the following scenario. Several email servers exists within a company:

  • In USA an on-premises Exchange environment is using addresses
  • In Spain an external hosting provider is delivering an email service based on pop3 using addresses
  • In Poland Exchange Online is used, but with addresses

A new corporate policy states that all users must have an email address of the form Also, a central antispam system must be used. At this point no consolidation of email servers will be done. Exchange Online Protection licenses has been bought by the company.

To take care of the mail flow in Exchange Online we have to create our Office 365 tenant and add the domain to it. We also have to change our DNS and let the MX records for point to Exchange Online. This will give us the following mail flow for a user in for example Poland:

Mail flow

I have a csv file with all users in each location:


For each user we will create a mail enabled user that holds the alias and target email addresses. I will use PowerShell to create these users:

#Import all users
$users = Import-Csv users.csv

#Create a password for all users
$Password = ConvertTo-SecureString 'Pa$$w0rd' -asPlainText -Force

#Create mail-enabled user
ForEach ($user in $users) {
	$Name = $user.Name
	$Email = $user.Alias
	$Target = $user.Email
	New-MailUser -Name $Name -MicrosoftOnlineServicesID $Email -ExternalEmailAddress $Target -Password $Password

Now all emails sent to the addresses will be delivered to the current regional email server. The next step would be to configure each email server to use as from address, and only accept incoming emails from Exchange Online.

/ Andreas

How to manually configure an Outlook profile for Office 365

Manually configuring Outlook for Office 365 can be tricky. That’s what Autodiscover is for. But in some situations you have to be able to do a manual configuration in for example a pilot deployment. Here are the steps required.

The nice thing with this method is that we will be able configure Outlook without changing our Autodiscover DNS records. That means we can do a full Office 365 test deployment without affecting users in an on-premises Exchange environment.

The first step is to establish a remote PowerShell session to Exchange Online. Here we need the ExchangeGuid attribute from our mailbox. Copy this value and save it for later.


The next step is to launch the New Profile Wizard in Outlook. We will go for the option to do a Manual setup.


In the next screen we select that we have a Microsoft Exchange Server.


Now it’s time to enter the exchange server name. Here we need the ExchangeGuid from the first step. Write the Guid followed by @ and the email domain. The user name is our Office 365 user name.
Now click More Settings.


On the Security tab we select Anonymous Authentication.


On the Connection tab check the box to connect using HTTP and click Exchange Proxy Settings


Fill in all values as below


Click OK to close all windows. You will be asked for credentials, fill in your Office 365 username and password.


Now our Outlook Profile is ready to use and Outlook is configured for Exchange Online, without using Autodiscover.

/ Andreas

Exchange Online: Migrating shared mailboxes and resources

In Exchange 2003 Resource Mailboxes and Shared Mailboxes are often set up as a regular user mailbox. These mailboxes are still possible to migrate using Staged Migration or Cutover Migration, by migrating them as a regular user mailbox. The downside is that they will require an Exchange Online license.

If you are migrating from an Exchange version that supports Hybrid Migration you will be able to migrate resources directly without assigning licenses, but there is a workaround for Cutover and Staged migrations as well.

The process of migrating a Shared Mailbox or Resource Mailbox is as follows:

  1. Migrate mailbox as regular user mailbox
  2. Assign license
  3. Convert mailbox to shared/resource
  4. Remove license

To convert a user mailbox to a shared mailbox we just need one line of PowerShell. Except from changing the type, we also have to modify the mailbox quotas.

Set-Mailbox -Identity "" `
	-Type Shared `
	-IssueWarningQuota 9.5GB `
	-ProhibitSendQuota 9.75GB `
	-ProhibitSendReceiveQuota 10GB

The same thing applies to Resource Mailboxes (Rooms and Equipment). The difference here is that we also want to configure AutoAccept policies and set default access rights to the calendar:

Set-Mailbox -Identity "" `
	-Type Room `
	-IssueWarningQuota 9.5GB `
	-ProhibitSendQuota 9.75GB `
	-ProhibitSendReceiveQuota 10GB

Set-CalendarProcessing -Identity "" `
	-AutomateProcessing AutoAccept 

Add-MailboxFolderPermission "\Calendar" `
	-User Default `
	-AccessRights LimitedDetails

After this is done the license can be removed. You will get a warning that your data will be lost, but it is safe to click Yes on this one.


/ Andreas

Office 365: Monitor and finish remote mailbox moves

A while ago, I posted a script that helps you out informing end users and starting remote mailbox moves in hybrid migration scenarios.
In the script we started our mailbox moves with the -SuspendWhenReadyToComplete switch. That switch means we manually have to go in and resume the mailbox moves with the Resume-MoveRequest cmdlet.

In this follow up script, we automate that process by monitoring active mailbox moves and handle resuming and removing of them. We also have the possibility to send out emails to our end users when the move has been completed (if uncommenting row 78).

Note: The script only works as intended if you have created one moverequest per user, as done in my script that start the migrations.

    Script that monitors remote mailbox moves in Exchange Online and handles resuming, removing of them. 
    Author: Johan Dahlbom 
    Email: johan[at] 
    The script are provided “AS IS” with no guarantees, no warranties, and they confer no rights.     

#region variables
$CloudUsername = ""
$CloudPassword = ConvertTo-SecureString "password" -AsPlainText -Force
$CloudCred = New-Object System.Management.Automation.PSCredential $CloudUsername, $CloudPassword
$PSScriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
$Logfile = ($PSScriptRoot + "\HybridMigrations.log")
$enduserinfo = @"
Hi $($MoveRequest.batchname),<p>

You've just been moved to Office 365, if you have questions regarding the move, or if anything is not working as intended, let us know!
<strong>Best Regards
IT Department
#endregion variables

#region functions
#Function to send out email with defined parameters
function Send-MigrationMail {
$emailFrom = "Office 365 <>"
$smtpserver = ""
$subject = "Migration batch Finished"
$cc = ""
Send-MailMessage -From $emailfrom -To $Recipient -Cc $cc -SmtpServer $smtpserver -Subject $subject -Body $Message -BodyAsHtml
#Function to write information to a log file and to console output
function Write-Log {
Param (
Add-Content $Logfile -value $logstring -ErrorAction Stop
Write-Output $logstring
#endregion functions

#Connect to Exchange Online
if (!(Get-Command Get-CloudMoveRequest -ErrorAction SilentlyContinue)) {
    $session = New-PSSession -ConfigurationName Microsoft.Exchange -Authentication Basic -ConnectionUri -AllowRedirection:$true -Credential $CloudCred
    Import-PSSession $session -Prefix Cloud -CommandName @("Get-MoveRequest","Resume-MoveRequest","Remove-MoveRequest","Get-MoveRequestStatistics") -AllowClobber

#Run the following as long as there are active move requests
while (Get-CloudMoveRequest)
	$MoveRequests = Get-CloudMoveRequest
	foreach ($MoveRequest in $MoveRequests) {
		switch ($MoveRequest.status) { 
			"InProgress" 	{ 
				Write-Output "INFO: Move request for $($MoveRequest.Batchname) at $((Get-CloudMoveRequestStatistics -Identity $MoveRequest.BatchName).PercentComplete)% $(Get-date -format u)" 
			"AutoSuspended" {
				Write-Log "INFO: Completing mailbox move for $($MoveRequest.BatchName) at $(get-date -Format u)"
				Resume-CloudMoveRequest -identity $moverequest.batchname
			"Completed" 	{
				Write-Log "INFO: Removing completed MoveRequest $($MoveRequest.Batchname) at $(get-date -Format u)"
                #Uncomment row below to send information to end users when migration has been completed.
                #Send-MigrationMail -Message $enduserinfo -Recipient $moverequest.batchname 
				Remove-CloudMoveRequest -identity $moverequest.batchname -confirm:$false 
	Write-Host "------------------------------------------------------------------------------"
	Start-Sleep 60

 Write-Log "INFO: All migration batches finished at $(Get-Date -format u)"
 #Send information to admin then the batches are complete.
 Send-MigrationMail -Message "Migration batch finished at $(Get-Date -format u)<br>Logfile attached." -Recipient

Hope this is at any help, just let me know if you have suggestions that can improve the script.


Exchange Online: Pre-populate language and time zone on new mailboxes

When a new Exchange Online mailbox is created the user is prompted to set language and time zone at first logon. This information is possible to pre-populate to make the experience smoother for the end users. This is particularly useful in a migration scenario.

2014-02-08 21-18-09

These settings are set with the cmdlet Set-MailboxRegionalConfiguration.


Set-MailboxRegionalConfiguration -identity "" `
    -TimeZone "W. Europe Standard Time" -Language "sv-SE" -confirm:$false

Some useful links:

/ Andreas