Notes From The Field – Enabling GAL Segmentation in Exchange Online

Introduction

A few weeks back, I was tasked with configuring Global Address List (GAL) Segmentation for one of my clients. GAL Segmentation is not a new concept, and if you were to Google it (as you would do in this day and age), you will find numerous posts on it.

However, during my research, I didn’t find any¬†ONE article that helped me. Instead I had to rely on multiple articles/blogposts to guide me into reaching the result.

For those that are new to GAL Segmentation, this can be a daunting task. This actually is the inspiration for this blog, to provide the steps from an implementers view, so that you get the full picture about the preparation, the steps involved and the gotchas so that you feel confident about carrying out this simple yet scary change.

This blog will be focus on GAL Segmentation for an Exchange Online hybrid setup.

So what is GAL Segmentation?

I am glad you asked ūüėČ

By default, in Exchange Online (and On-Premises Exchange environment as well), a global address list is present. This GAL contains all mail enabled objects contained in the Exchange Organisation. There would be mailboxes, contacts, rooms, etc.

This is all well and good, however, at times a company might not want everyone to see all the objects in the Exchange environment. This might be for various reasons, for instance, the company has too many employees and it won’t make sense to have a GAL a mile long. Or, the company might have different divisions, which do not require to correspond to each other. Or the company might be trying to sell off one of its divisions, and to start the process, is trying to separate the division from the rest of the company.

For this blog, we will use the last reason, as stated above. A “filter” will be applied to all users who are in division to be sold off, so that when they open their GAL, they only see objects from their own division and not everyone in the company. In similar fashion, the rest of the company will see all objects except the division that will be sold off. Users will still be able to send/receive emails with that particular division, however the GAL will not show them.

I would like to make it extremely clear that GAL Segmentation DOES NOT DELETE any mail enable objects. It just creates a filtered version of the GAL for the user.

Introducing the stars

Lets assume there was once a company called TailSpin Toys. They owned the email namespace tailspintoys.com and had their own Exchange Online tenant.

One day, the board of TailSpin Toys decided to acquire a similar company called WingTip Toys. WingTip Toys had their own Exchange Online Tenant and used the email namespace wingtiptoys.com. After the acquisition, WingTip Toys email resources were merged into the TailSpin Toys Exchange Online tenant, however WingTip Toys still used their wingtiptoys.com email namespace.

After a few years, the board of TailSpin Toys decided it was time to sell of WingTip Toys. As a first step, they decided to implement GAL Segmentation between TailSpin Toys and WingTip Toys users.

Listed below is what was decided

  • TailSpin Toys users should only see email objects in their GAL corresponding to their own email namespace (any object with the primary smtp address of @tailspintoys.com). They should not be able to see any¬†WingTip Toys email objects.
  • Only¬†TailSpin Toys users will be able to see¬†Public Folders in their GAL
  • WingTip Toys users should only see email objects in their GAL corresponding to their own email namespace (any object with the primary smtp address of @wingtiptoys.com). They should not be able to see any¬†TailSpin Toys email objects.
  • The¬†All Contacts in the GAL will be accessible to both¬†WingTip Toys¬†and¬†TailSpin Toys users.

The Steps

Performing a GAL Segmentation is a very low risk change. The steps that will be carried out are as follows

  • Create new Global Address Lists, Address Lists, Offline Address Book and Address Book Policy for¬†TailSpin Toys and¬†WingTip Toys users.
  • Assign the respective policy to¬†TailSpin Toys users and¬†WingTip Toys users

The only issue is that by default, no users are assigned an Address Book Policy (ABP) in Exchange Online (ABPs are the “filter” that specifies what a user sees in the GAL).

Due to this, when we are creating the new address lists, users might see them in their GAL as well and get confused as to which one to use. If you wish to carry out this change within business hours, the simple remedy to the above issue is to provide clear communications to the users about what they could expect during the change window and what they should do (in this case use the GAL that they always use). Having said that, it is always a good practice to carry carry out changes out of business hours.

Ok, lets begin.

  • By default, the Address Lists Management role is not assigned in Exchange Online. The easiest way to assign this is to login to the Exchange Online Portal using a Global Administrator account and add this role to the Organization Management role group. This will then provide all the Address List commands to the Global Administratos.
  • Next, connect to Exchange Online using PowerShell
  • For TailSpin Toys
    • Create a default Global Address List called¬†Default TST Global Address List
    • New-GlobalAddressList -Name "Default TST Global Address List" -RecipientFilter {((Alias -ne $null) -and (((ObjectClass -eq 'user') -or (ObjectClass -eq 'contact') -or (ObjectClass -eq 'msExchSystemMailbox') -or (ObjectClass -eq 'msExchDynamicDistributionList') -or (ObjectClass -eq 'group') -or (ObjectClass -eq 'publicFolder'))) -and (WindowsEmailAddress -like "*@tailspintoys.com") )}
    • Create the following Address Lists
      • All TST Distribution Lists
      • New-AddressList -Name "All TST Distribution Lists" -RecipientFilter {((Alias -ne $null) -and (ObjectCategory -like 'group') -and (WindowsEmailAddress -like "*@tailspintoys.com"))}
      • All TST Rooms
      • New-AddressList -Name "All TST Rooms" -RecipientFilter {((Alias -ne $null) -and (((RecipientDisplayType -eq 'ConferenceRoomMailbox') -or (RecipientDisplayType -eq 'SyncedConferenceRoomMailbox'))) -and (WindowsEmailAddress -like "*@tailspintoys.com"))}
      • All TST Users
      • New-AddressList -Name "All TST Users" -RecipientFilter {((Alias -ne $null) -and (((((((ObjectCategory -like 'person') -and (ObjectClass -eq 'user') -and (-not(Database -ne $null)) -and (-not(ServerLegacyDN -ne $null)))) -or (((ObjectCategory -like 'person') -and (ObjectClass -eq 'user') -and (((Database -ne $null) -or (ServerLegacyDN -ne $null))))))) -and (-not(RecipientTypeDetailsValue -eq 'GroupMailbox')))) -and (WindowsEmailAddress -like "*@tailspintoys.com"))}
    • Create an Offline Address Book called¬†TST Offline Address Book¬†(this uses the Default Global Address List that we had just created)
    • New-OfflineAddressBook -Name "TST Offline Address Book" -AddressLists "Default TST Global Address List"
    • Create an Address Book Policy called¬†TST ABP
    • New-AddressBookPolicy -Name "TST ABP" -AddressLists "All Contacts", "All TST Distribution Lists", "All TST Users", ‚ÄúPublic Folders‚ÄĚ -RoomList "All TST Rooms" -OfflineAddressBook "TST Offline Address Book" -GlobalAddressList "Default TST Global Address List"
  • For WingTip Toys
    • Create a default Global Address List called¬†Default WTT Global Address List
    • New-GlobalAddressList -Name "Default WTT Global Address List" -RecipientFilter {((Alias -ne $null) -and (((ObjectClass -eq 'user') -or (ObjectClass -eq 'contact') -or (ObjectClass -eq 'msExchSystemMailbox') -or (ObjectClass -eq 'msExchDynamicDistributionList') -or (ObjectClass -eq 'group') -or (ObjectClass -eq 'publicFolder'))) -and (WindowsEmailAddress -like "*@wingtiptoys.com") )}
    • Create the following Address Lists
      • All WTT Distribution Lists
      • New-AddressList -Name "All WTT Distribution Lists" -RecipientFilter {((Alias -ne $null) -and (ObjectCategory -like 'group') -and (WindowsEmailAddress -like "*@wingtiptoys.com"))}
      • All WTT Rooms
      • New-AddressList -Name "All WTT Rooms" -RecipientFilter {((Alias -ne $null) -and (((RecipientDisplayType -eq 'ConferenceRoomMailbox') -or (RecipientDisplayType -eq 'SyncedConferenceRoomMailbox'))) -and (WindowsEmailAddress -like "*@wingtiptoys.com"))}
      • All WTT Users
      • New-AddressList -Name "All WTT Users" -RecipientFilter {((Alias -ne $null) -and (((((((ObjectCategory -like 'person') -and (ObjectClass -eq 'user') -and (-not(Database -ne $null)) -and (-not(ServerLegacyDN -ne $null)))) -or (((ObjectCategory -like 'person') -and (ObjectClass -eq 'user') -and (((Database -ne $null) -or (ServerLegacyDN -ne $null))))))) -and (-not(RecipientTypeDetailsValue -eq 'GroupMailbox')))) -and (WindowsEmailAddress -like "*@wingtiptoys.com"))}
    • Create an Offline Address Book called WTT Offline Address Book¬†(this uses the Default Global Address List that we had just created)
    • New-OfflineAddressBook -Name "WTT Offline Address Book" -AddressLists "Default WTT Global Address List"
    • Create an Address Book Policy called¬†WTT ABP
    • New-AddressBookPolicy -Name "WTT ABP" -AddressLists "All Contacts", "All WTT Distribution Lists", "All WTT Users" -RoomList "All WTT Rooms" -OfflineAddressBook "WTT Offline Address Book" -GlobalAddressList "Default WTT Global Address List"
  • Once you create all the Address Lists, after a few minutes, you will be able to see them using Outlook Client or Outlook Web Access. One of the obvious things you will notice is that they are all empty! If you are wondering if the recipient filter is correct or not, you can use the following to confirm the membership
  • Get-Recipient -RecipientPreviewFilter (Get -AddressList -Identity {your address list name here}).RecipientFilter

    Aha, you might say at this stage. I will just run the Update-AddressList cmdlet. Unfortunately, this won’t work since this cmdlet is only available for On-Premises Exchange Servers. There is none for Exchange Online. Hmm. How do I update my Address Lists ? Its not too difficult. All you have to do is change some attribute of the members and they will start popping into the Address List! For a hybrid setup, this means we will have to change the setting using On-Premise Exchange Server and use Azure Active Directory Connect Server to replicate the changes to Azure Active Directory, which in turn will update Exchange Online objects, thereby updating the newly created Address Lists. Simple? Yes. Lengthly? Yes indeed

  • I normally use CustomAttribute for such occasions. Before using any CustomAttribute, ensure it is not used by anything else. You might ¬† ¬†be able to ascertain this by checking if for all objects, that CustomAttribute currently holds any value or not. Lets assume CustomAttribute10 can be used.
    #Get all On-Premise Mailboxes
    $OnPrem_MBXs = Get-Mailbox -Resultsize unlimited
    
    #Get all Exchange Online Mailboxes
    $EXO_MBXs = Get-RemoteMailbox -Resultsize Unlimited
    
    #Get all the Distribution Groups
    $All_DL = Get-DistributionGroup -Resultsize unlimited
    
    #Update the CustomAttribute10 Value
    #Since Room mailboxes are a special type of Maibox, the following update will
    #address Room Mailboxes as well
    
    $OnPrem_MBXs | Set-Mailbox -CustomAttribute10 ‚ÄúGAL‚ÄĚ
    $EXO_MBXs | Set-RemoteMailbox -CustomAttribute10 ‚ÄúGAL‚ÄĚ
    
    $All_DL | Set-DistributionGroup -CustomAttribute10 ‚ÄúGAL‚ÄĚ
  • Using your Azure Active Directory Connect server run a synchronization cycle so that the updates are synchronized to Azure Active Directory and subsequently to Exchange Online
  • One Gotcha here is if you have any Distribution Groups that are not synchronised from OnPremises. You will have to find these and update their settings as well. One simple way to find them is to use the property¬†isDirSynced. Connect to Exchange Online using PowerShell and then use the following command
  • $All_NonDirsyncedDL = Get-DistributionGroup -Resultsize unlimited| ?{$_.isdirsynced -eq $FALSE}¬† ¬†
    
    #Now, we will update CustomAttribute10 (please check to ensure this customAttribute doesn't have any values)
     
    $All_NonDirSyncedDL | Set-DistributionGroup -CustomAttribute10 "GAL"
  • Check using Outlook Client or Outlook Address Book to see that the new Address Lists are now populated
  • Once confirmed that the new Address Lists have been populated, lets go assign the new Address Book Policies to TailSpin Toys and WingTip Toys users¬†It can take anywhere from 30min – 1hr for the Address Book Policy to take effect
  • $allUserMbx = Get-Mailbox -RecipientTypeDetails UserMailbox -Resultsize unlimited
    
    #assign "TST ABP" Address Book Policy to TailSpin Toys users
    
    $allUserMbx | ?{($_.primarysmtpaddress -like "*@tailspintoys.com")} | Set-Mailbox -AddressBooksPolicy ‚ÄúTST ABP‚ÄĚ
    
    #assign "WTT ABP" Address Book Policy to WingTip Toys users
    $allUserMbx | ?{($_.primarysmtpaddress -like "*@wingtiptoys.com")} | Set-Mailbox -AddressBooksPolicy ‚ÄúWTT ABP‚ÄĚ
  • While waiting, remove the CustomAttribute10 values you had populated. Using PowerShell on On-Premises Exchange Server, run the following
  • #Get all On-Premise Mailboxes
    
    $OnPrem_MBXs = Get-Mailbox -Resultsize unlimited
    
    #Get all Exchange Online Mailboxes
    
    $EXO_MBXs = Get-RemoteMailbox -Resultsize Unlimited
    
    #Get all the Distribution Groups
    
    $All_DL = Get-DistributionGroup -Resultsize unlimited
    
    #Set the CustomAttribute10 Value to null
    
    #Since Room mailboxes are a special type of Maibox, the following update will
    
    #address Room Mailboxes as well
    
    $OnPrem_MBXs | Set-Mailbox -CustomAttribute10 $null
    
    $EXO_MBXs | Set-RemoteMailbox -CustomAttribute10 $null
    
    $All_DL | Set-DistributionGroup -CustomAttribute10 $null
  • Connect to Exchange Online using PowerShell and remove the value that was set for CustomAttribute10 for nonDirSynced Distribution Groups
  • $All_NonDirsyncedDL = Get-DistributionGroup -Resultsize unlimited| ?{$_.isdirsynced -eq $FALSE}¬† ¬†
    
    #Change CustomAttribute10 to $null
    
    $All_NonDirSyncedDL | Set-DistributionGroup -CustomAttribute10 $null

     

    Thats it folks! Your GAL Segmentation is now complete! Users from TailSpin Toys will only see TailSpin Toys mail enabled objects and WingTip Toys users will only see WingTip Toys mail enabled objects

