Hiding users from the Global Address List (GAL) is a fairly straight forward when the user is a cloud account. Simply "Hide from address list" from the Exchange Online console or run some quick powershell:
$LiveCred = Get-Credential $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection Import-PSSession $Session Set-Mailbox -Identity [email protected] -HiddenFromAddressListsEnabled $true
Hiding users from the GAL is fairly straight forward when the user is synchronized from on-premises as well. Simply edit the attribute of the user object, set msExchHideFromAddressLists to True, and do a sync. The problem though is what happens if you don't have the msExchHideFromAddressLists attribute in Active Directory?
Well, you can either extend your Active Directory Schema for Exchange, which is not something that you can easily roll back if something goes wrong and arguably adds a ton of attributes that likely will be never used. Or, you can simply create a custom sync rule within Azure AD Connect that flows the value from a different attribute.
This article will go over how to sync a custom attribute from on-premises to Azure AD to hide a user from the GAL, without the need of extending your Active Directory schema. In this case, we are going to use an attribute called msDS-cloudExtensionAttributeX (where X is the number of the attribute that is free/not being used within your directory). The msDS-cloudExtensionAttribute(s) were introduced in Windows Server 2012 and has 20 different numbers to allow flexibility for these types of scenarios. Now some customers may gravitate towards using a different attribute like showInAddressBook. The problem with the showInAddressBook is this attribute is referenced by very old versions of Exchange (which I'm sure people would never be running 😉 ) and is looking for the format of the common name of an object (not what we want). In this case, easiest way to move forward is to simply use the msDS-cloudExtensionAttributes.
Step 1: Scope in the msDS-cloudExtensionAttribute for Azure AD Connect
Open the Azure AD Connect Synchronization Service
Navigate to the Connectors tab, select your Active Directory (not the domain.onmicrosoft.com entry), and select Properties
In the top right, click on Show All, scroll down and find msDS-CloudExtensionAttribute1 (you can use any of the numbers 1-20, just make sure to check the box you are using), and select OK
Step 2: Create a custom sync rule
Open up the Azure AD Connect Synchronization Rules Editor
Click on the Add new rule button (make sure direction in the top left shows Inbound)
Enter the following for the description:
Name: Hide user from GAL
Description: If msDS-CloudExtensionAttribute1 attribute is set to HideFromGAL, hide from Exchange Online GAL
Connected System: Your Active Directory Domain Name
Connected System Object Type: user
Metaverse Object Type: person
Link Type: Join
Precedence: 50 (this can be any number less than 100. Just make sure you don't duplicate numbers if you have other custom rules or you'll receive a dead-lock error from SQL Server)
Click Next > on Scoping filter and Join rules, those can remain blank
Enter the following Transformation page, click the Add transformation button, fill out the form with the values below, and then click Add
Target Attribute: msExchHideFromAddressLists
Step 3: Perform an initial sync
Open up Windows PowerShell on the Azure AD Connect Server
Execute the following command: Start-ADSyncSyncCycle -PolicyType Initial
Step 4: Hide a user from Active Directory
Open Active Directory Users and Computers, find the user you want to hide from the GAL, right click select Properties
Select the Attributes Editor tab, find msDS-cloudExtensionAttribute1, and enter the value HideFromGAL (note, this is case sensitive), click OK and OK to close out of the editor.
Note: if you don't see the Attribute Editor tab in the previous step, within Active Directory Users and Computers, click on View in the top menu and select Advanced Features
Step 5: Validation
Open the Azure AD Connect Synchronization Service
On the Operations tab, if you haven't seen a Delta Synchronization, manually trigger the Delta sync to pick up the change you made in Active Directory
Select the Export for the domain.onmicrosoft.com connecter and you should see 1 Updates
Select the user account that is listed and click Properties. On the Connector Space Object Properties, you should see Azure AD Connect triggered an add to Azure AD to set msExchHideFromAddressLists set to true
There ya have it! An easy way to hide users from the GAL with minimal risk to ongoing operations. Due to the way Azure AD Connect upgrades, our sync rule will persist fine during regular updates/patches released.
I tried this. I also ran a manual Address List update using PowerShell by giving myself the Address List Manager role.
Still, I see the people I've hidden on the GAL.
I tried asking for a new Offline Address Book on the Outlook side. Nothing seems to happen the people are not hidden.
Your steps have helped me create a transform rule so I am seeing that the attribute in question is being applied but they don't actually disappear.
Is there anything I am doing wrong? Also, I don't know if this matters but we are using AAD Sync in Staging Mode.
Stage mode will only prep the changes, it won't commit them to azure. You'd need to disable staging mode if you want the changes to take affect in the cloud.
Thanks for the response. Interestingly, this change only worked with one user of ours.
I think the initial sync command needs to be re-run after I did all these users because we are stuck in staging mode.
My order of operations was exactly as yours. The test user worked but all other users failed.
Let me run the initial sync and demo this to my manager and we can move the server off staging mode.
Yep, initial sync is required after making the sync rule changes so it can populate the new attributes accordingly.
I have run the two sync commands. Yet nothing propogated to the EOP. I still see the check box to hide from address lists as unmarked. Yet my one lone user from yesterday is still good. I guess I'll just wait it out and see if it goes through.
Interesting that one person works in staging even and all else not updated yet. I'll wait and see or ask to move off staging.
Worked Perfect - did a group and user rule. Using Server 2008R2 I did not have all the msDS-CloudExtensionAttribute's available to me so I used msExcAssistantName attribute and it worked fine.
Glad it worked! Thank you for the comment!
Sorry to spam your post! Thanks for your help with this.
I just found out: If the user doesn't have E3 or E1 assigned Exchange Online Portal wont't touch that attribute. If I give them E3 or E1 then they are good and the change goes through.
Do you think this might be a staging issue? Have you seen this weird limitation?
Makes sense since the attribute is leveraged via Exchange Online.
Did anyone ever figure out how to sync this attribute for users that don have a licence assigned? I have this issue.... Microsoft support ticket I have open are still scratching there heads.
P.S. @Jack - excellent blog post.
Many Thanks, Jas
Not sure if I understand the scenario JasB. If the user doesn't have a license for Exchange Online/is mail enabled, they should not show up in the GAL.
I have the same issue. User does not have license assigned but still listed in GAL. The msExchHideFromAddressLists attribute is set to TRUE in AD. Any idea on this?
Can you try to assign the user an exchange online license, give it a few minutes and see if the account is hidden from the GAL? Once it is hidden, can you try to remove the license and see if the user still remains hidden?
Great post and looks like it will solve my issue. But I am getting an error when I try to make the rule. Here is the error:
Invalid character ” encountered in expression 'IIF(IsPresent([msDS-cloudExtensionAttribute1]),IIF([msDS-cloudExtensionAttribute1]=”HideFromGAL”,True,False),NULL)'
Any idea what is causing this?
This is caused from copying/pasting from the website. The "s and 's turn into extended ASCII characters, which Azure AD Connect cannot process. Copying and pasting this into notepad and retyping those characters will fix this. In addition, I've updated the website to try and not present those characters so it's easier to copy/paste moving forward.
Thanks for the feedback!
I have a problem that the version that is installed on my environment of azure connect does not have connectors tab from which i select msDS-CloudExtensionAttribute1, please guide me that which version i can install so that the option of connectors is available.
Try logging out of Windows and logging back in if you don't see any rules within the Rules Editor. A fresh installation of Azure AD Connect doesn't have a chance to etch the security groups added by the program to your Kerberos token, so logging out and back into Windows will give you the right access to open the tool.
Hi Jack, thank you a LOT for this post and explanations, master !!!
No problem -- glad to have helped! 🙂
even if you have the msExchHideFromAddressLists attribute in Active Directory and you set the value to true, it won't be synced.
You have to add a new rule for OUTBOUND!
Most of the Steps a equal to yours - here are only the changes
Azure AD Connect Synchronization Rules Editor
Select Direction: Outbound
Add new rule
Connected System: .onmicrosoft.com - AAD
Target Attribute: msExchHideFromAddressLists
Good call out--for whatever reason this was removed in after a few versions once Azure AD Connect was rebranded from Azure AD Sync. Good piece of documentation for those that do have the schema extended and can use the attribute.
For clarification for others, please note this step is not required per the article. If your environment had the msExchHideFromAddressLists (you had extended your schema) then you can disregard the above article and simply add this rule.
So my schema has the msExchHideFromAddressLists already. I just follow Ralf's steps to add Outbound rule. Should the change take affect in 24hrs because I don't see the change yet
All my disabled users doesn't have the license assigned so will this outbound rule still applies?
I believe you need the user to be licensed for the change to take effect. The sync interval is every 30 minutes on Azure AD Connect by default, so you shouldn't have to wait 24 hours.
You're the real deal, I just wanted to thank you (Muchas Gracias). I followed all steps and everything works as expected.
Important: Do not choose : .onmicrosoft.com – AAD only your local AD.
Thank you so much, very very helpful step by step guide.
Shame that Microsoft doesn't provide any easier solutions and i am not gonna install Exchange onprem for that..
You don't need to install Exchange on-prem. Just a 1kb Schema File.
True, but many may not want to add the Exchange schema to the directory.
This is fantastic, I've been looking for a way to do this for weeks, though I mostly need to hide an on prem mail-enabled security group that doesn't have the msDS-CloudExtensionAttribute1 fields, can I grab another attribute we aren't using and do a similar link using that or will it only work with the CloudExtensionAttributes? Thank you!
Haven't tested mail-enabled security groups, but in theory, yes you could take the same approach to flow the attribute.
I have a user, whose "Hide from Address Lists" attribute in Active Directory was turned to 'True' after they left the organisation. The subsequent sync performed fine and the User could still be seen in the list of All Users in the Exchange Admin Centre, but could not be seen in any address lists, and couldn't be searched for when addressing an email - All Good. We didn't remove any email address information, as we wanted to keep the account, in case we had any queries after the User had left the organisation.
The User has recently returned to the organisation, so we changed the attribute in Active Directory back to 'False'. The Sync seems to perform (I can see the attribute has changed) under 'updates', and yet in Office 365, the User still cannot be seen in any Address Lists, and cannot be searched for when addressing an email. Its as though they are still Hidden from view.
Any pointers or checks I can look for, to see why this hasn't worked? I'm concerned, as we have probably done this for a large batch of Leavers, and if any more return to the organisation, they won't appear as well.
Can you try modifying your Transformations to send NULL instead of False? I'm wondering if Exchange is just going by any value populated, in which False would mistakenly be read as "True" a value exists.
I read your article and its good. i have a question, its synchronization issues between our on perm AD and Azure AD after installing AD connect.
The issue we have is each time I add an email account to the special group we created for DLP in the on perm AD, when it synchronizes it changes the email user name
example: we have “ John Smith” on our domain controller AD email address is [email protected], then after synchronization the email changes to [email protected] on the Azure AD which automatically disconnects the user.
how do I fix this issue?
If you are using alternateID typically the mail address is mapped to the email field on the Properties of a user account. If you look at the advanced attributes of a user, the proxyAddresses attribute is what defines the actual email address for the user account. Typically, most customers sync by either the mail attribute (alternateID) or userPrincipalName (UPN).
Not sure if this helps or not.
Hi Jack, thanks for the solution, it worked fine here.
Quick question, what if I want to show one of those previously hidden users? Let's say that a user that left the company returns and I want to convert back the mailbox from a shared mailbox to a regular one and show it again in GAL?
Should I create another rule with ShowInGAL for example? What should be the expresion? : IIF(IsPresent([msDS-cloudExtensionAttribute1]),IIF([msDS-cloudExtensionAttribute1]="ShowInGAL",FALSE,False),NULL)
The expression should be what is documented above. If the attribute in AD is False, change the value from True to False/Null, so the user is visible.
Let uses a bit more of your time and be more precise with the question because I am not sure about the way the sync service evaluate the rules nor the exact syntax.
In the scenario I mentioned I will have the rule that you just mentioned in the original Post for hiding users and I will also have a second rule, the one that I posted, right? No sure about the syntax of my rule.
In this scenario the first rule (yours) will hide the users with the attribute set to HideFromGAL and will do the contrary for those users with the attribute set to ShowInGAL
And the other question is: that will be a new rule or a second transformation on the rule that you proposed?
Not sure I understand. You shouldn't need two different rules to hide/unhide, the expression rule in the original post allows you to unhide the account if you remove the "HideFromGAL" value from the attribute of the user account. Once removed, the following sync should sync a false value to Azure AD and show the user again.
Excellent manual. Many thanks, Jack!
This worked triple A awesome. Many thanks.
This worked for me, howerver i have to assign offboarded users E3 licenses and then remove them for this to work...i have 450 users in my disabled users OU...toughts?
Hi, When i select the msDS-cloudExtensionAttribute1 and click OK, I get a warning message "These features are intended for advanced configuration and troubleshooting and may cause severe issues etc........... Ok or Cancel.
Is this Correct ?
If you are making changes to Azure AD Connect in rules, you can indeed cause disruption/sync issues. However, the rules listed should be fine.
Very nice blog. I, however, have one fundamental point to clarify.
Once I sync the user from AD to AAD with basic attributes, I DO UNDERSTAND that this user is now onPremiseSyncEnabled user.
And for all the synched attributes , the source-of-truth is on-prem AD
We can not modify those attributes in AAD
However, if any admin wants to populate any NON-SYNCHED attribute right in the cloud , he can do it.
Am I right ??
in this case, once user is assigned EOL license, his profile's msExchHideFromAddressLists is automatically populated as FALSE by the EOL service.
So can NOT EOL-admin directly modify such cloud-borne attribute in the cloud.
In this case,
EOL-admin will either go to the portal or through powershell and modify msExchHideFromAddressLists to TRUE
It's been a long time since I wrote this article, but at that time, I believe all attributes were locked out if originating from on-premises unless it is a "cloud only" user.