Customizing Address Lists and Address Book Policies in Office 365

Use Case:

I’ve been working with a client on a large Office 365 migration. In the course of this migration, many smaller agencies with their own Exchange Organizations are being consolidated into one Office 365 tenant, but these agencies will remain autonomous units to themselves. As a result, the Global Address List contained thousands of users from all agencies. The requirement was given that each agency have access to the Global Address List including all users in the tenant, and also customized address lists with agency specific users and resources.

The Address Book Policy determines what address lists a user sees in their Outlook or OWA. When a new mailbox is created, the “AddressBookPolicy” attribute is empty. Without an  Address Book Policy specified, the user will see all available address lists in the Exchange Online tenant. If no address lists have been created, the user will see these address lists with no address book policies specified:


To change the address lists visible to the user, follow the steps below.


  1. Connect to Exchange Online Powershell. I recommend using Powershell ISE in most cases, and especially this one because you will have to tweak the commandlets to make sure your filter is pulling in the correct objects.
  2. Create the recipient filter for the new address list or lists you want to appear to the user. To develop the filter, I use the get-recipient commandlet before I create the address list. For example, the following will pull all the mailboxes with “IT” in the department field:

Get-Recipient -Filter “((RecipientType -eq ‘UserMailbox’) -and (Department -eq ‘IT’))”

This example is pretty simple. Depending on the requirement for the list, the filter could get very complex and long. There are a lot of combinations of attributes and operators that can be used in combination to pull back the desired objects. Far too many to mention in this post. See Microsoft’s documentation on this topic for a full explanation of the potential recipient filter configuration. Whatever attribute and operator configuration you use, test it using the get-recipient commandlet and adjust it until the get-recipient commandlet outputs the desired objects. This is where it is very helpful to use the Powershell ISE to easily change the filter configuration and perform tests.

3. Once you have your filter configured correctly, You will create the new address list using the New-AddressList commandlet. This example will create a new address list called “IT Users”, that contains all users with that have “IT” in their “Department” field:

New-AddressList “IT Users” -RecipientFilter “((RecipientType -eq ‘UserMailbox’) -and (Department -eq ‘IT’))”

4. Now that we have the new address list, we can create an address book policy that includes the new list, and any combination of the other lists available in the tenant. To do this, user the New-AddressBookPolicy commandlet. The following example creates a address book policy called IT Department. This policy includes all of the default lists in the tenant, and adds the newly configured IT Users list.

New-AddressBookPolicy “IT Department” -AddressLists “\IT Users”, “\All Groups”, “\All Users”, “\All Distribution Lists”, “\All Contacts”, “\Public Folders” -RoomList “\All Rooms” -GlobalAddressList “\Default Global Address List” -OfflineAddressBook “\Default Offline Address Book”

5. Apply the address book policy to the needed users. This can be done in any number of ways. To do this to an individual mailbox, you can use the Exchange Admin Center and adjust the “Address book Policy” field on the “Mailbox features” tab for that mailbox. To this in bulk, you can use the Set-Mailbox commandlet and set the AddressBookPolicy attribute to the needed policy. (ex: IT Department). I have used something like following line to pull back certain users, and apply an address book policy. Adding the “verbose” switch simply allows me to monitor the progress and accuracy of the script.

Get-User -Filter “((Department -eq ‘IT’) -and (RecipientType -eq ‘UserMailbox’))” -ResultSize Unlimited | Set-Mailbox -AddressBookPolicy “IT Department” -Verbose

Final Note:

There is a quirk in Exchange Online that adds one more step to this process. The quirk is that there is no “Update-AddressList” commandlet in Exchange Online like there is in Exchange on premises versions. So to get your new list to populate as you expect, you may need to make a slight change to the object that needs to be in the list, to get the list to include it. This is strange I know, but here is the Microsoft documentation around this limitation. See the “Update an address list” section.

There is a great script called Tickle Mail Recipients that works around this issue in bulk. I have used this a number of time in the past and it works well. The only warning I would give, is that in a large tenant, this script take a very long time to run.

Hard Delete an Office 365 User

Use case:

Sometimes, I have needed to completely remove a user from Office365. This can be due to needing to recreate them or for some other reason. Whatever the need, a soft delete will not cut it. When you soft delete a user from the “Active Users” section in the Office 365 Admin Center, that user will remain in the “Deleted Users” section for 30 days. After 30 days, the user is then purged from Office 365. When you need to purge a user immediately, follow this hard delete procedure:


  1. Soft delete the user either using the Office365 Admin Center, or through powershell:

Remove-MsolUser -UserPrincipalName <UserPrincipalName>

2. This next step must be done in powershell. Use the following commandlet to purge the user from Office 365:

Remove-MsolUser -UserPrincipalName <UserPrincipalName> -RemoveFromRecycleBin

Connect a Cloud Mailbox to a Different User With Mailbox Restore

Use Case:

I have used this procedure in the past in a few different scenarios. First, I have seen where a user becomes irreversibly corrupted in Azure AD Sync, and changes are no longer syncing to the cloud. Also, I have been a part of a cutover migration in which a mistake was made and a mailbox got associated with the wrong user account in the cloud. In either case, this process provides an easier resolution than remigrating. This process will restore a soft-deleted mailbox to a different mailbox in the cloud.

Side note: I like to do most of my powershell work in ISE. For this process in particular, there will some copying out long GUID values that is much easy if you have the notepad feature of ISE to use.


  1. Unlicense the user with the mailbox that needs to be restored elsewhere
  2. Hard delete the user
  3. (If needed) Created the new user in Office 365 either manually or through directory sync and license this user.
  4. Connect to Exchange Online through powershell.
  5. Get the soft deleted mailbox ExchangeGuid from the account you previously deleted using one of the following commandlets:

This will return the alias and ExchangeGuid of all soft deleted mailboxes. You could use this if you have a small tenant and you know there are not very many soft deleted mailboxes:

Get-Mailbox -SoftDeletedMailbox | FL Alias, ExchangeGuid


You can also specify and alias to return the specific ExchangeGuid you are looking for:

Get-Mailbox -SoftDeletedMailbox <alias> | fl ExchangeGuid


6. Get the mailbox ExchangeGuid from the newly created mailbox using the following commanlet. Specify the user with their UPN. (If you have just licensed the mailbox, it may take a few minutes for the mailbox to appear in Exchange Online.)

Get-Mailbox  -Identity <UPN> |FL ExchangeGuid


7. Start the mailbox restore process. This will restore the data from the soft deleted mailbox, to the newly created mailbox. You will copy and paste the ExchangeGUID of the soft deleted mailbox after the “-SourceMailbox” parameter, and the ExchangeGUID of the new mailbox after the “TargetMailbox” parameter.

New-MailboxRestoreRequest -SourceMailbox <ExchangeGUID of soft deleted mailbox> -TargetMailbox <ExchangeGUID of new mailbox> -LargeItemLimit unlimited -AcceptLargeDataLoss -BadItemLimit unlimited -AllowLegacyDNMismatch

8. To check progress, use the get-mailboxrestore request.


When this restore has completed, the user will be able to log into the new account and mailbox, and access the mailbox data from the old account.