A few words of wisdom

In the above steps, I would advise that once the new Address Lists have been populated

  • apply the Address Book Policy to a few test mailboxes
  • wait between 30min – 1 hour, then confirm that the Address Book Policy has been successfully applied to the test mailboxes and has the desired result
  • once you have confirmed that the test mailboxes had the desired result for ABP, then and ONLY then continue to the rest of the mailboxes

This will give you confidence that the change will be successful. Also, if you find that there are issues, the rollback is not too difficult and time consuming.

Another thing to note is that when users have their Outlook client configured to use ¬†cached mode, they might notice that their new GAL is not fully populated. This is because their Outlook client uses the Offline Address Book to show the GAL and at that time, the Offline Address Book would not have regenerated to include all the new members. Unfortunately in Exchange Online, the Offline Address Book cannot be regenerated on-demand and we have to wait for the the Exchange Online servers to do this for us. I have noticed the regeneration happens twice in 24 hours, around 4am and 4pm AEST (your times might vary). So if users are complaining that their Outlook Client GAL doesn’t show all the users, confirm using Outlook Web Access that the members are there (or you can run Outlook in non-cached mode) and then advise the users that the issue will be resolved when the Offline Address Book gets re-generated (in approximately 12 hours). Also, once the Offline Address Book has regenerated, it is best for users to manually download the latest Offline Address Book, otherwise Outlook client will download it at a random time in the next 24 hours.

The next gotcha is around which Address Lists are available in Offline mode (refer to the screenshot below)

GAL01

When in Offline mode, the only list available is¬†Offline Global Address List¬†. This is the one that is pointed to by the ¬†green arrow. Note that the red arrow is pointing to Offline Global Address List as well however this is an “Address List” that has been named¬†Offline Global Address List by Microsoft to confuse people! To repeat, the Offline Global Address List pointed to by the green arrow is available in Offline mode however the one pointed to by red is not!

In our case, the Offline Global Address List is named Default TST Global Address List and Default WTT Global Address List).

If you try to access any others in the drop down list when in Offline mode, you will get the following error

AddressListError

This has always been the case, unfortunately hardly anyone tries to access all the Address Lists in Offline mode. However, after GAL Segmentation, if users receive the above error, it is very easy to blame the GAL Segmentation implementation ūüė¶ Rest assured, this is not the case and this “feature” has always been present.

Lastly, the user on-boarding steps will have to be modified to ensure that when their mailbox is created, the appropriate Address Book Policy is applied. This will ensure they only see the address lists that they are supposed to (on the flip side, if no address book policy is applied, they will see all address lists, which will cause a lot of confusion!)

With these words, I will now stop. I hope this blog comes in handy to anyone trying to implement GAL Segmentation.

If you have any more gotchas or things you can think of regarding GAL Segmentation, please leave them in the comments below.

Till the next time, Enjoy ūüėČ

 

 

 

Advertisements

Amazon QuickSight – An elegant and easy to use business analytics tool

Introduction

Recently, I had a requirement for a tool to visualise some data I had collected. My requirements were very simple. I didn’t want something that would cost me a lot, and at the same time I wanted the reports to be elegant and informative. Most of all, I didn’t want to have to go through pages and pages of documentation to learn how to use it.

As my data was within Amazon Web Services (AWS), I thought to check if AWS had any such offerings. Guess what, there was indeed a tool just for what I wanted, and after using it, I was amazed at how simple and elegant it is.

In this blog, I will show how you can easily get started with Amazon QuickSight. I will take you through the steps to import your data into Amazon QuickSight and then create some informative visualisations.

Some background on Amazon QuickSight

Pricing

Amazon QuickSight is very inexpensive, infact, if your data is not too much, you won’t have to pay anything!

For standard edition use, Amazon QuickSight provides 1GB of SPICE for the first user free per month. SPICE is an acronym for Super-fast, Parallel, In-memory, Calculation Engine and it uses a combination of columnar storage, in-memory technologies enabled through the latest hardware innovations, machine code generation, and data compression to allow users to run interactive queries on large datasets and get rapid responses.  SPICE is the calculation engine that Amazon QuickSight uses.

Any additional SPICE is priced at $USD0.25 per GB/month. For the latest pricing, please refer to https://aws.amazon.com/quicksight/#Pricing

Data Sources

Currently Amazon QuickSight supports the following data sources

  • Relational Data Sources
    • Amazon Athena
    • Amazon Aurora
    • Amazon Redshift
    • Amazon Redshift Spectrum
    • Amazon S3
    • Amazon S3 Analytics
    • Apache Spark 2.0 or later
    • Microsoft SQL Server 2012 or later
    • MySQL 5.1 or later
    • PostgreSQL 9.3.1 or later
    • Presto 0.167 or later
    • Snowflake
    • Teradata 14.0 or later
  • File Data Sources
    • CSV/TSV – (comma separated, tab separated value text files)
    • ELF/CLF – Extended and common log format files
    • JSON – Flat or semi-structured data files
    • XLSX – Microsoft Excel files

Unfortunately, currently Amazon DynamoDB is not supported as a native data source. Since my data is in Amazon DynamoDB, I had to write some custom lambda functions to export it to a csv file, so that it could be imported into Amazon QuickSight.

Ok, time for that walk-through I promised earlier.  For this blog, I will be using an S3 bucket as my data source. It will contain the CSV files that I will use for analysis in Amazon QuickSight.

Step 1 – Create S3 buckets

If you haven’t already done so, create an S3 bucket that will contain the csv files. The S3 bucket does not have to be publicly accessible. Once created, upload the csv files into the S3 bucket.

In my case, the csv file is called orders.csv and its location is https://s3.amazonaws.com/sample/orders.csv (to get the URL to your S3 file, login to the S3 console and navigate to the S3 bucket that contains the file. Click the S3 bucket to open it, then click the file name to open its properties. Under Overview you will see Link. This is the URL to the file)

Step 2 – Create an Amazon QuickSight Account

Before you start using Amazon QuickSight, you must create an account. Unfortunately, I couldn’t find a way for creating an Amazon QuickSight account without creating an Amazon AWS¬†account. If you don’t have an existing Amazon AWS account, you can create an AWS Free Tier account. Once you have got an AWS account, go ahead and create an Amazon QuickSight account at¬†https://aws.amazon.com/quicksight/.

While creating your Amazon QuickSight account, you will be asked if you would like Amazon QuickSight to auto-discover your Amazon S3 buckets. Enable this and then click to Choose S3 buckets. Choose the S3 bucket that you created in Step 1 above. This will give Amazon QuickSight read-only access to the S3 bucket, so that it can read the data for analysis.

Step 3 – Create a manifest file

A manifest file is a JSON file that provides the location and format of the data files to Amazon QuickSight. This is required when creating a data set for S3 data sources. Please refer to https://docs.aws.amazon.com/quicksight/latest/user/supported-manifest-file-format.html if you would like more information about manifest files.

Below is my manifest file, which I have affectionately named ordersmanifest.json.

{
   "fileLocations": [
      {
         "URIs": [
            "https://s3.amazonaws.com/sample/orders.csv"
         ]
      },
   ],
   "globalUploadSettings": {
      "format": "CSV",
      "delimiter": ",",
      "textqualifier": "'",
      "containsHeader": "true"
   }
}

Once created, upload the manifest file into the same S3 bucket as to where the csv file is stored.

