How to hide users from the GAL in Office 365 synchronized from on-premises

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
FlowType: Expression
Target Attribute: msExchHideFromAddressLists
Source:

IIF(IsPresent([msDS-cloudExtensionAttribute1]),IIF([msDS-cloudExtensionAttribute1]="HideFromGAL",True,False),NULL)

 

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.

56 thoughts on “How to hide users from the GAL in Office 365 synchronized from on-premises

  1. gdogg121

    Hello,

    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.

    Reply
    1. Jack Post author

      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.

      Reply
      1. gdogg121

        Hello Jack,

        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.

        Reply
          1. gdogg121

            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.

            Thank you

    2. Bob Lindemann

      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.

      Reply
  2. gdogg121

    Hey Jack,

    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?

    Reply
    1. JasB

      Hi All/Jack

      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

      Reply
      1. Jack Post author

        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.

        Jack

        Reply
        1. Krisz

          Hi,

          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?

          Thanks,
          Krisz

          Reply
          1. Jack Post author

            Hi Krisz,

            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?

            Thank you,
            Jack

  3. Jeff West

    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:
    InnerException=>
    Invalid character ” encountered in expression 'IIF(IsPresent([msDS-cloudExtensionAttribute1]),IIF([msDS-cloudExtensionAttribute1]=”HideFromGAL”,True,False),NULL)'

    Any idea what is causing this?

    Thanks

    Reply
    1. Jack Post author

      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!
      Jack

      Reply
  4. Khurram Irshad

    Hi,

    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.

    Thanks

    Reply
    1. Jack Post author

      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.

      Reply
  5. Ralf Scholl

    Hi Jack,
    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
    Transformations
    FlowType: Direct
    Target Attribute: msExchHideFromAddressLists
    Source: msExchHideFromAddressLists

    Reply
    1. Jack Post author

      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.

      Reply
      1. Ricky Doan

        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?

        Reply
        1. Jack Post author

          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.

          Reply
  6. Peter

    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.

    Reply
  7. Taavi

    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..

    Reply
  8. Charles

    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!

    Reply
    1. Jack Post author

      Haven't tested mail-enabled security groups, but in theory, yes you could take the same approach to flow the attribute.

      Reply
  9. Lee

    Jack,
    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.

    Reply
    1. Jack Post author

      Hey Lee,

      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.
      IIF(IsPresent([msDS-cloudExtensionAttribute1]),IIF([msDS-cloudExtensionAttribute1]="HideFromGAL",True,NULL),NULL)

      Thanks!
      Jack

      Reply
  10. Richie

    Hi Jack,
    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?

    thank you

    Reply
    1. Jack Post author

      Hello Richie,

      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.
      Jack

      Reply
  11. Walter

    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)

    Thanks again

    Reply
    1. Jack Post author

      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.

      Reply
      1. Walter

        Thanks
        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

        Reply
        1. Jack Post author

          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.

          Reply
  12. Andy

    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?

    Reply
  13. Wayne

    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 ?
    Thanks

    Reply
    1. Jack Post author

      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.

      Reply
  14. Jason B.

    Nice! I may implement this if MS doesn't update Azure AD to unlock this AAD attribute if AD Connect doesn't detect an installed Exchange Schema extension soon.

    Reply
  15. chirag shah

    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 ??
    OR
    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

    Thanks

    Reply
    1. Jack Post author

      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.

      Reply
  16. Andrew

    Thanks for your post, we used it and it's been working perfectly for a while now.

    I just want to know if it's possible to do the same with mail enabled security groups as they don't have the msDS-CloudExtensionAttribute er attribute...

    Reply
  17. TheDuke

    Brilliantly described in your tutorial and worked as outlined. Thanks for putting together the info in a well documented way.

    Reply
  18. Ricky

    Several years since you wrote this article and it's still relevant and thankfully I found it.

    I knew roughly what needed to be done but wasn't sure about the transformation string, command, statement, whatever you want to call it.

    Thank you for the post, the Microsoft pages (as always) didn't explain the process very well.

    Reply
  19. Fakin IT

    I've been searching tech solutions for 25 years, and this it defiantly top 5. Simple, concise and it works. Most are shiet. How Microsoft has not addressed this particular issue is, well, whatever. Thanks - donation inbound.

    Reply
  20. Pancho

    Just wanted to say that this is still working in Oct 2024 with current version of Microsoft Entra Connect (version 2.3.20.0). Did it for both user and groups.

    For the group one I did something similar to what Bob Lindemann did in the comment above. I couldn't find the msDSCloudExtensionAttribute's in the Attribute Editor of the security groups I was trying to modify so I used the msExchAssistantName like Bob and it works. I don't see this being an issue in the future as this group will never send out emails.

    Here's the schema I used to hide security groups if anyone from the future is looking for it:
    IIF(IsPresent([msExchAssistantName]),IIF([msExchAssistantName]="HideFromGAL",True,False),NULL)

    I also set the connected system object type to group and the metaverse object type to group. Not sure if this makes a difference but modified those in the description section.

    Thanks Jack Stromberg! You're a real lifesaver.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *