Monday, May 20, 2013

How to Setup Hosted Exchange 2013 (Multi-Tenancy)



Need some guidance to setup Hosted Exchange 2013? I’ll share my thoughts
Please note that the following information is only guidance and will help you installing a non-productive environment for testing purposes. There might other or different steps be necessary for you to successfully install a productive hosted Exchange environment. This guide should provide help to build the Structures to “isolate” different Tenants on Exchange 2013
Here are some useful resources:
In my setup I used two virtual Servers running Windows 2012 Standard. One Server will act as Domaincontroller with all necessary roles while the second server will hold Exchange itself.

Domain Controller Requirements

  • Install the latest Windows Updates
  • Make sure server has a static IP address configured
  • Install Active Directory Roles
  • Promote Server to Domain Controller
In my example the Server is called DC2012 and the Active Directory Domain is called hosted.exchange.

Exchange Server Requirements

  • Install Windows Updates
  • Make sure the server has a static IP address
  • Join the newly created domain

Exchange Installation

Before we can start installing Exchange we have to install some Pre-Requisites as describedhere.
Then we just start the Exchange Setup and make sure we install both, the Mailbox Server Role as well as the Client Access Server Role.
Choose a name for your Exchange Organization. I simply named it “Hosted Exchange”
Let the installation process finish. The rest we can do from the Domaincontroller.
As the Multi-Tenancy and Hosting Guide for Exchange Server 2013 states, the only way to get a supported environment is using cmd-lets to automate your tasks. Any manual modification in Active Directory and/or Exchange Objects is unsupported. So let’s do all the necessary steps from the Windows Power Shell.

Creating Active Directory Structure for Tenants

We’re make it simple and Create a OU called Tenants right in the root of the Active Directory Structure
New-ADOrganizationalUnit -Name Tenants
This is a one time step. If you want you can provide more information to this OU using the according parameteres. You can always use Active Directory Users and Computers (ADUC) to verify if your commands have beend completed successfully. You should now see the OU Tenants in ADUC.

Creating first Tenant
# 1. create a OU for the first Tenant “Tenant A”
New-ADOrganizationalUnit -Name TenantA -Path “OU=Tenants,DC=hosted,DC=exchange”
# 2.  register the new UPN Suffix
Set-ADForest -Identity hosted.exchange -UPNSuffixes @{add=”tenanta.com”}
This is what need’s to be done in Active Directory. Now let’s continue using the Exchange Management Shell (EMS). We can “load” the EMS directly from this shell (assuming that you’re working with the Domain Administrator now)
# 3. connect to EMS
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://ex2013.hosted.exchange/PowerShell/ -Authentication Kerberos
Import-PSSession $Session
make sure you adjust the path according to your setup. PowerShell is now loading the Exchange cmd-lets
# 4. Add a new accepted Domain for the new Tenant
New-AcceptedDomain -Name “TenantA” -DomainName tenanta.com -DomainType:Authoritative
# 5. Create Global Address List for Tenant A
New-GlobalAddressList -Name “TenantA – GAL” -ConditionalCustomAttribute1 “TenantA” -IncludedRecipients MailboxUsers -RecipientContainer “hosted.exchange/Tenants/TenantA”
# 6. Create All Rooms Address List
New-AddressList -Name “TenantA – All Rooms” -RecipientFilter “(CustomAttribute1 -eq ‘TenantA’) -and (RecipientDisplayType -eq ‘ConferenceRoomMailbox’)” -RecipientContainer “hosted.exchange/Tenants/TenantA”
# 7. Create All Users Address List
New-AddressList -Name “TenantA – All Users” -RecipientFilter “(CustomAttribute1 -eq ‘TenantA’) -and (ObjectClass -eq ‘User’)” -RecipientContainer “hosted.exchange/Tenants/TenantA”
# 8. Create All Contacts Address List
New-AddressList -Name “TenantA – All Contacts” -RecipientFilter “(CustomAttribute1 -eq ‘TenantA’) -and (ObjectClass -eq ‘Contact’)” -RecipientContainer “hosted.exchange/Tenants/TenantA”
# 9. Create All Groups Address List
New-AddressList -Name “TenantA – All Groups” -RecipientFilter “(CustomAttribute1 -eq ‘TenantA’) -and (ObjectClass -eq ‘Group’)” -RecipientContainer “hosted.exchange/Tenants/TenantA”
# 10. Create Offline Address Book
New-OfflineAddressBook -Name “TenantA” -AddressLists “TenantA – GAL”
# 11. Create Email Address Policy
New-EmailAddressPolicy -Name “TenantA – EAP” -RecipientContainer “hosted.exchange/Tenants/TenantA” -IncludedRecipients “AllRecipients” -ConditionalCustomAttribute1 “TenantA” -EnabledEmailAddressTemplates “SMTP:%m@tenanta.com”,”smtp:%g.%s@tenanta.com”
You may want to play around with the parameter: -EnabledPrimarySMTPAddressTemplate “SMTP:%g.%s@tenanta.com” that will set Firstname.Lastname@domain.tld for the default Email Address Policy (EAP)
# 12. Create Address Book Policy
New-AddressBookPolicy -Name “TenantA” -AddressLists “TenantA – All Users”, “TenantA – All Contacts”, “TenantA – All Groups” -GlobalAddressList “TenantA – GAL” -OfflineAddressBook “TenantA” -RoomList “TenantA – All Rooms”