Step 4 – Create a data set

  • Login to your Amazon QuickSight account. From the top right, click on¬†Manage data
  • In the next screen, click on¬†New data set
  • In the next screen, for Create a Data Set FROM NEW DATA SOURCES,¬†click on¬†S3
  • In the next screen
    • provide a name for the data source
    • for¬†Upload a manifest file ensure¬†URL is clicked and enter the URL to the manifest file (you can get the url by logging into the S3 console, and then clicking on the manifest file to reveal its properties. Under the¬†Overview tab, you will see¬†Link. This is the URL to the manifest file).NewS3DataSource
    • Click¬†Connect
    • Amazon QuickSight will now read the manifest file and then import the csv file to SPICE. You will see the following screenFinishDataSetCreation
    • Click on¬†Edit/Preview data.
    • In the next screen, you will see the contents of the data file that was imported, along with the¬†Fields¬†name on the left. If you want to exclude any columns from the analysis, simply untick them (I unticked orderTime (S)¬†since I didn’t need it)¬†EditPreviewDataSet
    • By default, the data is called¬†Group 1. To customise the name, replace¬†Group 1 with a text of your choice (I have renamed my data to¬†Orders Data)RenameGroup1Label
    • Click¬†Save & visualize from the top menu

Step 5 – Create Visualisations

Now that you have imported the data into SPICE, you can start analysing it and creating visualisations.

After step 4, you should be in the Analysis section.

  • Depending on which visualisation you want, you can select the respective type under¬†Visual types from the bottom left hand side of the screen. For my visualisations, I chose Pie Chart (side note¬†– you will notice that¬†orderTime (S)¬†¬†isn’t listed under¬†Fields list. This is¬†because we had¬†unticked it in the previous screen)OrdersDataAnalysis-01
  • I want to create two Pie Charts, one to show me analysis about what is the most popular foodName and another to find out what is the most popular drinkName. For the first Pie Chart, drag foodName¬†(S) from the Fields list to¬†the¬†Value – Add a measure here box¬† in the top of the screen. Then drag¬†foodName (S)¬†from the¬†Fields list to the¬†Group/Color – Add a dimension here box in the top of the screen. You will see the followingOrdersDataAnalysis-02
  • You can customise the visualisation title Count of Foodname (S) by Foodname (S)¬†by clicking it and then changing the text (I have changed the title to¬†Popularity of Food Types)FoodNamePopularity
  • If you look closely, the legend on the right hand side doesn’t serve much purpose since the pie slices are already labelled quite well. You can also get rid of the legend and get more space for your visual. To do this, click on the down arrow above¬†FoodName (S) on the right and then select¬†Hide legend¬†FoodNameHideLengend
  • Next, lets create a Pie Chart visualisation for drinkName. From the top menu, click on¬†Add and then¬†Add visual¬†drinkNameAddVisual
  • You will now have another Canvas at the bottom of the first Pie Chart. Click this new canvas area to select it (a blue border will appear to show that it is selected). From Visual types at the bottom left hand side, click on the Pie Chart visual. Then from the top, click on¬†Field wells to expose the¬†Value and¬†Group/Color boxes for the second canvas¬†drinkNameCanvas
  • From the Field list¬†on the left,¬†drag drinkName¬†(S) to¬†the¬†Value – Add a measure here box¬† in the top of the screen. Then drag¬†drinkName (S)¬†from the¬†Fields list to the¬†Group/Color – Add a dimension here box in the top of the screen. You will now see the following¬†foodanddrinkvisual
  • We are almost done. I actually want the two Pie Charts to sit side by side, instead of one ontop ofthe other. To do this, I will show you a neat trick. In each of the visuals, at the bottom right border, you will see two diagonal lines. If you move your mouse pointer over them, they change to a resizing cursor. Use this to resize the visual’s canvas area. Also, in the middle of the top border of the visual, you will see two rows of gray dots. Click your mouse pointer on this and drag to the location you want to move the visual to.VisualResizeandMove
  • I have hidden the legend for the second visual, customised the title and resized both the visuals and moved them side by side. Viola! Below is what I get.¬†Not bad aye!BothVisualsSidebySide

Step 6 – Create a dashboard

Now that the visuals have been created, they can be shared it with others. This can be done by creating a dashboard. A dashboard is a read-only snapshot of the analysis. When you share the dashboard with others, they can view and filter the dashboard data, however any filters applied to the dashboard visual exist only when the user is viewing the dashboard, and aren’t saved once it is closed.

One thing to note about sharing dashboards – you can only share dashboards with users who have an Amazon QuickSight account.

Creating a dashboard is very easy.

  • In the Analysis screen, on the top right corner, click on¬†Share and then select¬†Create dashboardCreateDashboard
  • You can either replace an existing dashboard or create a new one. In our case, since we are creating a new dashboard, select¬†Create a new dashboard as and enter a name for the dashboard. Once finished, click¬†Create dashboardCreateDashboard-Name
  • You will then be asked to enter the username or email address of those you want to share the dashboard with. Enter this and click on¬†Share¬†ShareDashboard
  • That’s it, your dashboard is now created. To access it, go to the Amazon QuickSight home screen (click on the Amazon QuickSight icon on the top left hand side of the screen) and then click on¬†All dashboards. Those that you have shared the dashboard with will also be able to see it once they login to their Amazon QuickSight account.AllDashboards

Step 6 – Refreshing the Data Set

If your data set continually changes, your visualisations/dashboards will not show the updated information. This can be done by refreshing the data set. Doing this will import the new data into SPICE, which will then automatically update the analysis/visualisations and dashboards

Note: you will have to manually reload the webpage to see the updated visualisations and dashboard

There are two ways of refreshing data sets. One is to do it manually while the other is to use a schedule. The scheduled data refresh allows for the data to be automatically refreshed at a certain time daily, weekly or monthly. A maximum of five scheduled refreshes can be configured.

The steps below show how you can manually refresh the data or create schedules to refresh the data

  • From the Amazon QuickSight main screen, click on¬†Manage data from the top left of the screen¬†ManageData
  • In the next screen, you will see all your currently configured data sets. Click the¬†Orders Data dataset (this is the one we had created previously).
  • In the next screen, you will see¬†Refresh Now and¬†Schedule refreshManualScheduleDataRefresh
  • Clicking on¬†Refresh Now will manually refresh the data. Clicking on¬†Schedule refresh will bring up the screen where you can configure a schedule for refreshing the data automatically.

 

That’s it folks! Wasn’t that simple? If you already have an Amazon AWS account, I would strongly recommend giving Amazon QuickSight¬†a try for all your analytics needs. Even if you don’t have an Amazon AWS account, I would still suggest getting an AWS free tier account to try it out.

Enjoy ūüėČ

 

Using Microsoft Identity Manager Synchronisation Server’s Global Address List Synchronisation feature to create a shared global address book across three Exchange Forests

Introduction

Over the life of a company, there can be many acquisitions and mergers. During such events, the parent and the newly acquired entities have their IT “merged”. This allows for the removal of redundant systems and the reduction of expenses. It also fosters collaboration between the two entities. Unfortunately, the marriage of the two IT systems, can at times, take a long time.

To enable a more collaborative space between the parent and the newly acquired company, a shared “global address book” can be created, which will allow employees to quickly look up each others contact details easily.

In this blog, I will show how we can use Microsoft Identity Manager (MIM) 2016 Synchronisation Server’s ¬†GALSync feature to extend the Global Address Book (GAL) of three Exchange Forests. The GAL will be populated with contacts corresponding to ¬†mailboxes in the other Exchange Forests, and this will be automatically maintained, to ensure the contacts remain up-to-date.

Though this blog focuses on three Exchange Forests, it can easily be adapted for two Exchange Forests, if you remove all reference to the third AD Forest, AD Domain and Exchange Forest

For reference, we will be using the following:

Name: Contoso Limited (parent company)
Active Directory Forest: contoso.com
Active Directory Domain: contoso.com
Active Directory Forest Level: Windows Server 2008 R2
Exchange Server FQDN: CEX01.contoso.com
Exchange Server Version: Exchange 2010 SP3
Email Address Space owned: contoso.com, contoso.com.au
Number of employees: 2000

Name: Northwind Traders (newly acquired)
Active Directory Forest: northwind.com
Active Directory Domain: northwind.com
Active Directory Forest Level: Windows Server 2008 R2
Exchange Server FQDN: NWEX01.northwind.com
Exchange Server Version: Exchange 2010 SP3
Email Address Space owned: northwind.com, northwind.com.au
Number of employees: 400

Name: WingTip Toys (newly acquired)
Active Directory Forest: wingtiptoys.com
Active Directory Domain: wingtiptoys.com
Active Directory Forest Level: Windows Server 2008 R2
Exchange Server FQDN: WTTEX01.wingtiptoys.com
Exchange Server Version: Exchange 2010 SP3
Email Address Space owned: wingtiptoys.com, wingtiptoys.com.au
Number of employees: 600

 

Contoso, Northwind and WingTip Toys are connected using a wide area network and it has been decided that the MIM Synchronisation Server will be installed and configured in the the Contoso domain.

Preparation

Before we start, some preparation work has to be done to ensure there are no roadblocks or issues.

  • Cleanup of “inter forest” email objects
    • This is one of the most important things that must be done and I can’t stress this enough. You will have to go through all your email objects (mailboxes, contacts, mailuser objects) in each of the three Exchange Forests (Contoso, Northwind, WingTip Toys) and find any that are forwarding to the other Exchange forests. If there are any, these must be removed. GALSync will create email enabled contacts corresponding to the mailboxes in the other Exchange Forests, with ¬†externalemailaddress¬†of these new objects set to the primary email address of the other Exchange Forest’s objects. If duplicates arise because there were existing objects in the local Exchange Forest corresponding to the other Exchange Forest’s objects, this will cause the local Exchange Server to get confused and it will keep on queuing emails for these objects and will not deliver them [if after implementing GALSync, some users complain about not receiving emails from a certain Exchange Forest, this could be a possible reason]
  • Creation of Organisational Units (OU) that will be used by GALSync
    • Create the following Organisational Units in the three Active Directory domains
      • contoso.com\GALSync\LocalForest\Contacts
      • contoso.com\GALSync\RemoteForest\Contacts
      • northwind.com\GALSync\LocalForest\Contacts
      • northwind.com\GALSync\RemoteForest\Contacts
      • wingtiptoys.com\GALSync\LocalForest\Contacts
      • wingtiptoys.com\GALSync\RemoteForest\Contacts
  • Service Accounts
    • The following service accounts must be created in the specified Active Directory domains. You can change the name to comply with your own naming standards
      • MIM Synchronisation Server Service Account
        • UPN: svc-mimsync@contoso.com
        • AD Domain to create in: contoso.com
        • Permissions: non-privileged Active Directory service account
      • Management Agent Account to connect to Contoso.com AD Domain
        • UPN: svc-mimadma@contoso.com
        • AD Domain to create in: contoso.com
        • Permissions
          • non-privilged Active Directory service account
          • Grant “Replicating Directory Changes” permission
          • Grant the following permissions on the GALSync OU in the Contoso AD Domain that was created above. Ensure the permissions propagate to all sub-OUs within the GALSync OU
            • Create Contact Objects
            • Delete Contact Objects
            • Read all Properties
            • Write all Properties
          • Add to the Exchange¬†Organization Management Active Directory security group in Contoso AD Domain
      • Management Agent Account to connect to Northwind.com AD Domain
        • UPN: svc-mimadma@northwind.com
        • AD Domain to create in: nothwind.com
        • Permissions
          • non-privilged Active Directory service account
          • Grant “Replicating Directory Changes” permission
          • Grant the following permissions on the GALSync OU in the Northwind AD Domain that was created above. Ensure the permissions propagate to all sub-OUs within GALSync OU
            • Create Contact Objects
            • Delete Contact Objects
            • Read all Properties
            • Write all Properties
          • Add to the Exchange¬†Organization Management Active Directory security group in Northwind AD Domain
      • Management Agent Account to connect to WingTiptoys.com AD Domain
        • UPN: svc-mimadma@wingtiptoys.com
        • AD Domain to create in: wingtiptoys.com
        • Permissions
          • non-privilged Active Directory service account
          • Grant “Replicating Directory Changes” permission
          • Grant the following permissions on the GALSync OU in the WingTipToys AD Domain that was created above. Ensure the permissions propagate to all sub-OUs within GALSync OU
            • Create Contact Objects
            • Delete Contact Objects
            • Read all Properties
            • Write all Properties
          • Add to the Exchange¬†Organization Management Active Directory security group in Northwind AD Domain
      • Service account used for the scheduled task job that will run the MIM RunProfiles script on the MIM Synchronisation Server
        • UPN: svc-mimscheduler@contoso.com
        • AD Domain to create in: Contoso.com (this can also be a local account on the MIM Synchronisation Server)
        • Permissions
          • non-privileged Active Directory service account
          • Grant “Log on as a batch job” user right on the MIM Synchronisation Server
          • Add to FIMSyncOperators security group on the MIM Synchronisation Server (this security group is created locally on the MIM Synchronisation Server after MIM Synchronisation Server has been installed)
  • SQL Server Permissions
    • MIM Synchronisation Server requires a Microsoft SQL Server to host its database. On the SQL Server, grant SQL SYSADMIN role to the account that you will be logged on as when installing MIM Synchronisation Server

