Copy Links and Backlinks Between Users and Shared Mailboxes (automapping)


Automap for shared mailboxes does not work across forests when moving mailboxes.

When the user is granted permission to a shared mailbox, the default behaviour of automapping means that the shared mailbox has msExchDelegateListLink set to the DN of the user, and the backlink (hidden in AD by default) on the user is populated with the DN of the shared mailbox. Whenever the link attribute is updated, the backlink is automatically updated as well. For more on back links see https://neroblanco.co.uk/2015/07/links-and-backlinks-in-active-directory-for-exchange/

That is, is UserMailbox is granted full access to SharedMailbox you will see the following in Active Directory (Advanced View) > Attribute Editor > msExchDelegateListLink = “CN=UserMailbox,OU=etc” (on the SharedMailbox). And for the UserMailbox in Active Directory (Advanced View) > Attribute Editor > msExchDelegateListBL = “CN=SharedMailbox,OU=etc”.

When you migrate mailboxes across forests you make use of Prepare-MoveRequest.ps1 to copy all the attributes. The msExchDelegateListLink is not part of this attribute set and the msExchDelegateListBL is auto populated so we can ignore it for now – if msExchDelegateListLink was copied and updated to the new forest name, then msExchDelegateListBL would be filled in automatically.

So how do we copy the msExchDelegateListLink value for each user and then write it to the mail user object in the target forest before the mailbox is migrated (or if you have already done your migration and found this property missing and so automapping of shared mailboxes having failed (though the permissions have been copied fine), how can you grab the data from the old source forest and apply it to the mailboxes in the target?

Using PowerShell and the ActiveDirectory module is how.

First you need to export a list of all the automapped shared mailboxes each user has (this is the msExchDelegateListBL values for the user mailboxes you have migrated). There are two cmdlets to run here, the first does the entire source directory and the second filters the output to an OU and its child OU’s (so you can export a subset of data) using SearchBase. Only one of these two cmdlets is needed.

This code is PowerShell and needs to be run from any domain joined computer.

Import-Module ActiveDirectory
Get-ADUser -Properties msExchDelegateListBL,msExchDelegateListLink -LDAPFilter "(msExchDelegateListBL=*)" | Select name,DistinguishedName,@{Name='SharedMailbox';Expression={$_.msExchDelegateListBL -Join ";"}} | Export-csv automap-userlist.csv -NoTypeInformation -NoClobber -Encoding UTF8
Get-ADUser -Properties msExchDelegateListBL,msExchDelegateListLink -LDAPFilter "(msExchDelegateListBL=*)" -SearchBase 'OU=Sales,DC=domain,DC=local' | Select name,DistinguishedName,@{Name='SharedMailbox';Expression={$_.msExchDelegateListBL -Join ";"}} | Export-CSV automap-userlist.csv -NoTypeInformation -NoClobber -Encoding UTF8

These cmdlets return a CSV file listing each mailbox that has an automapping to a shared mailbox and what that shared mailbox is.

The CSV file then needs copying to the target AD forest, and as the target forest is very unlikely to contain the same OU structure and domain names, the DN of each object in the CSV file needs updating. This can be done with Find/Replace in Excel or Notepad quite easily.

For example, in a CSV I might see:

“name”,”Distinguishedname”,”SharedMailbox”

“First User”,”CN=First User,OU=Sales,DC=domain,DC=local”,”CN=SharedMailbox,CN=Users,DC=domain,DC=local CN=AnotherSharedMailbox,OU=Shared Mailboxes,OU=Exchange,DC=domain,DC=local”

“Second User”,”CN=Second User,CN=Users,DC=domain,DC=local”,”CN=Sales,OU=Shared Mailboxes,OU=Exchange,DC=domain,DC=local”

In this I have the DN of the mailbox and the DN of the shared mailbox in the source forest. Use Find and Replace to change all the source DN’s (or the OU/DC bits) to suit the location of the matching object in the target forest. For example, my above “second user” was as shown, but after updating the DN might be “CN=Second User,OU=Migrated,DC=target,DC=forest”. So in that case I find/replace “CN=Users,DC=domain,DC=local” for “OU=Migrated,DC=target,DC=forest”.

For my examples that follow on from here, I have saved the edited CSV file as automap-userlist-target-dn-updated.csv

Once I have the CSV file updated for the values in the target forest, I need to split each row where a user has more than one shared mailbox listed into multiple rows. This is simple with PowerShell:

Import-Csv -Path automap-userlist-target-dn-updated.csv |
% {$row = $_; $_.SharedMailbox.split(";")} |
% {$row.SharedMailbox=$_; $row} |
Export-Csv automap-userlist-target-dn-updated-split.csv -NoClobber -NoTypeInformation -Encoding UTF8

Now that I have a row in the CSV for each Shared Mailbox to User Mailbox mapping, I can set the msExchDelegateListLink value on each shared mailbox for the DN of the user that has access to it. This will update the msExchDelegateListBL on the user object automatically.

Import-Module ActiveDirectory
Import-CSV "automap-userlist-target-dn-updated-split.csv" | % {
Write-Host Add $_.DistinguishedName to $_.SharedMailbox
Get-ADUser -identity $_.SharedMailbox | Set-ADUser -Add @{msExchDelegateListlink=$_.DistinguishedName} 
}

In terms of errors in the above, if you get “get-aduser : Directory object not found” then the DN value for the Shared Mailbox is wrong, and if you see “set-aduser : The name reference is invalid” then the DN value for the user who has access to the shared mailbox is wrong (the DistinguishedName column in the CSV). The script can be run multiple times, so you are safe to fix the CSV file and import the entire list again. It will only add a given DN once in total per shared mailbox.

If your target (or source) forest has more than one domain, run the script from a server in the correct domain or use “-Server DC-name” in both the Get-ADUser and the Set-ADUser cmdlets.

Comments

One response to “Copy Links and Backlinks Between Users and Shared Mailboxes (automapping)”

  1. Mike Crowley avatar

    Cool. I had to do this with Office 365 and they don’t expose this attribute directly, so i wrote a function to grab it from the AutoDiscover service https://mikecrowley.us/2017/12/08/querying-msexchdelegatelistlink-in-exchange-online-with-powershell/

Leave a Reply

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

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