# 13. Create a Room Mailbox (optional)
New-Mailbox -Name ‘Tenant A Conference Room 1′ -Alias ‘TenantA_ConfRoom1′ -OrganizationalUnit ‘hosted.exchange/Tenants/TenantA’ -UserPrincipalName ‘confroom1@tenanta.com’ -SamAccountName ‘TenantA_ConfRoom1′ -FirstName ‘Conference’ -Initials ” -LastName ‘Room 1′ -AddressBookPolicy ‘TenantA’ -Room
Set-Mailbox TenantA_ConfRoom1 -CustomAttribute1 ‘TenantA’
It is important that Tenant-wide Objects do have the CustomAttribute1 Set to the according Tenant.
Now that we have all the address books and policies configured we can start with the first user mailbox. The new user will have the same password as the account you enter after the first command. You can adjust the New-Mailbox command to your needs.
$c = Get-Credential
New-Mailbox -Name ‘Tenant User 1′ -Alias ‘TenantA_user1′ -OrganizationalUnit ‘hosted.exchange/Tenants/Tenant A’ -UserPrincipalName ‘User1@tenanta.com’ -SamAccountName ‘tenanta_user1′ -FirstName ‘Tenant’ -Initials ’1′ -LastName ‘User’ -Password $c.password -ResetPasswordOnNextLogon $false -AddressBookPolicy ‘TenantA’
Set-Mailbox user1@tenanta.com -CustomAttribute1 “TenantA”

After you’re done, you want to close the Session to the EMS
Remove-PSSession $Session
You can now log on to owa with the user you just created and check the configuration. You will find all the Tenant related Address Lists. You can create another user for this Tenant and find him in your address book. They can share calendars and book conference rooms.
You can repeat the steps above to create another Tenant, with its own accepted domainname, address lists and policies.
to be continued