Configuration

Provision a Microsoft Windows Server 2012 R2 in the Contoso.com Active Directory domain and install MIM 2016 Synchronisation Server. During installation, specify svc-mimsync@contoso.com as the account under which the MIM Synchronisation Service will run.

One thing to note is that GALSync will update the proxyaddress field for all mailboxes in its scope (mailboxes for which it will be creating contacts in the other Exchange Forests) with X500 entries.

Management Agent Configuration

  1. Once the MIM Synchronisation Server has been successfully installed, use the following steps to create the GALSync Management Agents. Open the Synchronisation Service Manager
    • Create GALSync Management Agent for Contoso.com AD Forest
      • From Tools¬†menu, click¬†Management Agents and then click¬†Create
      • ¬†In the¬†Management Agent drop-down list, click¬†Active Directory global address list (GAL)¬†
      • In the name type¬†GALSyncMA for Contoso.com
      • On the¬†Connect to an Active Directory Forest¬†page, type the forest name, the MIM MA account details (svc-mimadma@contoso.com) and the domain name
      • In the next screen, specify the OUs that GALSync will query to find mailboxes to create contacts for in the other forests. Also, place a tick beside contoso.com\GALSync¬†(this selects GALSync and all sub-OUs)
      • In the Containers screen, for
        • Target Container select Contoso.com\GALSync\RemoteForest\Contactsthis is the OU where MIM GALSync will create contacts corresponding to the mailboxes in Northwind and WingTipToys Exchange Forest
        • Source Container select Contoso.com\GALSync\LocalForest\Contactsthis is where MIM GALSync will create contacts corresponding to Contoso.com mailboxes. These will be sent to the GALSync/RemoteForest/Contacts OU in Northwind and WingTipToys AD Domain (personally, I haven’t seen any objects created in this OU)
      • In¬†Exchange Configuration¬†click¬†Edit and enter all the email suffixes that belong to Contoso.com. The email suffixes listed here are used to filter out which email addresses from the original email object are added to the corresponding contact in the other Exchange Forests. In this case the email suffixes will be @contoso.com and @contoso.com.au. Note the @ before the email suffix)
      • Leave everything else as default and proceed to the Configure Extensions¬†section.¬†One thing I would like to mention here is that in¬†Configure Connection Filter¬†section, the¬†Filter Type for¬†user¬†is supposed to be¬†Declared¬†(and is the default setting), not¬†Rules extension as stated in¬†https://technet.microsoft.com/en-us/library/cc708642(v=ws.10).aspx
      • In the¬†Configure Extensions section, set the following
      • Click¬†OK
    • Create GALSync Management Agent for Northwind.com AD Forest
      • From Tools¬†menu, click¬†Management Agents and then click¬†Create
      • ¬†In the¬†Management Agent drop-down list, click¬†Active Directory global address list (GAL)¬†
      • In the name type¬†GALSyncMA for Northwind.com
      • On the¬†Connect to an Active Directory Forest¬†page, type the forest name, the MIM MA account details (svc-mimadma@northwind.com) and the domain name
      • In the next screen, specify the OUs that GALSync will query to find mailboxes to create contacts for in the other forests. Also, place a tick beside northwind.com\GALSync¬†(this selects GALSync and all sub-OUs)
      • In the Containers screen, for
        • Target Container select Northwind.com\GALSync\RemoteForest\Contactsthis is the OU where MIM GALSync will create contacts corresponding to the mailboxes in Contoso and WingTipToys Exchange Forest
        • Source Container select Northwind.com\GALSync\LocalForest\Contactsthis is where MIM GALSync will create contacts corresponding to Northwind.com mailboxes. These will be sent to the GALSync/RemoteForest/Contacts OU in Contoso and WingTipToys AD Domain (personally, I haven’t seen any objects created in this OU)
      • In¬†Exchange Configuration¬†click¬†Edit and enter all the email suffixes that belong to Northwind.com. The email suffixes listed here are used to filter out which email addresses from the original email object are added to the corresponding contact in the other Exchange Forests. In this case the email suffixes will be @northwind.com and @northwind.com.au. Note the @ before the email suffix)
      • Leave everything else as default and proceed to the Configure Extensions¬†section.¬†One thing I would like to mention here is that in¬†Configure Connection Filter¬†section, the¬†Filter Type for¬†user¬†is supposed to be¬†Declared¬†(and is the default setting), not¬†Rules extension as stated in¬†https://technet.microsoft.com/en-us/library/cc708642(v=ws.10).aspx
      • In the¬†Configure Extensions section, set the following
      • Click¬†OK
    • Create GALSync Management Agent for WingTipToys.com AD Forest
      • From Tools¬†menu, click¬†Management Agents and then click¬†Create
      • ¬†In the¬†Management Agent drop-down list, click¬†Active Directory global address list (GAL)¬†
      • In the name type¬†GALSyncMA for WingTipToys.com
      • On the¬†Connect to an Active Directory Forest¬†page, type the forest name, the MIM MA account details (svc-mimadma@wingtiptoys.com) and the domain name
      • In the next screen, specify the OUs that GALSync will query to find mailboxes to create contacts for in the other forests. Also, place a tick beside wingtiptoys.com\GALSync¬†(this selects GALSync and all sub-OUs)
      • In the Containers screen, for
        • Target Container select WingTipToys.com\GALSync\RemoteForest\Contactsthis is the OU where MIM GALSync will create contacts corresponding to the mailboxes in Contoso and Northwind Exchange Forest
        • Source Container select WIngTipToys.com\GALSync\LocalForest\Contactsthis is where MIM GALSync will create contacts corresponding to WingTipToys.com mailboxes. These will be sent to the GALSync/RemoteForest/Contacts OU in Contoso and Northwind AD Domain (personally, I haven’t seen any objects created in this OU)
      • In¬†Exchange Configuration¬†click¬†Edit and enter all the email suffixes that belong to WingTipToys.com. The email suffixes listed here are used to filter out which email addresses from the original email object are added to the corresponding contact in the other Exchange Forests. In this case the email suffixes will be @wingtiptoys.com and @wingtiptoys.com.au. Note the @ before the email suffix)
      • Leave everything else as default and proceed to the Configure Extensions¬†section.¬†One thing I would like to mention here is that in¬†Configure Connection Filter¬†section, the¬†Filter Type for¬†user¬†is supposed to be¬†Declared¬†(and is the default setting), not¬†Rules extension as stated in¬†https://technet.microsoft.com/en-us/library/cc708642(v=ws.10).aspx
      • In the¬†Configure Extensions section, set the following
      • Click¬†OK
  2. Enable provisioning by using the following steps
    • In the Synchronisation Service Manager, from¬†Tools¬†select¬†Options
    • Under Metaverse Rules Extensions¬†ensure the following have been ticked
      • Enable metaverse rules extensions
      • Enable Provisioning Rules Extension

Run Profiles Execution Order

Congratulations! All configuration has now been completed. All we have to do now is to run the synchronisation jobs to get the mailbox object information from the three AD Forests into the MIM metaverse, let MIM GALSync do a bit of processing to find out which contacts are to be created in the other Exchange Forests, and then carry out an export, to create those contacts in the other Exchange Forests. Unfortunately, MIM has no way of finding out if the exports were successful, and that is why we will have to do a confirming import on all the management agents, so that MIM can find out if everything had been exported as expected.

From my testing, I have found that when MIM GALSync does its processing, it compares the mailboxes that an Exchange Forest has with what is in the MIM metaverse. MIM then exports out, as contacts, all objects that are in the metaverse but not in that particular Exchange Forest. These are populated in that AD Domains GALSync/RemoteForest/Contacts OU as AD objects and subsequently mail enabled using the Exchange RPS URI (remote PowerShell url)

CAUTION! Before you continue, you need to find out if a synchronisation solution had previously been deployed in the environment.

If any of the AD Forests had previously had a synchronisation solution deployed, then we will need to follow the run profile execution order mentioned below. This is done to ensure no duplicate contacts are created during the initial GAL synchronisation.

  1. Full Import (Staging Only) on GALSyncMA for Contoso.com
  2. Full Import (Staging Only) on GALSyncMA for Northwind.com
  3. Full Import (Staging Only) on GALSyncMA for WingTipToys.com
  4. Delta Synchronisation on GALSyncMA for Contoso.com
  5. Delta Synchronisation on GALSyncMA for Northwind.com
  6. Delta Synchronisation on GALSyncMA for WingTipToys.com
  7. Repeat Delta Synchronisation on GALSyncMA for Contoso.com
  8. Repeat Delta Synchronisation on GALSyncMA for Northwind.com
  9. Repeat Delta Synchronisation on GALSyncMA for WingTipToys.com
  10. Export on GALSyncMA for Contoso.com
  11. Export on GALSyncMA for Northwind.com
  12. Export on GALSyncMA for WingTipToys.com
  13. Delta Import on GALSyncMA for Contoso.com
  14. Delta Import on GALSyncMA for Northwind.com
  15. Delta Import on GALSyncMA for WingTipToys.com

 

If there hasn’t been any previous synchronisation solutions deployed in any of the AD Forests, then use the following runprofile order for the initial run

  1. Full Import (Staging Only) on GALSyncMA for Contoso.com
  2. Full Import (Staging Only) on GALSyncMA for Northwind.com
  3. Full Import (Staging Only) on GALSyncMA for WingTipToys.com
  4. Full Synchronisation on GALSyncMA for Contoso.com
  5. Full Synchronisation on GALSyncMA for Northwind.com
  6. Full Synchronisation on GALSyncMA for WingTipToys.com
  7. Export on GALSyncMA for Contoso.com
  8. Export on GALSyncMA for Northwind.com
  9. Export on GALSyncMA for WingTipToys.com
  10. Delta Import on GALSyncMA for Contoso.com
  11. Delta Import on GALSyncMA for Northwind.com
  12. Delta Import on GALSyncMA for WingTipToys.com

 

