Skip to content
Geek and I
Go back

Exchange 2013 multi-tenancy, step by step

Updated:
Mike Horwath4 min read

This all started because I wanted to learn something new (and useful) yesterday.

Multiple searches on the Internet gave me a lot of what I needed to get this done but no single site had everything laid out. (not complete truth, one site had great information and is the catalyst of this post)

So I decided to put together a step by step guide for the new Exchange administrator, or even a seasoned administrator moving to Exchange 2013 and needing to have distinct, separate organizations on a single server or cluster.

Here is how I set up multi-tenancy in Exchange 2013. This is all done via PowerShell Exchange Cmdlets. Powerful and verbose!

We need a container to hold all of our data, created at the root of Active Directory (A/D going forward).

On your A/D server, via PowerShell:

Terminal window
New-ADOrganizationalUnit -Name Habitats

First, create an Organization Unit (OU) to hold the tenant data, I am using the word ‘Tenant’ with a 5 digit sequence number in my examples. In the example you will need to replace ‘hosted’ ‘exchange’ with your local domain.

On your A/D server, via PowerShell:

Terminal window
New-ADOrganizationalUnit -Name Tenant00001 -Path "OU=Habitats,DC=hosted,DC=exchange"

Now we need to User Principal Name (UPN) suffixes for later.

On your A/D server, via PowerShell:

Terminal window
Set-ADForest -Identity hosted.exchange -UPNSuffixes @{add="zsmtp.net"}

If you are working remote against the Exchange server then you need to create a connection to EMS as the rest of the configuration is now with Exchange directly instead of A/D.

NOTE: This is not required if you are on the Exchange server itself. You later destroy this session at the end (documented below) but since you are on the A/D server for the above cmdlets then it is just easier to keep going with a single PowerShell connection.

Terminal window
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://ex01/PowerShell/ -Authentication Kerberos
Import-PSSession $Session

Now, add a new domain for the new tenant.

Terminal window
New-AcceptedDomain -Name "Tenant00001" -DomainName zsmtp.net -DomainType:Authoritative

Create the Global Address List (GAL) for Tenant00001

Terminal window
New-GlobalAddressList -Name "Tenant00001 - GAL" -ConditionalCustomAttribute1 "Tenant00001" -IncludedRecipients MailboxUsers -RecipientContainer "hosted.exchange/Habitats/Tenant00001"

If needed then create All Rooms Address List

Terminal window
New-AddressList -Name "Tenant00001 - All Rooms" -RecipientFilter "(CustomAttribute1 -eq 'Tenant00001') -and (RecipientDisplayType -eq 'ConferenceRoomMailbox')" -RecipientContainer "hosted.exchange/Habitats/Tenant00001"

And time to create All Users Address List

Terminal window
New-AddressList -Name "Tenant00001 - All Users" -RecipientFilter "(CustomAttribute1 -eq 'Tenant00001') -and (ObjectClass -eq 'User')" -RecipientContainer "hosted.exchange/Habitats/Tenant00001"

The All Contacts Address List

Terminal window
New-AddressList -Name "Tenant00001 - All Contacts" -RecipientFilter "(CustomAttribute1 -eq 'Tenant00001') -and (ObjectClass -eq 'Contact')" -RecipientContainer "hosted.exchange/Habitats/Tenant00001"

The All Groups Address List

Terminal window
New-AddressList -Name "Tenant00001 - All Groups" -RecipientFilter "(CustomAttribute1 -eq 'Tenant00001') -and (ObjectClass -eq 'Group')" -RecipientContainer "hosted.exchange/Habitats/Tenant00001"

Now for something quite useful: Offline Address Book

Terminal window
New-OfflineAddressBook -Name "Tenant00001" -AddressLists "Tenant00001 - GAL"

You’ll also need to create an Email Address Policy. This example also includes first.last@domain email aliasing, or you can set the primary email address to first.last@domain by using the -EnabledPrimarySMTPAddressTemplate "SMTP:%g.%[email protected]" attribute and data.

Terminal window
New-EmailAddressPolicy -Name "Tenant00001 - EAP" -RecipientContainer "hosted.exchange/Habitats/Tenant00001" -IncludedRecipients "AllRecipients" -ConditionalCustomAttribute1 "Tenant00001" -EnabledEmailAddressTemplates "SMTP:%g.%[email protected]","smtp:%[email protected]" -EnabledPrimarySMTPAddressTemplate "SMTP:%g.%[email protected]"
Set-EmailAddressPolicy -Identity "Tenant00002 - EAP" -EnabledPrimarySMTPAddressTemplate "SMTP:%g.%[email protected]"

Now we need to create the Address Book Policy

Terminal window
New-AddressBookPolicy -Name "Tenant00001" -AddressLists "Tenant00001 - All Users", "Tenant00001 - All Contacts", "Tenant00001 - All Groups" -GlobalAddressList "Tenant00001 - GAL" -OfflineAddressBook "Tenant00001" -RoomList "Tenant00001 - All Rooms"

Optional: create a resource for rooms by creating a Room Mailbox. It is vital that we also set a Custom Attribute for the tenant

Terminal window
New-Mailbox -Name 'Tenant00001 Conference Room 1' -Alias 'Tenant00001_conf1' -OrganizationalUnit 'hosted.exchange/Habitats/Tenant00001' -UserPrincipalName '[email protected]' -SamAccountName 'Tenant00001_conf1' -FirstName 'Conference' -LastName 'Room 1' -AddressBookPolicy 'Tenant00001' -Room
Set-Mailbox Tenant00001_conf1 -CustomAttribute1 'Tenant00001'
Set-CalendarProcessing -Identity Tenant00001_conf1 -AutomateProcessing AutoAccept -DeleteComments $true -AddOrganizerToSubject $true -AllowConflicts $false

Almost done, we are getting to the good parts now.

Let’s create some users with their associated mailboxes.

First, we need to get a password for the user, this will prompt you for such. For the ‘username’ field you can type anything you want as it is the password attribute we want for the mailbox being created. As with a room mailbox we need to also set a custom attribute to the tenant.

Terminal window
$c = Get-Credential
New-Mailbox -Name 'Mike Horwath' -Alias 'tenant00001_mike' -OrganizationalUnit 'hosted.exchange/Habitats/Tenant00001' -UserPrincipalName '[email protected]' -SamAccountName 'tenant00001_mike' -FirstName 'Mike' -LastName 'Horwath' -Password $c.password -ResetPasswordOnNextLogon $false -AddressBookPolicy 'Tenant00001'
Set-Mailbox [email protected] -CustomAttribute1 "Tenant00001"

If you connected to the Exchange server from remote you should close your Session

Terminal window
Remove-PSSession $Session

And you now have created your first tenant organization.

You can now continue to create users and resource mailboxes via the new Exchange Action Center (EAC).

Good luck!

One item that will probably crop up for you is the issues of quotas. By default, the quotas are 2 GiB for a mailbox; here is how you can add/update the quota on a mailbox.

Of course, adjust as needed.

Terminal window
Set-Mailbox -Identity "[email protected]" -IssueWarningQuota 4.5gb -ProhibitSendQuota 4.9gb -ProhibitSendReceiveQuota 5gb -UseDatabaseQuotaDefaults $false

Download: scripted-tenancy.zip

References



Related Posts

Previous Post
Configure syslog for VMware ESXi via PowerCLI
Next Post
Continuing to play with Statamic