The Attribute, the Myth, the legacyExchangeDN

Exchange 2010 LogoAfter some recent Exchange troubleshooting I decided to do a small write-up on an attribute most people working with Exchange know about, the infamous exchangeLegacyDN.

History
In the early days of Exchange, the NT world was flat. Exchange utilized its own hierarchical X.500 addressing scheme, and to uniquely identify objects it used an attribute called obj-Dist-Name (similar to distinguishedName nowadays). It contained a constructed value using elements like organization, containers and the canonical name to construct the entry, e.g. /o=Contoso/ou=EMEA/cn=Recipients/cn=User.

Then came the introduction of Active Directory with the release of Windows Server 2000. In AD, while you could refer to object using obj-Dist-Name’s counterpart distinguishedName, objects are primarily identified using their static Global Unique Identifier (GUID). The distinguishedName is constructed using relative names like the OU and CN, e.g. CN=User,OU=EMEA,DC=contoso,DC=com. Because it’s dynamic, the distinguishedName will change when you move or rename the object.

For backward compatibility with older versions of Exchange, clients or 3rd party tooling the legacyExchangeDN attribute was introduced which was to provide a unique key for the Exchange object. A process called Recipient Update Service (RUS) was responsible for populating the legacyExchangeDN value using the current location in conjunction with the given name (CN). Since Exchange 2007, legacyExchangeDN is set at creation time or can be updated manually using the Update-Recipient cmdlet. When a conflicts are detected, a unique value was constructed by adding a GUID-like series of hex characters.

When public folders are used for publishing Free/Busy information, the legacyExchangeDN was used to determine in which public folder the information was published. More information on this in an earlier blog here.

Typical values for the legacyExchangeDN attribute are:

  • Pre-Exchange 2007:
    • /o=Contoso/ou=First Administrative Group/cn=Recipients/cn=UserA
  • Exchange 2007 and later:
    • /o=Contoso/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=UserA

Until Exchange 2010 SP1 Rollup 6 the legacyExchangeDN value was predictable, but as of this Rollup (and Exchange 2013), 3 random hex characters are added for uniqueness.

Exchange Internal Addressing
While SMTP addressing is the de facto e-mail addressing standard, Exchange internally still uses an X.500 addressing scheme. Using X.500 implies that an X.500 is required, which is why mail objects in an Exchange organization such as mailboxes, require a properly populated legacyExchangeDN.

The most encountered symptom of not having properly populated or unpopulated legacyExchangeDN attributes is failure of e-mail delivery or transport, which I’ll elaborate on a bit below. I’ll mention it again: legacyExchangeDN is required, unlike some Exchange admins I overheard a while ago when they were looking for the cause of several NDRs discussing SMTP was used so it should be ‘no problem’.

IMCEA and IMCEAEX
When sending a message, the sender and recipient are checked against the Global Address List (GAL). When it can’t find a match in the GAL, IMCEA encapsulation is used which stands for Internet Mail Connector Encapsulated Addressing. An IMCEA encapsulated address looks like:

IMCEAEX-_O=CONTOSO_OU=First+20Administrative+20Group_cn=Recipients_cn=philip@contoso.com

A trailing “EX” at the end of IMCEAEX indicates that a non-SMTP address was encapsulated. The used SMTP domain “contoso.local”  is taken from the GAL object unless the lookup failed; in that case the forest DN is used.

Migrations and Co-existence Issues
Clients like Outlook cache information like the legacyExchangeDN for name lookups (the infamous name cache or .nk2 files). It will also store the legacyExchangeDN (PR_EMAIL_ADDRESS) with e-mail item. This is used when replying to old e-mail and which is why you’ll see X.500 addresses when you open the e-mail outside of the organization.

While using the legacyExchangeDN makes your client insensitive to e-mail address changes, name changes etc. it will provide a (small) challenge when for example a mailbox is moved to a different forest (or to or from Office 365 for that matter) as it will get a new legacyExchangeDN value.