Once the initial synchronisation has completed, you will see contacts in each AD Domain’s GALSync\RemoteForest\Contacts OU corresponding to mailboxes in the other two Exchange Forests. These will have been email enabled and will show in the Exchange console and the online Global Address List.

Outlook clients that use offline address books won’t see the new contacts until the offline address book generation process has run on the Exchange servers and the updated offline address book has been downloaded by the outlook client.

To ensure the GALSync generated contacts remain up-to-date, the following runprofile execution order must be used from hereon. This should be repeated every 1 hour (or as per your required interval. Keep in mind that if after one cycle of the following order, if anything is still pending an Export, then this will be run at the next runprofile execution, so changes might not be seen for at most two runcycle intervals)

  1. Delta Import (Staging Only) on GALSyncMA for Contoso.com
  2. Delta Import (Staging Only) on GALSyncMA for Northwind.com
  3. Delta Import (Staging Only) on GALSyncMA for WingTipToys.com
  4. Delta Synchronisation on GALSyncMA for Contoso.com
  5. Delta Synchronisation on GALSyncMA for Northwind.com
  6. Delta Synchronisation on GALSyncMA for WingTipToys.com
  7. Export on GALSyncMA for Contoso.com
  8. Export on GALSyncMA for Northwind.com
  9. Export on GALSyncMA for WingTipToys.com
  10. Delta Import on GALSyncMA for Contoso.com
  11. Delta Import on GALSyncMA for Northwind.com
  12. Delta Import on GALSyncMA for WingTipToys.com

I don’t imagine anyone would want to run the runprofiles¬†manually every hour ūüėČ So below is a script that can be used to do it.

Export all the runprofiles using the Synchronisation Service Manager as vbs scripts and place them in a folder c:\scripts\runprofiles on the MIM Synchronisation Server.

Copy the below script and save it as GALSync_RunProfiles.cmd in c:\scripts

@echo off
REM This script will run the MIM RunProfiles in the correct order
REM Author nivleshc@yahoo.com

set _script_dir="c:\scripts\runprofiles\"

REM Delta Import (Stage Only)
echo ContosoGALSyncMA Delta Import -StageOnly
CSCRIPT //B %_script_dir%ContosoGALSyncMA_Delta_Import_StageOnly.vbs

echo NorthwindGALSyncMA Delta Import -StageOnly
CSCRIPT //B %_script_dir%NorthwindGALSyncMA_Delta_Import_StageOnly.vbs

echo WingTipToysGAlSyncMA Delta Import -StageOnly
CSCRIPT //B %_script_dir%WingTipToysGAlSyncMA_Delta_Import_StageOnly.vbs

REM Delta Sync
echo ContosoGALSyncMA Delta Sync
CSCRIPT //B %_script_dir%ContosoGALSyncMA_Delta_Sync.vbs

echo NorthwindGALSyncMA Delta Sync
CSCRIPT //B %_script_dir%NorthwindGALSyncMA_Delta_Sync.vbs

echo WingTipToysGAlSyncMA Delta Sync
CSCRIPT //B %_script_dir%WingTipToysGAlSyncMA_Delta_Sync.vbs

REM Export
echo ContosoGALSyncMA Export
CSCRIPT //B %_script_dir%ContosoGALSyncMA_Export.vbs

echo NorthwindGALSyncMA Export
CSCRIPT //B %_script_dir%NorthwindGALSyncMA_Export.vbs

echo WingTipToysGAlSyncMA Export
CSCRIPT //B %_script_dir%WingTipToysGAlSyncMA_Export.vbs

REM Delta Import
echo ContosoGALSyncMA Delta Import
CSCRIPT //B %_script_dir%ContosoGALSyncMA_Delta_Import.vbs

echo NorthwindGALSyncMA Delta Import
CSCRIPT //B %_script_dir%NorthwindGALSyncMA_Delta_Import.vbs

echo WingTipToysGAlSyncMA Delta Import
CSCRIPT //B %_script_dir%WingTipToysGAlSyncMA_Delta_Import.vbs

 

Create a scheduled task on the MIM Synchronisation Server to run GALSync_RunProfiles.cmd script every 1 hour (or for an interval of your choice). Use the task scheduler account that had been created during the preparation stage to run this scheduled task.

Some Gotchas

I have found that sometimes some mailboxes fail to be imported into the MIM Metaverse and report an mv-constraing-restriction violation on the msExchSafeSenderHash attribute. This error occurs because the AD attribute msExchSafeSenderHash is much longer than what the corresponding MIM Metaverse attribute is. Since this attribute is not being used to create the contacts in the other Exchange Forests, it can be dropped from the attribute flow.

Use the steps outlined in the following article to resolve this issue. https://social.technet.microsoft.com/wiki/contents/articles/10733.troubleshooting-galsync-mv-constraint-violation-msexchsafesenderhash.aspx

 

I hope this blog helps those that might be wanting to create a shared “global address book” among multiple Exchange Forests.

As mentioned previous, the above steps can be used to create a ¬†shared “global address book” for two Exchange Forests as well. In that case, just remove any mention of the third AD Forest, AD Domain and Exchange Forest from the above mentioned steps.

Enjoy ūüėČ

 

Moving an Office 365 domain to a new tenant

There are times when companies acquire other companies to increase their portfolio. When this happens, the acquired company’s IT infrastructure normally gets merged with the parent company. The opposite of this situation is also true. There are also times when a company sells off one of its acquired companies or divisions. In this scenario, the company that is being sold off must have all its IT infrastructure separated from the parent company.

In this blog I will show the steps that can be used to separate a previously acquired company’s email system from its parent company, after the child company has been sold off.

Background

To provide some context, let me provide some details for the parent company and the child company that is being sold off

  • The parent company is called Tail Spin Toys and owns the domain name tailspintoys.com
  • Tail Spin Toys have their own Active Directory Forest called tailspintoys.com and this is synchronised to Azure Active Directory using Azure Active Directory Connect (AADC) server.
  • Tail Spin Toys has a hybrid Exchange Online setup. Their Office 365 tenant is called¬†tailspintoys and has the tenant address of¬†tailspintoys.onmicrosoft.com
  • Tail Spin Toys users have their userprincipalname and primary email address in the form of firstname.lastname@tailspintoys.com
  • The previously acquired company (referred to as child company in this blog) is trading as Wing Tip Toys and owns the domain name wingtiptoys.com. This domain has been added to Tail Spin Toys Office 365 tenant as an additional domain.
  • Wing Tip Toys have their own Active Directory Forest called wingtiptoys.net and all their users, computers and servers are part of this Active Directory Forest.
  • Wing Tip Toys users have their mailboxes provisioned in Tail Spin Toys Office 365 tenant (the process will be explained in the next bullet point). Wing Tip Toys only use email services in Office 365.
  • Each Wing Tip Toys user has two identities. The first is in the wingtiptoys.net Active Directory Domain, which is used to login to their computers and to access their local resources (fileshares, printers etc).
  • The other identity is a user object created in Tail Spin Toys Active Directory Domain. This is used to provision a mailbox in Tail Spin Toys Office 365 tenant. Unfortunately, for Wing Tip Toys users, their Office 365 experience is not very elegant since their userprincipalname¬†for Office 365 is of the form firstname.lastname@tailspintoys.com but their primary email address is of the form firstname.lastname@wingtiptoys.com. The users login to their computers using the wingtiptoys.net samaccountname. However, all users are aware of this and it doesn’t affect them too much.
  • To ensure users are not burdened with having to manage both the user object passwords,¬†Password Change Notification System¬†has been implemented. This replicates any password changes in the wingtiptoys.net Active Directory domain to the respective user object in tailspintoys.com Active Directory domain.

Requirement

Now that Wing Tip Toys has been sold off, all of its data must be separated from Tail Spin Toys. The following will be done for its emails.

  • A new Office 365 tenant will be provisioned for Wing Tip Toys
  • All mailbox data will be migrated to the new Office 365 tenant
  • Once all mailbox data has been migrated, after a few weeks, the Wing Tip Toys mailboxes in Tail Spin Toys Office 365 tenant will be disabled (or deleted)

Migration Plan

Ok, lets get started.

  • Due to the small size of Wing Tip Toys, it has been decided to use a Cloud-Only Office 365 Deployment. ( details on how to configure a Cloud-Only Office 365 deployment can be found¬†here¬†) however a hybrid Exchange Online environment will still work with the following steps ( a few extra steps will have to be added)
  • BitTitan MigrationWiz¬†will be used to copy the mailbox data from Tail Spin Toys Office 365 tenant to Wing Tip Toys Office 365 tenant

