TL;DR
This post will go over how to sync a custom attribute from on-premises Active Directory to Azure Active Directory to hide a user from the GAL, without the need of extending your Active Directory schema.
Problem we had
Few days ago, I had a chance to troubleshoot an interesting problem that my customer had. To understand what happened, hereās a background of their infrastructure. They had an Active Directory Domain Services and an Exchange Server 2016. Pretty standard infrastructure for small business to say the least. Then they decided to move to Microsoft 365 2 years ago and decommission Exchange Server.
After a while, their AD DS got a bit messy and so they decided to build new AD DS and this time implement it properly like it should be - use Tiering Model. Still with me? Mkay. After the implementation of new AD DS, it was my time to shine. I had to install new Azure Active Directory Connect and pair all new on-premises identities with old identities in Microsoft 365.
Now to get to the problem they had. When you use Exchange Server, your Active Directory gets extended by tons of msExch* attributes including msExchHideFromAddressLists. This attribute is there to hide user from Global Address List. They used this attribute to hide some mailboxes. HOWEVER, when you decommission Exchange server and reimplement Domain Services, that attribute is gone. POOF! You donāt see it in new AD DS anymore. But in Exchange Online, this attribute is still set to true. And more importantly, you canāt change the attribute back to false in Exchnage admin center either, it throws an Operation failed error.
Nor you can change it in Exchange Online Powershell using this command:
Set-Mailbox -Identity XYZ@domain.com -HiddenFromAddressListsEnabled $false
The error message you get when trying said command is:
The operation on mailbox "XYZ" failed because it's out of the current user's write scope. The action 'Set-Mailbox', 'HiddenFromAddressListsEnabled', can't be performed on the object 'XYZ' because the object is being synchronized from your on-premises organization. This action should be performed on the object in your on-premises organization.
So thatās it. You have no way to change the Exchange Online parameter
HiddenFromAddressListsEnabled
Solution
The first thing that comes to mind is to extend your Active Directory Domain Services with all msExch* attributes again, change said attribute and sync it to Microsoft 365. VoilĆ ! You have your user back in GAL in Microsoft 365. But extending your AD DS schema is an irreversible change. Those attributes - and thereās loads of them - are here to stay forever, or at least until you reimplement AD DS again.
More ideal solution that I went with is to use one of msDS-CloudExtensionAttribute1 attributes that already is in your AD DS. You can create custom rule in AAD Connect Sync Rule Editor. This post will go over how to sync a custom attribute from on-premises Active Directory to Azure Active Directory to hide a user from the GAL, without the need of extending your Active Directory schema.
Synchronize extension attribute to cloud
First, you have to ensure, that the attribure msDS-CloudExtensionAttribute1 is in scope of synchronization.
NOTE: If msDS-CloudExtensionAttribute1 is in scope already, skip this step.
- Go to start and look for Azure AD Connect Synchronization Service. Open it.
- Go to Connectors tab and select Active Directory domain (not *.onmicrosoft.com) > Properties
- In Select Attributes window, find msDS-CloudExtensionAttribute1 attribute and check the box next to it (if you are using Extension attributes for other purposes, choose whichever suits you)
Create a custom sync rule
To get the value of msDS-CloudExtensionAttribute1 attribute to Exchange Online msExchHideFromAddressLists attribute, you need to create a custom synchronization rule and map one to the other.
- Open Azure AD Connect Synchronization Rules Editor
- Click on the Add new rule button (make sure direction shows Inbound)
- Set new rule
- Name: Hide user Global Adress List without extending AD DS schema
- Description: If msDS-CloudExtensionAttribute1 attribute is set to HIDE, hide user from Exchange Online Global Address List.
- Connected System: Your Active Directory domain name (e.g.: ad.domain.com)
- Connected System Object Type: user
- Metaverse Object Type: person
- Link Type: Join
- Precedence: 50 (can be any number less than 100; if you created custom rules already, just endure that there are no duplicate numbers)
- Leave Scoping filter and Join rules blank
- On Transformation page, click Add transformation and fill the form
- FlowType: Expression
- Target Attribute: msExchHideFromAddressLists
- Source:
IIF(IsPresent([msDS-cloudExtensionAttribute1]),IIF([msDS-cloudExtensionAttribute1]="HIDE",True,False),NULL)
The rule here is fairly simple. There are two nested conditions. First if is asking if the msDS-cloudExtensionAttribute1 even exists in your AD DS schema. If it does NOT, it does nothing. However if it does, it goes into the second condition, which asks if the attribute is set to āHIDEā. If it is, then the msExchHideFromAddressLists in Azure AD is set to True, otherwise it is set to False.
Test and run Initial sync
Now that you created custom rule, you should test it. Go to a server with Active Directory Users and Computers installed and set users msDS-CloudExtensionAttribute1 to āHIDEā.
NOTE: If you donāt see Attribute Editor in userās properties, you need to turn on Advanced Features of Active Directory Users and Computers in View > Advanced Features.
Afterwards at server with Azure Active Directory Connect, run powershell command
Start-ADSyncSyncCycle -PolicyType Initial
Start-ADSyncSyncCycle -PolicyType Delta
Verify that it worked
To verify that all those shenanigans worked, you have 3 options. Go to either Exchange Online PowerShell and run
Get-Mailbox -Identity <username> | fl HiddenFromAddressListsEnabled
Or go to Exchange Admin Center and on said mailbox, click on Hide mailbox check that Hide from Address List is set to On.
Last thing where you can verify that it indeed did work is in Azure Active Directory Connect itself. Go to Synchronization Service. In there, find (presumably) last Export to *.onmicrosoft.com - AAD connector. There should be 1 action. When you click on that the Updates link, window with exported objects will open. Go to the exported object and look for HiddenFromAddressListsEnabled attribute. Itās value will be True!
And youāre DONE!
If you found this blog post helpful in one way or the other, consider subscribing to my mailing list. You will get notified once new post is added or when something special is going to happen. If you have further questions, do not hesitate to contact me on twitter or linkedIn. š
Until next time, have a nice day.