To attach those old legacyExchangeDN addresses to an object in the new environment, add an X.500 entry to the proxy addresses (X.500 refers to the protocols built on the X.400 standard), e.g. X500:/o=Contoso/ou=First Administrative Group/cn=Recipients/cn=UserA.

When the target environment already contains a mail-enabled contact, ideally you want to preserve the current legacyExchangeDN as x500 address on the mailbox object (depending on if the solution transforms the contact of creates a new object). This way, users in the target environment won’t be getting NDRs because their legacyExchangeDN became invalid by the move, e.g.

Delivery has failed to these recipients or groups:
Philip Mortimer
The e-mail address you entered couldn’t be found. Please check the recipient’s e-mail address and try to resend the message. If the problem continues, please contact your helpdesk
Diagnostic Information for administrators:
Generating Server: L13L14EX1.fabrikam.local
IMCEAEX-_O=CONTOSO_OU=First+20Administrative+20Group_cn=Recipients_cn=philip@contoso.com

In this case, the user tried to reply using the X.500 address /O=Contoso/OU=First Administrative Group/cn=Recipients/cn=philip. contoso.local (later more on address conversion).

If preserving the contact’s legacyExchangeDN isn’t possible, you could collect existing legacyExchangeDN values and stamp them as X500 address on the mailbox before or after moving it.

Unpopulated legacyExchangeDN
As explained earlier, the legacyExchangeDN is required for mail-enabled Exchange objects, including mail-enabled contacts. I’ve seen contacts with unpopulated legacyExchangeDN attributes in situations where the GAL Sync tool was misconfigured.

Sending an e-mail to such a contact will also result in an NDR:

Delivery has failed to these recipients or groups:
Francis Blake
The e-mail address you entered couldn’t be found. Please check the recipient’s e-mail address and try to resend the message. If the problem continues, please contact your helpdesk
Diagnostic Information for administrators:
Generating Server: L13L14EX1.fabrikam.local
IMCEAEX-_O=NT5_ou=00000000000000000000000000000000_cn=4D182F9E133B564F88CA6A86830D4314@contoso.local
#550 5.1.1 RESOLVER.ADR.ExRecipNotFound; not found ##

Solving this situation depends on the solution used. Basically, GAL Sync or Identity Management products directly manipulate AD objects, bypassing the regular process like provisioning Exchange attributes. Therefor, they should call “Update-Recipient” to provision Exchange attributes like the legacyExchangeDN or any e-mail addresses to be set via E-Mail Address Policies.

Microsoft’s Identity Management product, ForeFront Identity Manager’s, contains a GAL agent which has a setting which will trigger the provisioning of Exchange attributes. Make sure this setting is enabled and you provided a valid URI:

image

Reporting
Instead of waiting for users to report on (internal) NDR messages, you can consult the transport logs for failed delivery messages. For example, to report on all NDR messages of the last 7 days on all transport servers, you can run the following cmdlet from the Exchange Management Shell:

Get-TransportServer | Get-MessageTrackinglog -EventID FAIL -Start (Get-Date).AddDays(-7) -ResultSize Unlimited | Where {$_.Recipients -match "^IMCEAEX*"}

NDRReportReconstructing legacyExchangeDN
If for some reason you need to reconstruct the X.500 address using the information from the NDR message, support article KB2807779 contains a short instruction or utilize the small interactive script below to convert the reported IMCEAEX address to an X500 entry:

$Addr= Read-Host "Enter full IMCEAEX address:"
$Repl= @(@("_","/"), @("\+20"," "), @("\+28","("), @("\+29",")"), @("\+2C",","), @("\+3F","?"), @("\+5F", "_" ), @("\+40", "@" ), @("\+2E", "." )) 
$Repl | ForEach { $Addr= $Addr -replace $_[0], $_[1] } 
$Addr= "X500:$Addr" -replace "IMCEAEX-","" -replace "@.*$", "" 
Write-Host $Addr

Feedback
Feedback is welcomed through the comments. If you got scripting suggestions or questions, do not hesitate using the contact form.