20 comments:

  1. I'm stuck on step 6. When i run the powershell command i get the following:

    Cannot bind parameter 'RecipientFilter' to the target. Exception setting "RecipientFilter": "Invalid filter syntax. For
    a description of the filter parameter syntax see the command help.
    "(CustomAttribute1 -eq 'My Company') -and (RecipientDisplayType -eq 'ConferenceRoomMailbox')" at positi
    on 24."
    At C:\Users\Administrator\AppData\Local\Temp\2\tmp_mo1i05u1.25d\tmp_mo1i05u1.25d.psm1:30681 char:9
    + $steppablePipeline.End()
    + ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : WriteError: (:) [New-AddressList], ParameterBindingException
    + FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.Exchange.Management.SystemConfigurationTasks.NewAddress
    List


    Any tips?

    ReplyDelete
    Replies
    1. $c = Get-Credential

      New-Mailbox -Name ‘Tenant User 1′ -Alias ‘TenantA_user1′ -OrganizationalUnit ‘hosted.exchange/Tenants/Tenant A’ -UserPrincipalName ‘User1@tenanta.com’ -SamAccountName ‘tenanta_user1′ -FirstName ‘Tenant’ -Initials ’1′ -LastName ‘User’ -Password $c.password -ResetPasswordOnNextLogon $false -AddressBookPolicy ‘TenantA’

      Set-Mailbox user1@tenanta.com -CustomAttribute1 “TenantA”

      Please check the quote

      Delete
    2. Hi Evyn,

      that is a few steps to far. I'm stuck on this command

      New-AddressList -Name “TenantA – All Rooms” -RecipientFilter “(CustomAttribute1 -eq ‘TenantA’) -and (RecipientDisplayType -eq ‘ConferenceRoomMailbox’)” -RecipientContainer “hosted.exchange/Tenants/TenantA”

      Delete
  2. Please check the quote. Do not copy and paste.

    ReplyDelete
    Replies
    1. found what you meant, thanks a bunch!

      Now i'm sorry to say that i'm stuck at step 10

      PS C:\Users\Administrator> Get-GlobalAddressList

      Name RecipientFilter
      ---- ---------------
      Default Global Address List ((Alias -ne $null) -and (((ObjectClass -eq 'user') -or (...
      TenantA - GAL ((CustomAttribute1 -eq 'TenantA') -an...

      PS C:\Users\Administrator> New-OfflineAddressBook -name "TenantA" -AddressLists "TenantA - GAL"
      Address list or global address list "TenantA - GAL" was not found. Please make sure you typed the identity correctly.
      + CategoryInfo : NotSpecified: (:) [New-OfflineAddressBook], ManagementObjectNotFoundException
      + FullyQualifiedErrorId : 47BE0D06,Microsoft.Exchange.Management.SystemConfigurationTasks.NewOfflineAddressBook
      + PSComputerName : rsrc-exch-fe01.exchange.local

      Delete
    2. nevermind, i found the issue :)

      Delete
    3. I am stuck here as well. What was your issue?

      Delete
    4. Has anyone got past 10 as I get a GAL error TenantA - GAL not found

      Delete
  3. I managed to work around the quotes and resolved so that bit is fine I am not on step 10 and it errors as follows
    [PS] C:\Windows\system32>New-OfflineAddressBook -Name "TenantA" -AddressList "TenantA - GAL"
    Address list or global address list "TenantA - GAL" was not found. Please make sure you typed the identity correctly.
    + CategoryInfo : NotSpecified: (:) [New-OfflineAddressBook], ManagementObjectNotFoundException
    + FullyQualifiedErrorId : B0330D4D,Microsoft.Exchange.Management.SystemConfigurationTasks.NewOfflineAddressBook
    + PSComputerName : buzz.apps247.local

    ReplyDelete
  4. After typing in step 13 and hit enter I get >> and nothing else. Do i need to enter anything further
    Thank you

    ReplyDelete
    Replies
    1. Got it had to retype the entire cmdlt not just the commas

      Delete
    2. How did you get past the step 10 ???

      Delete
    3. IT just worked when i typed it in

      Delete
  5. Has anyone worked out how to get past Step 10?
    I am getting the same error no matter if I copy paste or type it all out.

    Below is the output of Get-'s and New-'s

    PS C:\Users\Administrator> Get-AddressList

    Name DisplayName RecipientFilter
    ---- ----------- ---------------
    Public Folders Public Folders ((Alias -ne $null) -and (ObjectCategory -like 'publicFolder'))
    tenanta - All Rooms tenanta - All Rooms ((CustomAttribute1 -eq 'tenanta') -and (RecipientDisplayType -...
    tenanta - All Users tenanta - All Users ((CustomAttribute1 -eq 'tenanta') -and (ObjectClass -eq 'User'))
    tenanta - All Contacts tenanta - All Contacts ((CustomAttribute1 -eq 'tenanta') -and (ObjectClass -eq 'Conta...
    tenanta - All Groups tenanta - All Groups ((CustomAttribute1 -eq 'tenanta') -and (ObjectClass -eq 'Group'))
    All Contacts All Contacts ((Alias -ne $null) -and (((ObjectCategory -like 'person') -and (...
    All Groups All Groups ((Alias -ne $null) -and (ObjectCategory -like 'group'))
    All Rooms All Rooms ((Alias -ne $null) -and (((RecipientDisplayType -eq 'ConferenceR...
    All Users All Users ((Alias -ne $null) -and (((((ObjectCategory -like 'person') -and...


    PS C:\Users\Administrator> Get-GlobalAddressList

    Name RecipientFilter
    ---- ---------------
    Default Global Address List ((Alias -ne $null) -and (((ObjectClass -eq 'user') -or (...
    tenanta - GAL ((CustomAttribute1 -eq 'tenanta') -and (RecipientType ...


    PS C:\Users\Administrator> New-OfflineAddressBook -Name "tenanta" -AddressLists "tenanta - GAL"
    Active Directory operation failed on W12-AD01.hosted-lab.local. The object 'CN=tenanta,CN=Offline Address
    Lists,CN=Address Lists Container,CN=hosted-lab,CN=Microsoft
    Exchange,CN=Services,CN=Configuration,DC=hosted-lab,DC=local' already exists.
    + CategoryInfo : NotSpecified: (:) [New-OfflineAddressBook], ADObjectAlreadyExistsException
    + FullyQualifiedErrorId : 703C994E,Microsoft.Exchange.Management.SystemConfigurationTasks.NewOfflineAddressBook
    + PSComputerName : w12-es01.hosted-lab.local

    PS C:\Users\Administrator> New-AddressBookPolicy -Name "tenanta" -AddressLists "tenanta - All Users", "tenanta - A
    ll Contacts", "tenanta - All Groups" -GlobalAddressList "tenanta - GAL" -OfflineAddressBook "tenanta" -RoomList "C
    asaTorre - All Rooms"
    Address list or global address list "tenanta - All Users" was not found. Please make sure you typed the identity
    correctly.
    + CategoryInfo : NotSpecified: (:) [New-AddressBookPolicy], ManagementObjectNotFoundException
    + FullyQualifiedErrorId : 6AF50B2D,Microsoft.Exchange.Management.SystemConfigurationTasks.NewAddressBookPolicy
    + PSComputerName : w12-es01.hosted-lab.local

    PS C:\Users\Administrator> Get-AddressBookPolicy
    PS C:\Users\Administrator>

    ReplyDelete
  6. Love the step by step guide. Wondering has anyone set this up with federation so it use the tennants own active directory users id and password for logon too the mailbox

    ReplyDelete
    Replies
    1. Hi Anonymous,

      did you ever get an answer for that question regarding federation of the tenants?

      Delete
  7. use cloudpanel a good interface for multitenant

    ReplyDelete
  8. The steps worked create for me.

    Thank you.
    Shahid Mushtaq

    ReplyDelete