Here are the steps

  1. Add an additional UPN suffix (wingtiptoys.com) to the Wing Tip Toys Active Directory Domain
  2. Configure all Wing Tip Toys users in the wingtiptoys.net domain to have a userprincipalname of the form firstname.lastname@wingtiptoys.com
  3. For all the Wing Tip Toys users in the Tail Spin Toys Office 365 tenant, export their email addresses (we are after the proxyaddresses). Ensure the X500 addresses are also exported.
  4. In the wingtiptoys.net Active Directory domain, for each user, find their email addresses from the export that was done in step 3 and import it into the¬†proxyaddresses¬†attribute of their Active Directory user object. Ensure only email addresses for the domain wingtiptoys.com are imported (if you import any email address for which the domain hasn’t been added to wingtiptoys Office 365 tenant, these will display as the default Office 365 tenant address [@wingtiptoys.onmicrosoft.com] instead of the actual email address). Also, make sure the X500: addresses are also imported. Check to ensure the proxyaddress firstname.lastname@wingtiptoys.com is prefixed with an uppercase¬†SMTP:. This will make it the primary smtp address
  5. Create a new Office 365 tenant for Wing Tip Toys. For simplicity, we will assume that the tenant name is wingtiptoys and the tenant address is wingtiptoys.onmicrosoft.com. Since the domain wingtiptoys.com is already attached to the Tail Spin Toys Office 365 tenant, we won’t be able to attach it to the new tenant just yet.
  6. Install Azure Active Directory Connect (AADC) Server and configure it to synchronise objects from the wingtiptoys.net Active Directory domain to the Wing Tip Toys Azure AD. For Single Sign On, we will enable AADC server for password hash synchronisation however Active Directory Federation Services (ADFS) servers can also be used.
  7. If required, configure the transport rules in Wing Tip Toys Office 365 tenant to match those in Tail Spin Toys Office 365 tenant. For example, to apply disclaimers to all outgoing emails.
  8. Export configuration of all Distribution groups in Tail Spin Toys Office 365 tenant that belong to Wing Tip Toys.
  9. Create a user in Tail Spin Toys Office 365 tenant with the upn migrationwiz@tailspintoys.onmicrosoft.com. For all Wing Tip Toys mailboxes in Tail Spin Toys Office 365 tenant, give migrationwiz@tailspintoys.onmicrosoft.com full mailbox access. This account will be used by Bittitan MigrationWiz.
  10. Create a user in Wing Tip Toys Office 365 tenant with the upn migrationwiz@wingtiptoys.onmicrosoft.com and give it Global Administrator access. This account will be used by Bittitan MigrationWiz.
  11. Provision Office 365 licenses (at least Exchange Online Plan 2) to all user objects in Wing Tip Toys Office 365 tenant that have been synchronised from the on-premise Active Directory domain. This will create mailboxes for them. At this stage, they will only have the email address firstname.lastname@wingtiptoys.onmicrosoft.com (this is because the domain wingtiptoys.com hasn’t been added to this tenant).
  12. Create an account at Bittitan and purchase licenses for MigrationWiz. One license is required for one mailbox data migration, so purchase the required number of licenses ( when you create an account, you are provided with 3 trial licenses. You can use these to test out the migration process).
  13. Use the steps listed at https://help.bittitan.com/hc/en-us/articles/115008106827-Office-365-to-Office-365-Migration-Guide-While-Keeping-the-Same-Domain-Name to configure Bittitan MigrationWiz. The source and destination mailboxes within MigrationWiz must be specified using the Office 365 tenant address, for example in our case, the source mailboxes will be firstname.lastname@tailspintoys.onmicrosoft.com and the destination mailboxes will be firstname.lastname@wingtiptoys.onmicrosoft.com
  14. Pre-Stage the mailbox data for the Wing Tip Toys mailboxes by using MigrationWiz to copy everything except the last 20 days of data from the Tail Spin Toys Office 365 tenant to the Wing Tip Toys Office 365 tenant mailboxes (the more data you pre-stage, the faster the cut-over will be).
  15. Add wingtiptoys.com domain to the Wing Tip Toys Office 365 tenant. You will get a TXT record, which must be used to create a DNS entry in wingtiptoys.com domain, to prove domain owership. Create the DNS record and have the TTL set to 300s (5min). You won’t be able to verify the domain in Wing Tip Toys Office 365 tenant as it is currently attached to the Tail Spin Toys Office 365 tenant.
  16. Change the TTL for the MX DNS entry for wingtiptoys.com to 300s (5min). Make a note of the existing MX entries.
  17. At this stage, all the preparation has been done and we are ready for the cut-over. I would suggest planning the cutover out of office hours, preferably on a Friday evening. Send out user communications at least a week prior to cut-over so that everyone is aware of the change. In the communications, ensure you state that users will not be able to receive new emails in their Mobile and Outlook clients until it has been reconfigured to use the new Office 365 tenant. Provide instructions on how users can reconfigure their Outlook and Mobile clients and also provide the Outlook Web App address (this would be similar to https://outlook.office.com/wingtiptoys.com/ )
  18. Twenty minutes prior to cut-over time, change the MX for wingtiptoys.com to invalid.outlook.com. Setting the MX record to an invalid domain just ahead of the migration causes the sender’s email server to queue the emails and retry later. This will reduce the possibility of Office 365 sending a “recipient not found” Non Delivery Receipt if the email is received for a Wing Tip Toys user after the wingtiptoys.com domain has been removed from the Tail Spin Toys Office 365 tenant but hasn’t been added to the Wing Tip Toys Office 365 tenant.
  19. At cut-over time, remove the domain wingtiptoys.com from Tail Spin Toys Office 365 tenant. A message will be displayed stating that user logins and email addresses will need to be reconfigured. It will also state that the automatic domain removal process will change them to the default domain (tailspintoys.com) and that they will no longer receive emails at wingtiptoys.com. Click Remove. The time taken to remove the domain depends on the amount of mailboxes that have to be reconfigured to use the tenant email address.
  20. Add wingtiptoys.com to the Wing Tip Toys Office 365 tenant. If you receive an error stating that the domain is already attached to another Office 365 tenant, wait for a few minutes and then try again.
  21. Run a Full Synchronisation using Azure Active Directory Connect server and wait for it to complete. Confirm that the userprincipalname and primary smtp address for the users in the Wing Tip Toys Office 365 tenant has now changed to the format firstname.lastname@wingtiptoys.com.
  22. Change the MX for wingtiptoys.com to the value shown in the Wing Tip Toys Office 365 Portal under Domain Settings.
  23. Run a full migration using MigrationWiz so that the remaining mailbox data is copied across.
  24. Create a DNS entry in the internal and external DNS server for autodiscover.wingtiptoys.com. The value for this is shown in the Wing Tip Toys Office 365 Portal, under the Domains section.
  25. Test the following scenarios
    • you can login using Outlook Web App to a mailbox in the Wing Tip Toys Office 365 tenant and access all emails.
    • you can configure Outlook client and a Mobile email client to access a mailbox in the new Wing Tip Toys Office 365 tenant using autodiscover (this depends on the autodiscover.wingtiptoys.com dns record. If there are errors, check to ensure this record has been correctly populated and is pointing to the value shown in the Office 365 portal)
    • emails from external senders are successfully received in a wingtiptoys mailbox in the Wing Tip Toys Office 365 tenant.
    • emails sent from a wingtiptoys user in the Wing Tip Toys Office 365 tenant to an external recipient is successfully received
    • emails sent between wingtiptoys users in the Wing Tip Toys Office 365 tenant is successfully received
  26. Import the Distribution groups that were exported from Tail Spin Toys Office 365 tenant
  27. The cut-over is now complete.
  28. By now, users must be able to access their emails using Outlook Web App. If they have followed the instructions, their Outlook and Mobile devices must be working as well.
  29. The mailboxes belonging to the Wing Tip Toys users in the Tail Spin Toys Office 365 tenant can be kept active for at least 30 days (this will come in handy for those cases where a user reports that some emails were not copied across). After this, the mailboxes can be backed up and then deleted (If the Wing Tip Toys user mailboxes in the Tail Spin Toys Office 365 tenant had other email aliases, on which emails were being received, it would be a good idea to configure an Out of Office rule to state that all emails sent to this user should instead be sent to firstname.lastname@wingtiptoys.com)

 

Thats it folks. After following the above steps, you would have moved an additional Office 365 domain to a new Office 365 tenant and would have also moved their mailbox data to the new tenant.

I hope the above helps those that are looking at getting this done.

Have a great day ūüėČ

A tool to find mailbox permission dependencies

When planning to migrate mailboxes to Office 365, a lot of care must be taken around which mailboxes are moved together. The rule of the thumb is “those that work together, move together”. The reason for taking this approach is due to the fact that there are some permissions that do not work cross-premises and can cause issues. For instance, if a mailbox has delegate permissions to another mailbox (these are permissions that have been assigned using Outlook email client) and if one is migrated to Office 365 while the other remains on-premises, the delegate permissions capability is broken as it does not work cross-premises.

During the recent Microsoft Ignite, it was announced that there are a lot of features coming to Office 365 which will help with the cross-premises access issues.

I have been using Roman Zarka’s¬†Export-MailboxPermissions.ps1¬†(part of https://blogs.technet.microsoft.com/zarkatech/2015/06/11/migrate-mailbox-permissions-to-office-365/¬†bundle) script to export all on-premises mailboxes permissions then using the output to decide which mailboxes move together. Believe me, this can be quite a challenge!

Recently, while having a casual conversation with one of my colleagues, I was introduced to an Excel ¬†spreadsheet that he had created. Being the Excel guru that he is, he was doing various VLOOKUPs into the outputs from Roman Zarka’s script, to find out if the mailboxes he was intending to migrate had any permission dependencies with other mailboxes. I just stared at the spreadsheet with awe, and uttered the words¬†“dude, that is simply awesome!”

I was hooked on that spreadsheet. However, I started craving for it to do more. So I decided to take it on myself to add some more features to it. However, not being too savvy with Excel, I decided to use PowerShell instead. Thus was born Find_MailboxPermssions_Dependencies.ps1

I will now walk you through the script and explain what it does

 

  1. The first pre-requisite for¬†Find_MailboxPermissions_Dependencies.ps1 are the four output files from Roman Zarka’s Export-MailboxPermissions.ps1 script¬†(MailboxAccess.csv, MailboxFolderDelegate.csv, MailboxSendAs.csv, MaiboxSendOnBehalf.csv)
  2. The next pre-requisite is details about the on-premises mailboxes. The on-premises Exchange environment must be queried and the details output into a csv file with the name OnPrem_Mbx_Details.csv. The csv must contain the following information (along the following column headings)“DisplayName,¬†UserPrincipalName,¬†PrimarySmtpAddress,¬†RecipientTypeDetails, Department, Title, Office, State,¬†OrganizationalUnit”
  3. The last pre-requisite is information about mailboxes that are already in Office 365. Use PowerShell to connect to Exchange Online and then run the following command (where O365_Mbx_Details.csv is the output file)
    Get-Mailbox -ResultSize unlimited | Select DisplayName,UserPrincipalName,EmailAddresses,WindowsEmailAddress,RecipientTypeDetails | Export-Csv -NoTypeInformation -Path O365_Mbx_Details.csv 

    If there are no mailboxes in Office 365, then create a blank file and put the following column headings in it¬†“DisplayName”, “UserPrincipalName”, “EmailAddresses”, “WindowsEmailAddress”, “RecipientTypeDetails”

  4. Next, put the above files in the same folder and then update the variable $root_dir in the script with the path to the folder (the path must end with a \ )
  5. It is assumed that the above files have the following names
    • MailboxAccess.csv
    • MailboxFolderDelegate.csv
    • MailboxSendAs.csv
    • MailboxSendOnBehalf.csv
    • O365_Mbx_Details.csv
    • OnPrem_Mbx_Details.csv
  6.  Now, that all the inputs have been taken care of, run the script.
  7. The first task the script does is to validate if the input files are present. If any of them are not found, the script outputs an error and terminates.
  8. Next, the files are read and stored in memory
  9. Now for the heart of the script. It goes through each of the mailboxes in the OnPrem_Mbx_Details.csv file and finds the following
    • all mailboxes that have been given SendOnBehalf permissions to this mailbox
    • all mailboxes that this mailbox has been given SendOnBehalf permissions on
    • all mailboxes that have been given SendAs permissions to this mailbox
    • all mailboxes that this mailbox has been given SendAs permissions on
    • all mailboxes that have been given Delegate permissions to this mailbox
    • all mailboxes that this mailbox has been given Delegate permissions on
    • all mailboxes that have been given Mailbox Access permissions on this mailbox
    • all mailboxes that this mailbox has been given Mailbox Access permissions on
    • if the mailbox that this mailbox has given the above permissions to or has got permissions on has already been migrated to Office 365
  10. The results are then output to a csv file (the name of the output file is of the format Find_MailboxPermissions_Dependencies_{timestamp of when script was run}_csv.csv
  11. The columns in the output file are explained below
Column Name Description
PermTo_OtherMbx_Or_FromOtherMbx? This is Y if the mailbox has given permissions to or has permissions on other mailboxes. Is N if there are no permission dependencies for this mailbox
PermTo_Or_PermFrom_O365Mbx? This is TRUE if the mailbox that this mailbox has given permissions to or has permissions on is  already in Office 365
Migration Readiness This is a color code based on the migration readiness of this permission. This will be further explained below
DisplayName The display name of the on-premises mailbox for which the permission dependency is being found
UserPrincipalName The userprincipalname of the on-premises mailbox for which the permission dependency is being found
PrimarySmtp The primarySmtp of the on-premises mailbox  for which the permission dependency is being found
MailboxType The mailbox type of the on-premises mailbox  for which the permission dependency is being found
Department This is the department the on-premises mailbox belongs to (inherited from Active Directory object)
Title This is the title that this on-premises mailbox has (inherited from Active Directory object)
SendOnBehalf_GivenTo emailaddress of the mailbox that has been given SendOnBehalf permissions to this on-premises mailbox
SendOnBehalf_GivenOn emailaddress of the mailbox that this on-premises mailbox has been given SendOnBehalf permissions to
SendAs_GivenTo emailaddress of the mailbox that has been given SendAs permissions to this on-premises mailbox
SendAs_GivenOn emailaddress of the mailbox that this on-premises mailbox has been given SendAs permissions on
MailboxFolderDelegate_GivenTo emailaddress of the mailbox that has been given Delegate access to this on-premises mailbox
MailboxFolderDelegate_GivenTo_FolderLocation the folders of the on-premises mailbox that the delegate access has been given to
MailboxFolderDelegate_GivenTo_DelegateAccess the type of delegate access that has been given on this on-premises mailbox
MailboxFolderDelegate_GivenOn email address of the mailbox that this on-premises mailbox has been given Delegate Access to
MailboxFolderDelegate_GivenOn_FolderLocation the folders that this on-premises mailbox has been given delegate access to
MailboxFolderDelegate_GivenOn_DelegateAccess the type of delegate access that this on-premises mailbox has been given
MailboxAccess_GivenTo emailaddress of the mailbox that has been given Mailbox Access to this on-premises mailbox
MailboxAccess_GivenTo_DelegateAccess the type of Mailbox Access that has been given on this on-premises mailbox
MailboxAccess_GivenOn emailaddress of the mailbox that this mailbox has been given Mailbox Access to
MailboxAccess_GivenOn_DelegateAccess the type of Mailbox Access that this on-premises mailbox has been given
OrganizationalUnit the Organizational Unit for the on-premises mailbox

The color codes in the column Migration Readiness correspond to the following

  • LightBlue – this on-premises mailbox has no permission dependencies and can be migrated
  • DarkGreen ¬†– this on-premises mailbox has got a Mailbox Access permission dependency to another mailbox. It can be migrated while the other mailbox can remain on-premises, without experiencing any issues as Mailbox Access permissions are supported cross-premises.
  • LightGreen – this on-premises mailbox can be migrated without issues as the permission dependency is on a mailbox that is already in Office 365
  • Orange – this on-premises mailbox has SendAs permissions given to/or on another on-premises mailbox. If both mailboxes are not migrated at the same time, the SendAs capability will be broken. Lately, it has been noticed that this capability can be restored by re-applying the SendAs permissions to both the migrated and on-premises mailbox post migration
  • Pink – the on-premises mailbox has FolderDelegate given to/or on another on-premises mailbox. If both mailboxes are not migrated at the same time, the FolderDelegate capability will be broken. A possible workaround is to replace the FolderDelegate permission with Full Mailbox access as this works cross-premises, however there are privacy concerns around this workaround as this will enable the delegate to see all the contents of the mailbox instead of just the folders they had been given access on.
  • Red – the on-premises mailbox has SendOnBehalf permissions given to/or on another on-premises mailbox. If both mailboxes are not migrated at the same time, the SendOnBehalf capability will be broken. A possible workaround could be to replace SendOnBehalf with SendAs however the possible implications of this change must be investigated

12. Yay, the output has now been generated. All we need to do now is to make it look pretty in Excel ūüôā

Carry out the following steps

  • Import the output csv file into Excel, using the semi-colon “;”¬†as the delimiter (I couldn’t use commas as the delimiter as sometimes department,titles etc fields use them and this causes issues with the output file)
  • Create Conditional Formatting rules for the column¬†Migration Readiness so that the fill color of this cell corresponds to the word in this column (for instance, if the word is¬†LightBlue then create a rule to apply a light blue fill to the cell)

Thats it Folks! The mailbox permissions dependency spreadsheet is now ready. It provides a single-pane view to all the permissions across your on-premises mailboxes and gives a color coded analysis on which mailboxes can be migrated on their own without any issues and which might experience issues if they are not migrated in the same batch with the ones they have permissions dependencies on.

In the output file, for each on-premises mailbox, each line represents a permission dependency (unless the column PermTo_OtherMbx_Or_FromOtherMbx? is N). If there are more than one set of permissions applicable to an on-premises mailbox, these are displayed consecutively underneath each other.

It is imperative that the migration readiness of the mailbox be evaluated based on the migration readiness of all the permissions associated with that mailbox.

Find_MailboxPermissions_Dependencies.ps1 can be downloaded from  GitHub

A sample of the spreadsheet that was created using the output from the Find_MailboxPermissions_Dependencies.ps1 script can be downloaded from https://github.com/nivleshc/arm/blob/master/Sample%20Output_MailboxPermissions%20Dependencies.xlsx

I hope this script comes in handy when you are planning your migration batches and helps alleviate some of the headache that this task brings with it.

Till the next time, have a great day ūüėČ

[Updated] How are email addresses created for Office 365 Mailboxes?

Background

Over the past few weeks, I have been doing some Cloud-Only Office 365 deployments using Azure AD Connect . As you might imagine, this deployment is abit different to the Hybrid Office 365 deployment.

One of the things that got me thinking was, how are the email addresses created for my Office 365 mailboxes? As I was synchronising objects from my on-premises Active Directory, this question held the answer to what values I needed to change in my on-premises Active Directory user object, to get the desired email addresses populated in the Office 365 mailbox that will be created for it.

Preparation

To find the above answer, I devised a simple experiment.

I decided to create four on-premises Active Directory user objects, with different combinations of Netbios, UserPrincipalName (UPN), Mail attribute and ProxyAddresses and trace what happens to these values as they are used to create their corresponding Azure AD object. I will then assign an Office 365 Exchange Online Plan 2 license to these Azure AD objects and see what email addresses got assigned to the resulting Office 365 mailbox.

Simple? Lets begin.

The four user accounts I created in on-premises Active Directory had the following properties (ProxyAddresses were populated using ADSIEdit). The domains used by the UPN, Email and proxyaddresses attributes are all internet routable domains.

FirstName     :Ross
LastName      :McCary
DisplayName.  :Ross McCary
Netbios       :CONTOSO\R.McCary
UPN           :Ross.McCary@contoso.com
Email         :{blank}
ProxyAddresses:{blank}

FirstName.    :Angela
LastName      :Jones
DisplayName.  :Angela Jones
Netbios       :CONTOSO\A.Jones
UPN           :Angela.Jones@contoso.com
Email         :An.Jones@contoso.com
ProxyAddresses:{blank}

FirstName     :Zada
LastName      :Daley
DisplayName.  :Zada Daley
Netbios       :CONTOSO\Z.Daley
UPN           :Zada.Daley@contoso.com
Email         :Zada.Daley@tailspintoys.com
ProxyAddresses:{blank}

FirstName     :Bob
LastName      :Brown
DisplayName   :Bob Brown
Netbios       :CONTOSO\B.Brown
UPN           :Bob.Brown@contoso.com
Email         :Bob.Brown@contoso.com
ProxyAddresses:SMTP:Bo.Brown@contoso.com
               smtp:Bob@contoso.com
               smtp:Bobi@tailspintoys.com

The Experiment

I initiated an Azure AD Connect delta synchronisation cycle and waited. After a few minutes, I saw new objects created in my Office 365 tenant’s Azure AD that corresponded to the ones that I had created in the on-premises Active Directory.

Here are the values that Azure AD Connect (AADC) added for the newly created AAD objects (tenantid is the id for the Office 365 tenant)

FirstName     :Ross
LastName      :McCary
DisplayName   :Ross McCary
SignInName    :Ross.McCary@contoso.com
UPN           :Ross.McCary@contoso.com
ProxyAddresses:{blank}

FirstName     :Angela
LastName      :Jones
DisplayName   :Angela Jones
SignInName    :Angela.Jones@contoso.com
UPN           :Angela.Jones@contoso.com
ProxyAddresses:{SMTP:An.Jones@contoso.com}

FirstName     :Zada
LastName      :Daley
DisplayName   :Zada Daley
SignInName.   :Zada.Daley@contoso.com
UPN           :Zada.Daley@contoso.com
ProxyAddresses:{SMTP:Zada.Daley@tailspintoys.com}

FirstName     :Bob
LastName      :Brown
DisplayName   :Bob Brown
SignInName.   :Bob.Brown@contoso.com
UPN           :Bob.Brown@contoso.com
ProxyAddresses:{SMTP:Bo.Brown@contoso.com,
                smtp:Bob@contoso.com,
                smtp:Bobi@tailspintoys.com,
                smtp:Bo.Brown@tenantid.onmicrosoft.com,
                smtp:Bob.Brown@contoso.com}

Now, this was quite interesting. AADC added proxyaddresses for only those Azure AD (AAD) objects that had the email field populated in their corresponding on-premises Active Directory user objects. Also, for Bob Brown, two additional proxy addresses had been added. Interesting indeed! (the additional attributes are in orange above)

I then proceeded to assigning an Office 365 Exchange Online Plan 2 license to all the above AAD objects so that a mailbox would be provisioned for them. After waiting a few minutes, I checked to confirm that the mailboxes had been successfully provisioned. I then went back to Azure AD and checked the attributes again.

Below is what I saw (additional values that got added after license assignment are in Orange)

FirstName     :Ross
LastName      :McCary
DisplayName   :Ross McCary
SignInName    :Ross.McCary@contoso.com
UPN           :Ross.McCary@contoso.com
ProxyAddresses:{SMTP:Ross.McCary@tenantid.onmicrosoft.com,
                smtp:Ross.McCary@contoso.com}

FirstName     :Angela
LastName      :Jones
DisplayName   :Angela Jones
SignInName    :Angela.Jones@contoso.com
UPN           :Angela.Jones@contoso.com
ProxyAddresses:{SMTP:An.Jones@contoso.com,
                smtp:Angela.Jones@contoso.com,
                smtp:An.Jones@tenantid.onmicrosoft.com}

FirstName     :Zada
LastName      :Daley
DisplayName   :Zada Daley
SignInName    :Zada.Daley@contoso.com
UPN           :Zada.Daley@contoso.com
ProxyAddresses:{SMTP:Zada.Daley@tailspintoys.com,
                smtp:Zada.Daley@contoso.com,
                smtp:Zada.Daley@tenantid.onmicrosoft.com}

FirstName     :Bob
LastName      :Brown
DisplayName   :Bob Brown
SignInName.   :Bob.Brown@contoso.com
UPN           :Bob.Brown@contoso.com
ProxyAddresses:{SMTP:Bo.Brown@contoso.com,
                smtp:Bob@contoso.com,
                smtp:Bobi@tailspintoys.com,
                smtp:Bo.Brown@tenantid.onmicrosoft.com,
                smtp:Bob.Brown@contoso.com}

For the mailboxes, below is what I saw

FirstName     :Ross
LastName      :McCary
DisplayName   :Ross McCary
UserID        :Ross.McCary@contoso.com
ProxyAddresses:{SMTP:Ross.McCary@tenantid.onmicrosoft.com,
                smtp:Ross.McCary@contoso.com}

FirstName     :Angela
LastName      :Jones
DisplayName   :Angela Jones
UserID        :Angela.Jones@contoso.com
ProxyAddresses:{SMTP:An.Jones@contoso.com,
                smtp:Angela.Jones@contoso.com,
                smtp:An.Jones@tenantid.onmicrosoft.com}

FirstName     :Zada
LastName      :Daley
DisplayName.  :Zada Daley
UserID        :Zada.Daley@contoso.com
ProxyAddresses:{SMTP:Zada.Daley@tailspintoys.com,
                smtp:Zada.Daley@contoso.com,
                smtp:Zada.Daley@tenantid.onmicrosoft.com}

FirstName     :Bob
LastName      :Brown
DisplayName   :Bob Brown
UserID        :Bob.Brown@contoso.com
ProxyAddresses:{SMTP:Bo.Brown@contoso.com,
                smtp:Bob@contoso.com,
                smtp:Bobi@tailspintoys.com,
                smtp:Bo.Brown@tenantid.onmicrosoft.com,
                smtp:Bob.Brown@contoso.com}

Quite interesting (hmm well not really ūüėČ ). The newly created mailboxes had the same proxyaddresses as the proxyaddresses assigned to their corresponding AAD object.

The Result

After looking at the results, I could easily see a pattern between the on-premises Active Directory user object’s email and proxyaddresses values and the Azure AD and Office 365 mailbox email addresses.

From my experiment, I deduced the following process that is used to create email addresses for the Office 365 mailboxes

  1. When provisioning Azure AD objects, AADC first checks to see if the on-premises AD user object has proxyaddresses assigned. If there are any, these are added as proxyaddresses for the Azure AD object (the proxyaddress with the¬†SMTP:¬†prefix (uppercase smtp) will be the primarySMTP for the AAD object). If the email attribute is not part of the proxyaddresses, it is added as an additional proxyaddress. Next, the primarySMTP’s part before the¬†@ is prefixed to the tenant email domain to create the mailbox’s routing email address and then added as an additional proxyaddress (for instance Ross.McCary@tenantid.onmicrosoft.com)
  2. If the on-premises Active Directory user object does not have any proxyaddresses, then the email attribute is assigned as the primarySMTP address for the AAD object. If the email attribute is not the same as the UPN, then the UPN is added as an additional proxy address.¬†Next, the primarySMTP’s part before the¬†@ is prefixed to the tenant email domain to create the mailbox’s routing email address and then added as an additional proxyaddress (for instance Ross.McCary@tenantid.onmicrosoft.com)
  3. In cases where both the email attribute and proxyAddresses are blank, the part of the UPN before the¬†@ is prefixed to the tenant email domain to create the mailbox’s routing email address. In this instance, the routing email address is set as the primarySMTP address. The UPN is then added as an additional proxyaddress.

An interesting thing to note is that even before assigning an Office 365 license, you can see what email addresses will be assigned, by using PowerShell to check the proxyaddresses attribute of the Azure AD object.

I hope the above provides some clarity around how email addresses are created for Office 365 mailboxes and helps with your Cloud-Only Office 365 architectures.

Have a great day ūüėČ

[Update] There could be instances, where by some mistake

  • (a) a new user is assigned an email attribute that is already attached to an existing mailbox in Office 365
  • (b) a new user is assigned a proxyaddress that is already attached to an existing mailbox in Office 365

For issue (a), AADC will not create the new user in AAD and instead display an error in the AADC console when doing an exporting to AAD. The error will be similar to below

“Unable to update this object because the following attributes associated with this object have values that may already be associated with another object in your local directory services: [ProxyAddresses xxxxxxxxx;]. Correct or remove the duplicate values in your local directory.”

The error will provide detailed information regarding the values that are causing the issue. It will also contain the ObjectIdInConflict. This is the id of the existing Object that the new user is in conflict with.

Using the¬†ObjectIdInConflict¬†value, search the AADC Metaverse with the clause “cloudAnchor contains¬†ObjectIdInConflict“. (replace ObjectIdInConflict with the ObjectIdInConflict value¬†as shown in the error). This will show the metaverse record of the object that the new user is conflicting with. In this case, remediate the issue in the on-premises Active Directory and then initiate another AADC delta synchronisation cycle.

For issue (b), AADC will create a new user in AAD however it will remove the proxyAddress that is causing the conflict from the new user object in AAD. It will also create a record in the Office 365 Admin Center, under Settings\DirSync errors, with details of the new user, the existing user that it is in conflict with and also the attribute that is in conflict. In this case, remediate the issue in the on-premises Active Directory and initiate another AADC delta synchronisation cycle.

Note: In both cases above, the technical contact for the Office 365 tenant gets sent an email with details of the errors.

Deploying Cloud-only mailboxes in Office 365 using On-Premises Directory objects

In this blog, I will show you how to create Cloud-only mailboxes in Exchange Online (Exchange Online is the messaging part of Office 365) that are bound to objects synchronised from your on-premises Active Directory. The Cloud-only approach is different to the Hybrid approach because you do not need an Exchange server deployed in your on-premises environment.

There are a few reasons why you would want to link your¬†Cloud-only¬†mailboxes to your on-premises Active Directory. The most important reason is to ensure you don’t have multiple identities for the same user. Another reason is to provide the notion of¬†single-sign-on. This can be established by using the password synchronisation feature of Azure AD Connect (this will be discussed abit later).

Ok, lets get started.

The diagram below shows what we will be doing. In a nutshell, we will replicate our on-premises Active Directory objects to Azure AD (these will be filtered so that only required objects are synchronised to Azure AD) using Azure AD Connect Server. Once in Azure AD, we will appropriately license the objects using the Office 365 Admin portal (any license bundle that contains the Exchange Online Plan 2 license is fine. Even Exchange Online Plan 2 by itself is sufficient).

Onpremise AD Objects Synchronised AAD

Prepare your Office 365 Tenant

Once you have obtained your Office 365 tenant, add and verify the domain you will be using for your email addresses (for instance, if your email address will be tom.jones@contoso.com, then add contoso.com in Office 365 Admin Center under Setup\Domains). You will be provided with a TXT entry that you will need to use to create a DNS entry under the domain, to prove ownership.

Once you have successfully verified the domain ownership, you will be provided with the MX entry value for the domain. This must be used to create an MX entry DNS record for the domain so that all emails are delivered to Office 365.

Prepare your on-premises Active Directory

You must check to ensure your on-premises Active Directory does not contain any objects that are incompatible with Azure AD. To perform this check, run idFix in your environment.

Note of advice - idFix, by default runs across all your Active Directory objects. You do not have to fix objects that you won't be synchronising to Azure AD

It is highly recommended that your on-premise Active Directory user objects have their userprincipalname (upn) matched to their primary email address. This will remove any confusion that users might face when accessing the Office 365 services via a web browser as Office 365 login pages refer to username as “email address”.

Next, ensure that the E-mail field for all users in Active Directory contains the UPN for the user.

ADUser

Deploy and Configure Azure AD Connect Server

Ensure all the prerequisites have been met, as outlined at https://docs.microsoft.com/en-us/azure/active-directory/connect/active-directory-aadconnect-prerequisites

Next, follow the article at https://docs.microsoft.com/en-us/azure/active-directory/connect/active-directory-aadconnect-select-installation to deploy and configure your Azure AD Connect (AADC) Server.

During the configuration of AADC, you will be asked to specify which on-premise Active Directory objects should be synchronised to Azure AD. Instead of synchronising all your on-premise Active Directory objects, choose the Organisational Unit that contains all the users, groups and contacts you want to synchronise to Azure AD.

Choose the Password Synchronisation option while installing the AADC server. This will synchronise your on-premise password hashes to Azure AD, enabling users to use their on-premises credentials to access Office 365 services

At this stage, your AADC server would have already done an initial run, which would have created objects in Azure AD. These are visible using the Office 365 Admin Center.

After the initial sync, AADC runs an automatic synchronisation every 30 minutes to Azure AD

Provision Mailboxes

Now that everything has been done, open Office 365 Admin Center. Under Users\Active Users you will see all the on-premise users that have been synchronised.

Click on each of the users and then in the next screen click Edit beside Product licenses and select the location of the user and also the combination of license options you want to assign the user. Ensure you select at least Exchange Online (Plan 2) as this is needed to provision a user mailbox. Click on Save.

As soon as you assign the¬†Exchange Online (Plan 2) license, the mailbox provisioning starts. This shouldn’t take more than 10 minutes to finish. You can check the progress by clicking the user in¬†Office 365 Admin Center and then¬†Mail Settings at the bottom of the screen. Once the mailbox has been successfully provisioned, the¬†We are preparing a mailbox for this user message will disappear and instead details about the user mailbox will be shown.

Once the mailbox has been provisioned, open the Exchange Admin Center and then click on recipients from the left menu. In the right hand side screen, click mailboxes. This will show you details about the mailboxes that have been provisioned so far. The newly created user mailbox should be listed there as well.

Thats it folks! You have successfully created an Exchange Online mailbox that is attached to your on-premises Active Directory user object.

Any changes to the Office 365 object (display name etc) will have to be done via the on-premises Active Directory. These changes will be synchronised to Azure AD every 30 minutes and will be reflected in the Exchange Online mailbox

If you try to modify any of the attributes via the Office 365 or Exchange Online Admin Center, you will receive the following error

The action '<cmdlet>', '<property>', can't be performed on the object '<name>' because the object is being synchronized from your on-premises organisation.

Some Additional Information

Please note that the following is not supported by Microsoft.

There are times when you need to have additional email aliases attached to a user mailbox. To do this, follow the below steps

  1. Open Active Directory Users and Computers in your on-premises Active Directory
  2. In the top menu, click View and then select Advanced Features
  3. Navigate to the user object that you want to add additional email aliases to and double click to open its settings
  4. From the tabs click on Attribute Editor
  5. Under Attributes locate proxyAddresses and click on Edit (or double click) to open it
  6. In the values field, first enter the current email address, prefixed with SMTP: (ensure the smtp is in upper case).
  7. Then add all the email aliases that you want to assign to this user. Ensure each email alias is prefixed with smtp:  The email domain for the aliases has to be a domain that is already added and verified in Office 365 Admin Center.
  8. If you need to change the reply-to (primary smtp) address for the user then remove the value that currently has the upper case SMTP: assigned to it and then re-add it, however prefix it with a lower case smtp:. Then remove the alias that  you want to assign as the reply-to (primary smtp) and re-add it, however prefix it with an upper case SMTP:

ADUser_ProxyAddresses

I hope the blog helps out those who might be wanting to use the Cloud Only instead of the Hybrid deployment approach to Office 365.

Have a great day ūüėČ