54 thoughts on “The Attribute, the Myth, the legacyExchangeDN

  1. On my very first migration from Exchange 2000 on-premises, to Office 365 about 1 and half year ago, I run into similar issue 🙂 … I didn’t use dirsync (not supported from Ex2000) nor used migration tool provided by Office 365, so I just recreated 20 mailboxes on the tenant, and decided to migrate old content by just copying and pasting messages from on premises mailbox to cloud mailbox with both mailboxes on the same outlook profile. The result: no-one could reply to old email sent from colleagues because on cloud mailboxes x500 attribute was not created on proxy addresses. Solution was adding x500 proxy address to each mailbox (manually!) 🙂

    Liked by 1 person

  2. Pingback: NeWay Technologies – Weekly Newsletter #55 – August 8, 2013 | NeWay

  3. Pingback: Info about legacyExchangeDN and related trouble | ril3y

  4. Pingback: Notes on X.400, X.500, IMCEA, and Exchange « prgmr.io

  5. Pingback: legacyExchangeDN Woes |

  6. Good summary. You think any change to the script may be required with the current (Exchange 2013) addition of the GUID to the legacyExchangeDN?

    Like

  7. Pingback: EighTwOne 2014 Stats | EighTwOne (821)

  8. Can you suggest a fix, outside of deleting everyone’s auto-complete/cached email address’s, where an external Exchange GAL Contact e.g. ‘Contoso1’ with email address contoso1@outlook.com was renamed and also given a completely different email address i.e. ‘Contoso’2 and contoso2@outlook.com and a new Contact was created for Contoso1, that would fix an issue where a users cache looks correct and is showing Contoso1 but emails are still ending up with Contoso2? If that makes sense. Problem is Contoso1 is very very widely used and should never have been changed.

    Exchange 2010/Outlook 2010 environment.

    Like

  9. Good. Write-up. Does anyone know how to fix an issue when mailboxes are migrated to Office 365 from Exchange 2010. Hybrid enviroment, DirSync (FIM) etc. The mailbox objects in 365 contain the LEDN of the migrated mailbox from on-premise, however when doing a reply to all from an email received prior to the migration, the senders email address is included (reply all includes self). I think this is connected to the LEDN / X500 stamping but cannot find a fix.

    Like

  10. Hi Michel , this article is very useful and great, but As I am new with exchange stuff, I need your help, we have a mixed environment where some users are in our on-premise exchange 2010 and some of them are in the Rackspace hosted solution, when I move the users from Rackspace to on premise then the users can’t send replies to my old emails and it is surely due to exchangelegacyDN , how can I solve these issues with my users. Thank you,

    Like

    • If possible, extract the LegacyExchangeDN from Rackspace environment and apply as x500 to your on-prem environment. If not possible, extract the legacyExchangeDN from the messagetrackinglogs, NDR or other means (see article for how to ‘convert’), and apply as x500 to your on-prem environment.

      Like

  11. I do not understand this topic at all. where does a beginning exchange administrator who has to do a forest migration find answers for how to fix? I’ve been trying to perform forest to forest migration for a week now without any success of any kind.
    The critical property ‘LegacyExchangeDN’ is missing in the UserMailbox object ‘Mailtest4’.

    Like

  12. Can someone tell me which service in Exchange 2013 updates the legacylegacyExchangeDN . I know there is command to update it , however i want to know which service in Exchange 2013 automatcically updates it

    Like

  13. Please confirm what is the CN value for legacyexchangeDN as i have noticed it is not matching with CN value of the object for most of the user objects

    /o=Contoso/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=????

    Like

    • Those values used to match, but since Ex2010SP1RU6, a 3-character hex suffix is added (to make the legacyExchangeDN ‘unique’). Note that only applies to objects created after migrating to this version in your environment, so you may have a mix as your environment went from version to version.

      Like

      • Thanks Michael , we are facing issue in getting this populated automatically and i believe in exchange 2013 there is no separate service which runs and populates the field , It is done using the update-recipient command only . We were thinking to forcefully update the field based on the attribute format of legacyexchangeDN. do you know any other way to populate the value automatically .

        Like

        • Not in a supported way, yet you may perhaps adjust the provisioning process (e.g. Cmdlet Extension Agent for New-Mailbox, Enable-Mailbox) to post-configure legacyExchangeDN. Do check on its uniqueness though.

          Like

          • I agree however we use FIM to bring in objects and as you might be knowing FIM works on attributes values rather than running powershell commands .

            Like

            • It helps if you add details like this 🙂 You can do the same for Update-Recipient, which is called by agents like the GalSync MA, or custom (code) the MA to prepopulate this attribute. Again, note you might be walking the unsupported path. Why do you want to align the legacyExchangeDN CN part with the CN in the first place? To have it look ‘proper’?
              On another note, and perhaps more supported, is you could schedule a script to detect unmatched CN’s, configure the legacyExchangeDN the way you want, preserving the old one as an x500 proxy address. Most desirable option depends on the requirements of the organization, of course.

              Like

  14. Pingback: Что такое IMCEA и IMCEAEX, а также x.400 и x.500 — rusmandalay

  15. Pingback: Приключения с переключением ящика | Булдаков.ru | Записки сисадмина

  16. This makes complete sense to me. We recently added O365 for some of our international users. Mailboxes created after the O365 implementation do not have X500 addresses created with the new mailbox. I’ve checked the email-address policies and the X500 address is in fact no longer in there. I can manually add these addresses using the Exchange Management Shell to pull the legacyExchangeDN and adding that as the X500 address. However, I would prefer not to take the extra time to do so. Can you help me with the syntax to add this back into the policy?

    Like

    • You can create custom address policies x500:/o=/ou=/cn=Recipients/cn=, however they need to map to the legacy DN and that DN nowadays contains a random postfix beside part of the alias, eg
      ../cn=Recipients/cn=Al.Bund127676345. Note that these x500’s are only used for things like replying to old mail etc., as stated in the article.

      Like

      • If these are only used for replying to old messages, why would we be receiving NDRs for new accounts? After adding the X500 address and removing the autofill from Outlook, messages are delivered. We are currently on Exchange 2010 with Update Rollup 5 for Exchange Server 2010 SP3. (We are planning to upgrade to Exchange 2016 next year.)

        Like

        • You mentioned “implementing Office 365”; I assumed you moved everything over. With old messages, I mean messages received before (from that person). That will store an entry in the name cache (x500 format).

          Like

  17. Pingback: X500 addresses – where is the beef? – Polisz Admin Blog

  18. Hello.

    As you wrote, the number is added to the legacyExchangeDN value.

    At first, 1, 2, 3, and 4 are in order, and now the number is 2104350504.

    We are preparing for a data migration, but we have not actually done so, and the new domain is only connected to the domain we are using now.

    I am too eager to ask you for help.

    How do you find the cause of the crash?

    AD objects with legacyExchangeDN are deleted and re-created daily for synchronization.

    Thank you.

    Like

  19. Classic Michael. A most excellent and educative post on a subject rife with myth and superstition.

    How aboout in the case of mailboxes who were never part of a hybrid or on-premises environment? They were cloud objects from creation. We’re gettting ready to do a tenant-to-tenant migration and this has emerged as an issue. Does Exchange Online still stamp mailboxes with this attribute?

    Thanks.

    Like

  20. Hi,
    I think the prepare_moverequest.ps1 is moving all attributes to target forest even the legacy x500
    so there will be no problem in replying to old mails which before migration.
    correct me if i’m wrong

    Like

  21. Pingback: Hijacking the Cloud Legacy DN Writeback - Part 1

  22. Pingback: Hijacking the Cloud Legacy DN Writeback – Part 1 | ITAnswers

  23. Pingback: Annual Report 2020 | EighTwOne (821)

  24. Hi,
    legacyExchangeDN stores information about the list of all x500?

    For example, I want to change an email to a contact by disable a contact.
    1. I remember the current legacyExchangeDN
    2. Disconnect contact with the current email
    3. I turn on the contact with the new email
    4. I register the old legacyExchangeDN as x500 in the proxy address.

    Over time, this contact once again changed the email.
    Do I need to complete the entire x500 list? or just the last working legacyExchangeDN is enough?

    Like

      • I didn’t want to describe the whole process, I know about the update, but in this case it does not fit. I will try to briefly.
        My GAL contains contacts of users from a different domain, where users can disconnect their mailbox for up to several days (a unique process in that domain is bad practice). Then turn on the mailbox again with the old mailing address or a new one.
        On my side there is a script that disconnects the contact – if the user does not have a mailbox in another domain.
        Therefore, I decided to write legacyExchangeDN in proxyAddresses, but I cannot find the information that x500 stores in itself.
        I need to understand, is it enough to write the last legacyExchangeDN or enter all the previous legacyExchangeDNs in proxyAddresses?

        Like

        • It depends. You certainly may want to save the current legacyExchangeDN as x500/proxyAddress to save 1 iteration. However, what if the person is reprovisioned 2 times? 3 times? What about addresses related to old migrations – if any – and the requirement to be able to respond/resolve addresses from 5 years ago (unless someone was offboarded, depending process)? That said,why not safekeep the existing legacyExchangeDN in one of the extension attributes and set legacyExchangeDN to it after reprovisioning if it exists? Just some thoughts.

          Like

          • I studied and tried different methods, I will not describe the process, but the logic is something like this.

            In my task, to save the current legacyExchangeDN, I use the ‘notes’ attribute (the rangeUpper value allows me to implement the logic of saving several old legacyExchangeDN that ever exist during these disable/enable of a contact).
            It will not work to save in the extended attribute (extensionAttribute).
            When a contact is disconnected, the extensionAttribute is overwritten, as are the proxyAddresses.

            When I turn on a contact, I need to add one or more legacyExchangeDN (which I will take from notes) to proxyAddresses.

            Will the last old proxyAddresses be enough or is the entire list needed?
            Judging by your thoughts in the article and my experience, I need to register the entire list as x500 in proxyAddresses.

            So I’m going to centrally solve the cache problem in Outlook and reduce the number of NDRs on the Exchange side.

            Thanks Michel

            Like

  25. X400 is a mail address, like SMTP, it is not a directory service.
    X500 is a directory service. Exchange 5.5 had its own directory service (Microsoft Exchange Directory Service), Exchange 2000 and higher use the Active Directory as the X500-service, that’s why an Exchange schema extension is required and why Exchange needs the Global Catalog.
    The LEDN is the X500-path to a mailbox in the directory.

    Like

  26. This is still relevant! Awesome, thanks for the explanation, I never know WTH MS used this attribute. We just finished creating a new company and “forklift” moved over two existing domains. Imported the PST’s and had the IMCEAEX errors. Ran this to export from the two old AD dB’s:
    get-aduser -Filter {enabled -eq $true} -Properties SamAccountName,legacyExchangeDN | Select-Object SamAccountName,legacyExchangeDN | Export-CSV C:\UserExport.csv -NoTypeInformation
    Then took the output csv and ran it thru excel formulas to create these lines:
    Set-ADUser exampleusera -add @{ProxyAddresses”x500:/o=GHMP/ou=first administrative group/cn=Recipients/cn=ExampleUserA”}

    Worked perfectly on Exchange 2019. Since the users started emailing on the new server for half a day before we figured out what was causing the Undeliverables, we kept the current LegacyExchangeDN in the new AD dB and just added an additional X500 Proxy address.

    Works like a charm!
    Thanks MdR!

    Like

  27. Hi Michel,
    I did a migration from Exchange 2010 to 2016. After moving the mailboxes, 2 users couldn’t logon to their Outlook profile. I had to change the legacyExchangeDn to the old administrative group – and then it worked again.
    The only problem was, that recurring appointsments in Outlook calender weren’t anymore accessable, the uses had to recreate the items.
    Do you have an idea why this reapply old legacyexchangeDN was needed?

    Like

    • legacyExchangeDN doesn’t have anything to do with login, only Exchange resolving. So put those back or you will have other issues, such as others not being able to respond to their old mail. Is Autodiscover pointing to Ex2016? You might want to bump the Autodiscover app pool post-migration or set the recycle interval to something shorter the (undefined) default 2hrs.

      Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.