Prepare-MoveRequest und dupplicate proxy addresses
Es finden immer noch Migrationen von Exchange OnPremise von einem Forest in einen anderen Forest und das kombiniert mit der Benutzermigration durch ADMT und SID-History statt. ADMT 3.2 ist die letzte Version und wurde bis Windows 2008R2 und damaligen SQL-Versionen unterstützt. Da kann es mit neueren Windows Servern, Security Einstellungen und SQL-Versionen zu Problemen kommen. Diese Seite beschreibt den Sonderfall ADMT mit Prepare-MoveRequest.
Der Tippfehler in "dupplicate" steht wirklich so im Skript von Exchange 2016/2019/SE drin.
- Support policy and known issues for ADMT
- Windows Server | Microsoft Learn
https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/support-policy-and-known-issues-for-admt - ADMT Fehler 0x8004005
Umgebung
Es mag immer weniger Dienstleister geben, die sich mit Active Directory, Cross Forest Migrationen, SIDHistory etc. noch gut auskennen aber gegeben ist folgende einfache Umgebung:
- Quellforest mit Windows 2016 DC und Exchange 2016
- Zielforest ist Windows 2025 mit Exchange SE
- ADMT 3.2 ist auf einem Windows 2022 Server im Zielforest mit SQL Express 2022

Die Aufgabe ist der Umzug aller Benutzer und Verteiler samt Exchange Postfach in den neuen Forest. Ein Szenario, was bei M&A-Operationen häufig ist und manchmal zum "Rename" eines Forests genutzt werden. In Exchange Online sind das dann Tenant zu Tenant Migrationen.
Die Arbeitsteilung der Tools ist dabei klar vorgegeben:
- ADMT migriert die Benutzer und Gruppen samt SIDHistory
- Exchange PowerShell aktivierte den User mit Enabled-Mailuser
- Prepare-MoveRequest bereitet den Boden im Ziel für die Exchange Migration
- Exchange RemoteMoveRequest verschiebt die Postfächer aus der Quelle ins Ziel.
In den meisten Anleitung ist der Schritt 2 allerdings nicht explizit beschrieben. Auf die Besonderheiten einer Exchange Hybrid Bereitstellung mit Entra ID Connect Sync in der Quelle bzw. Ziel gehe ich hier nicht weiter ein, um die Komplexität niedrig zu halten.
ADMT
Wir haben ADMT 3.2 installiert und die Verbindungen zu den beiden Forests eingerichtet, d.h. Benutzer und Rechte vergeben auf dem Quell-DC den "HKLM\System\CurrentControlSet\Control\LSA TcpipClientSupport=0x000001" aktiviert, PasswordExportServer konfiguriert und dann die erste Migration gestartet. Der Benutzer ist korrekt im Ziel angelegt worden aber ADMT hat dennoch einen Fehler gemeldet. In der Protokolldatei in "C:\Windows\ADMT\Logs" fanden wir:
Unable to store default excluded system properties in database. Unspecified error (0x80004005)
Die Meldung war noch deutlich länger und führte jede Menge Felder auf, von denen viele für Exchange wichtig waren.
Zu dem Fehler gibt es mit ADMT Fehler 0x8004005 eine ganz eigene Seite
Hier beschreibe ich nur die Kurzfassung. ADMT pflegt eine eigene Liste der "Excludes", die man über VBScript auslesen kann. Beim Fehler 0x8004005 ist das Feld aber leer, wie Sie wie folgt prüfen können
REM Script GetADMT.VBS
Set jMigration = CreateObject("ADMT.Migration")
WScript.Echo "UserPropertiesToExclude :" & objMigration.UserPropertiesToExclude
WScript.Echo "InetOrgPersonPropertiesToExclude :" & objMigration.InetOrgPersonPropertiesToExclude
WScript.Echo "GroupPropertiesToExclude :" & objMigration.GroupPropertiesToExclude
WScript.Echo "ComputerPropertiesToExclude :" & objMigration.ComputerPropertiesToExclude
WScript.Echo "SystemPropertiesToExclude :" & objMigration.SystemPropertiesToExclude
Die Ausgabe zeigte bei mir, dass es keinerlei "SystemPropertiesToExclude" gab.

Das hilft natürlich nicht weiter, wenn ADMT mit das Feld "HomeMDB" und andere von einem Forest in den anderen Forest migriert. Mit einer halb provisionierten UserMailbox im Ziel kann der später geplante Move-Request nichts anfangen.
When a User is created via
ADMT, the PrepareMoveRequest script doesn't work
since there are no proxyAddresses für the script
to match the source forest User with the target
forest User. The recommended approach is to copy
at least 1 proxy address using ADMT.
However, if you use the -UseLocalObject
parameter, the script will only copy the 3
mandatory parameters (msExchMailboxGUID,
msExchArchiveGUID, msExchArchiveName).
Quelle: Exchange 2010 Cross-Forest Mailbox Moves
(https://techcommunity.microsoft.com/blog/exchange/exchange-2010-cross-forest-mailbox-moves/591367)
Daher habe ich mir die Ausschlüsse aus meiner Referenzinstallation (siehe auch ADMT Fehler 0x8004005) geschnappt und eingespielt. Allerdings habe ich dabei die Felder "mail" und "ProxyAddresses" aus der Ausschlussliste entfernt, denn die braucht Prepare-MoveRequest noch später:
Achtung:
Übernehmen sie nicht blind das
Skript. Schauen Sie erst nach, ob ihre ADMT-Installation
nicht doch schon Einträge in "SystemPropertiesToExclude"
hat.
Set objMigration = CreateObject("ADMT.Migration")
objMigration.SystemPropertiesToExclude = _
"msDS-PSOApplied, attributeCertificateAttribute, audio, carLicense, departmentNumber, " _
+"employeeNumber, employeeType, gecos, gidNumber, homePostalAddress, houseIdentifier, " _
+"ipHostNumber, jpegPhoto, labeledURI, loginShell, memberUid, msDFSR-ComputerReferenceBL, " _
+"msDFSR-MemberReferenceBL, msDS-Obje ctReferenceBL, msDS-SourceObjectDN, " _
+"msExchAssistantName, msExchHouseIdentifier, msExchLabeledURI, " _
+"msRADIUS-FramedIpv6Route, msRADIUS-SavedFramedIpv6Route, " _
+"msSFU30Alias es, msSFU30Name, msSFU30NisDomain, msSFU30PosixMember, msSFU30PosixMemberOf, " _
+"networkAddress, nisMapName, otherMailbox, photo, preferredLanguage, " _
+"registeredAddress, roomNumber, secretary, shadowExpire, shadowFlag, " _
+"shadowInactive, shadowLastChange, shadowMax, shadowMin, shadowWarning, " _
+"textEncodedORAddress, uid, uidNumber, UnixHomeDirectory, unixUserPassword, " _
+"UserPKCS12, UserSMIMECertificate, x500uniqueIdentifier"
Damit wurden die Benutzer erneut migriert und im Ziel landete dann auch das Feld "mail" und "ProxyAddresses".
- Migration von AD-Benutzern mit ADMT:
Fehlende Attribute übertragen
https://www.windowspro.de/roland-eich/migration-ad-benutzern-admt-fehlende-attribute-uebertragen
Problem mit Prepare-MoveRequest
Nachdem die Benutzer korrekt übertragen worden sind und auch ein Feld ProxyAddresses hatten, wollte ich Prepare-MoveRequest dazu nutzen, die Objekte im Ziel für die Migration mit dem "RemoteMoveRequest" vorzubereiten. Technisch muss ich dazu die ExchangeMailboxGUID und ArchivGUID aus der Quelle an das passende Objekte am Ziel schreiben. Prepare-MoveRequest überträgt aber keine SIDHistory, so dass ich nun die Wahl habe, ob ich mit Prepare-Moverequest die User neu anlegen lasse und dann mit ADMT danach ein Matching mache, um die SIDHistory an die vorher angelegten Konten anzufügen, oder Prepare-MoveRequest die bestehenden AD-Konten im Ziel "auffrischt". Ich nutze in der Regel erst ADMT für die User und Gruppen um dann die Exchange Migration vorzubereiten.
Da der Sourcecode von Prepare-Moverequest.ps1 in den Exchange-Installationsquellen lesbar ist, wissen wir, wie das Skript im Grund funktionieren. Die Kurzfassung:
1. Suche in der Quelle nach dem Objekt und prüfen
1a: Es muss eine Mailbox sein ("MailNickName" und "msExchHomeServerName" sind vorhanden)
1b: Wenn er deaktiviert ist, muss er ein "msExchMasterAccountSid" haben
2. Suche dann das Objekt im Ziel anhand der SID/MasterAccountSID oder einer übereinstimmenden ProxyAddresse
3a Wenn kein Objekte gefunden wurde, dann lege einen MEU mittels Funktion "createMEUAndCopyAttrs" an
3b Ansonsten Suche im Ziel mit "Get-Recipient" und prüfe auf Type= MailUser/MailContact
Wenn gültiges Objekt, dann starte Funktion "forceMergeObject"
Hier ein Ausschnitt des Codes für "3b":

Wenn Sie sich das Skript anschauen, dann kann einem aber schon etwas gruselig werden, denn Microsoft widerspricht ihren eigenen Support-Statements, dass man keine Exchange Empfänger an der Exchange PowerShell vorbei anfassen sollte. In dem Skript sehe ich aber, dass ...
- Neue Benutzer mit ADSI angelegt werden
- ProxyAddresses direkt per ADSI geschrieben werden
- "msExchRecipientDisplayType" und "msExchRecipientTypeDetails" per ADSI geschrieben werden
- Ich kein "Enabled-MailUser/New-MailUser"
finde
Obwohl die PowerShell dies sehr wohl erlaubt. Möchten die Entwickler damit "Split Permission" umgehen?
Da sind die paar Tippfehler in Write-Host/Write-Verbose-Ausgaben direkt verziehen. Fakt ist aber, dass Prepare-MoveRequest den Aufruf direkt mit folgendem Fehler quittiert:
Local ad account with dupplicate proxy addresses found: cn=testuser,ou=migration,dc=mxsfaq,dc=de Cannot create mail enabled user because an existing mailbox user or mail enabled group already has the same proxy addresses/MasterAccountSid."
Die Beschreibung ist komplett irreführend, denn es gibt noch keinen "Mailenabled User", denn das von ADMT migriert Objekt enthält außer "mail" und "ProxyAddresses" keine weiteren Exchange Informationen. Das Feld "ProxyAddresses" brauche ich aber, damit Prepare-MoveRequest den User matchen kann.
Ich habe erst gedacht, dass Microsoft das Skript bei Exchange SE geändert hat aber dem ist nicht so, Das Skript ist in Exchange 2016/2019 identisch. Nur die Codesignatur hat sich geändert.
Das Verhalten war also schon immer so.
Lösung durch Enable-MailUser
Wir wissen aber nun, dass Prepare-MoveRequest.ps1 nicht einfach nach der SID/MasterAccountSID bzw. ProxyAddresses matched, sondern zusätzlich den Empfängertür mit "Get-Recipient" abfragt. Also helfen wir dem Skript etwas, indem wir alle User im Ziel, die durch ADMT mit einer Mailadresse angelegt wurden, entsprechend aufwerten.
Get-User `
-Filter "WindowsEmailAddress -like '*' -and RecipientType -eq 'User'" `
| Foreach-Object {
Enable-Mailuser `
-Identity $_`
-ExternalEmailAddress "SMTP:$($_.WindowsEmailAddress)"
}
Es steht ihnen frei in ihrer Umgebung den Filter z.B. OUs zu beschränken. Nach Abschluss der AD-Replikation habe ich dann richtige "MailUser" im Ziel, die per ADMT weiter ihre SID-History haben aber von Prepare-MoveRequest auch akzeptiert werden.
Prepare-Moverequest
So vorbereitet kann ich nun Prepare-MoveRequest ansetzen, um die Objekte im Ziel mit den notwendigen Eigenschaften zu versehen, damit der RemoteMoveRequest diese als gültige Ziele ansieht
Genaugenommen könnten Sie auch ADMT so einrichten, dass er direkt alle Felder kopiert, die auch Prepare-MoveRequest überträgt und auf das PowerShell-Script direkt verzichten. Aber das würde nur für vielleicht 99% passen. Prepare-MoveRequest überträgt z.B. den LegacyExchangeDN aus der Quelle als "X500-Adresse" ins Ziel und erlaubt auch Sonderfälle wie "Linked Mailbox" und meldet Fehler bei Unstimmigkeiten.
Insofern ist "Prepare-MoveRequest.ps1" schon eine wichtige Komponente, die aber nur genau das macht, was Sie tun soll aber bei der kleinsten Abweichung dann missverständliche Fehler liefert. Da der Code aber seit Exchange 2016 unverändert. Es ist also kein ganz neues Verhalten. Mein Aufruf für einen Benutzer war dann:
Prepare-MoveRequest.ps1 ` -Identity testuser ` -RemoteForestDomainController dc1.quellforest.de ` -RemoteForestCredential $RemoteForestCred ` -LocaForestDomainController dc2.zielforest.de ` -LocalForestCredential $localForestCred ` -UserLocalObject ` -OverWriteLocalObject ` -Verbose
Prepare-MoveRequest hat nun den Benutzer im Ziel anhand der ProxyAddresse gefunden, die ADMT migriert hat. Durch den "Enable-MailUser" vor dem Aufruf hat Prepare-MoveRequest nun auch einen gültigen Exchange Empfänger gefunden, die erforderlichen Felder für den RemoteMoveRequest übertragen.
Weitere Links
- ADMT - Active Directory Migration Toolkit
- Prepare-Moverequest.ps1
- ADMT Fehler 0x8004005
- MoveRequest und MigrationBatch
- ADMT: Unable to store default excluded system properties
in database
https://community.spiceworks.com/t/admt-unable-to-store-default-excluded-system-properties-in-database/663309 - Support policy and known issues for ADMT - Windows Server
| Microsoft Learn
https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/support-policy-and-known-issues-for-admt - Adam Arkwright | Technical Blog: proxyAddress Attribute
doesn't copy when using Active Directory Migration Tool
(ADMT)
https://blog.arkwright.com.au/2018/12/proxyaddress-attribute-doesnt-copy-when.html - ADMT 3.2 - SystemPropertiesToExclude Script don't get
results
https://learn.microsoft.com/en-us/archive/msdn-technet-forums/90ff242c-74d8-49fe-ad3a-8e9839bd3876 - Understanding Move Requests
https://technet.Microsoft.com/en-us/library/dd298174(v=exchg.141).aspx - Cross-forest mailbox migration with ADMT
https://learn.microsoft.com/en-us/answers/questions/602410/cross-forest-mailbox-migration-with-admt















