ADSync Join

Wenn ADSync Objekte aus mehreren Quelle einliest und synchronisiert, dann gibt es den Fall, dass mehrere Objekte letztlich die gleiche Identität sind. Dies gilt z.B. für einen Ressource Forest oder bei Migrationen von AD-Objekten in andere Forests z.B. mit ADMT -Active Directory Migration Toolkit o.ä. hier ist es wichtig, dass das gleiche Objekte in mehreren Quellen im Metaverse zusammengeführt werden.

Funktionsweise

Ehe ich auf die einzelnen Fälle eingehe, fasse ich ein paar Kernaussagen von Microsoft mit eigenen Worten zusammen:

  • Matching mit Join-Rules
    Dazu liest ADSync nacheinander alle Objekte aus und für jeden Object läuft er die verschiedenen Synchronization Rules der Reihe nach durch, in denen "Join rules" definiert sind. Wird anhand dieser Regeln ein Objekt im Metaverse gefunden, dann wird das Objekt verknüpft.
  • Provision wenn kein Join
    Wird anhand der Join-Rules kein Objekt gefunden, dann wird anhand der "Provisioning"-Regeln ein neues Objekt im Metaverse angelegt. Dazu muss das Objekt aber auf jeden in mindestens einem Feld der Join-Rules auch einen Wert stehen haben, damit später für andere Objekte ein Join ermöglich wird
  • Join passiert nur einmal
    Ein neues Objekt in einem Connectorspace wird nur beim ersten Sync über die Join-Logik auf ein bestehendes passendes Objekt im Metaverse verbunden. Die Verbindung wird im Metaverse gespeichert. Es findet kein "ReJoin" statt, wenn es ein neues besseres Objekt gibt. Es werden auch nicht zwei Objekte im Metaverse zu einem Objekt zusammengeführt
  • Nur eine Join-Regel pro Objekt
    Ein Objekt wird durch den Connector und den Objekttyp klassifiziert und ADSync legt immer nur genau eine Synchronization Rule pro Kombination mit "Join Rules" an. Wenn Sie die Regeln selbst ändern, darf es immer nur genau eine Synchronization Rule pro Objekt geben, welche eine "Join Rule" enthält. Ansonsten erhalten Sie einen Fehler.
  • Unjoin
    Eine Verknüpfung eines Objekts im Connectorspace mit dem Metaverse wird nur gelöscht, wenn das Objekt im Connectorspace gelöscht und diese Änderung durch einen Sync im Metaverse aktualisiert wird. Ein bereits verknüpftes Objekt wird nicht umorganisiert, wenn sich der Feldinhalte ändert, der für den Join relevant ist.

Mit diesen Vorarbeiten können wir nun die verschiedenen Szenarien durchspielen:

1:1:1 Regelfunktion

ADSync, was letztlich auch nur eine Lite-Version von MIM, FIM, ILM, MIIS ist, kennt dazu die "Join"-Funktion, um mehrere Objekte aus verschiedenen Quellen zu einem Metaverse zusammenzuführen. Der klassische Weg ist natürlich, dass jedes Objekt in einem lokalen Verzeichnissen genau einmal vorkommt. Dann hat ADSync leichtes Spiel:

Der Import liest das Objekt in den Connectorspace des Connectors. Beim nächsten Sync wird das Objekt anhand der "Synchronization Rules" in das Metaverse und den Connectorspace der Ziele übertragen. Beim Export der jeweiligen Zielverbindungen schreibt ADSync dann die Änderungen in das Zielsystem.

2:1:1 Regelfunktion

Wenn wir nun z.B. lokal einen Exchange Ressource Forest haben, dann gibt es in einem Forest das Anmeldekonto und im anderen Forest das deaktiviert Exchange Postfach, bei dem das Feld msExchMasterAccountSID (Siehe Linked Mailbox und Disabled Account) die Verbindung zwischen den beiden Objekten herstellt:

Für jeden lokalen Forest gibt es einen eigenen Connector Space, in den die Objekte beim Import eingelesen werden. Erst beim "Sync" findet der Join statt. Wenn Sie dann ADSync bei der Installation der zweiten Verbindung für dieses Szenario korrekt konfiguriert haben, dann sollten Sie zwei Regeln "In from AD - User Join" finden, die bei den Join-Rules folgenden Eintrag haben:

Sie sehen aber auch, dass z.B. "msExchMasterAccountSID" auf "objectSid" in beide Richtungen vorhanden ist und sogar das Szenario mit einem Skype for Business/Lync-Ressource Forest abgedeckt wird.

Es ist also nicht wichtig, welcher Connector "zuerst" eingerichtet wird, um den Join zu erreichen. Allerdings ist es später schon wichtig, welche SyncRule an welcher Stelle steht, denn es werden die Feldinhalte die Regel mit der niedrigeren Nummer (= höhere Priorität) geladen. Das ist aber nur en Problem, wenn ein Feld in zwei oder mehr Quellen unterschiedliche Inhalte hat.

Ich nutze hier das relativ einfache Beispiel des Ressource Forest. Mit ADSync können Sie auch ein Matching anhand des Feld "Mail" als auch SamAccountName/MailNickName oder einem anderen Feld einrichten.

Das ADSync Setup legt dann die entsprechenden Regeln direkt an. Folgende Regeln haben bei mir eine Join-Rule:

In from AD - User Join
In from AD - InetOrgPersion Join
In from AD - Group Join
In from AD - Contact Join
In from AD - ForeignSecurityPrincipal Join User
In from AD - COmputer Join
In from AD - Device Join 
In from AAD - User Join
In from AAD - Contact Join
In from AAD - Group Join
In from AAD - DeviceCommon

Auch diese können Sie im ADSync Regel-Editor weiter anpassen.

Allerdings sollten Sie hier dann genau wissen, was sie tun und die Default-Regeln nie ändern sondern kopieren, deaktivieren und dann nur die Kopie ändern. Ansonsten überschreibt ein ADSync Update die Default-Regeln und ihre Änderungen.

Übrigens gibt es auch "Join Rules", wenn Sie nur genau einen Connector zu einem lokalen AD eingerichtet haben. So hat die Regel "In from AD - User Join" folgenden Eintrag:

Das Feld "Mail" ist also immer schon ein besonders guter primärer Schlüssel. Der Join bezieht sich aber immer nur auf Objekte aus unterschiedlichen Connectorspaces. Wenn Sie z.B. in einem AD zwei Objekte mit der gleichen Mailadresse anlegen, dann bekommen Sie beim Import noch keinen Fehler aber beim Sync wird nur das erste Objekte angelegt und das zweite läuft auf einen Fehler

Damit wissen Sie nun einen weiteren Punkt, warum im AD das Feld Mail "eindeutig" sein sollte. Legen Sie also nie mehrere Objekte mit der gleichen Mailadresse an.

2:2:2 NoMatch

Nun kann es speziell bei einem Provisioning passieren, dass Sie z.B. im Ressource Forest das AD-Konto und das Postfachkonto anlegen  aber das Feld "msExchMasterAccoundSID" nicht sofort mit setzen, d.h. das Postfach hat keinen Wert oder ADSync das Anmeldekonto nicht findet, weil das Provisioning das Konto auf einem anderen DC angelegt hat und die AD-Replikation verzögert ist.

Dann kann ADSync nichts matchen und der reguläre Weg sind dann zwei Konten im Metaverse und letztlich auch im AzureAD. Dies ist aber recht einfach zu erkennen, wenn Sie im AzureAD nach den fraglichen Objekten suchen und zwei Objekte finden. Kniffliger ist es, wenn das zweite Objekt aufgrund von anderen Filtern gar nicht im Zielsystem erscheint:

Sie finden wie erwartet nur genau ein Objekt im Ziel aber die Felder sind nicht wie erwartet gefüllt.

Um diese Objekte zu analysieren, können sie in der ADSync Management Console am besten das fragliche Objekt erst einmal im jeweiligen Connectorspace suchen und von dort dann zum Metaverse springen.

Dort suchen Sie dann nach dem Objekt über den DistinguishedName

In den Details können Sie dann über "Lineage" nicht nur die SyncRules sehen, sondern auch zum entsprechenden Metaverse Objekt springen.

Dies ist insbesondere dann hilfreich, wenn das Objekt gar nicht in das AzureAD exportiert wird und daher z.B. nur einen Connector hat.

Wenn sie solche Inkonsistenzen zuverlässig verhindern wollen, dann müssen Sie entweder eine gewisse Reihenfolge beim Provisionieren von Objekten in mehreren Forests einhalten und zudem beim Schreiben des Objekts selbst immer gleiche alle Felder korrekt setzen.

Tipp: Wenn Sie dies nicht 100% sicherstellen können und das Risiko hoch ist, dann sollten Sie vielleicht eine "Staging-OUs" vorsehen, in der Sie die Objekte anlegen und konfigurieren und erst als letzten Schritt dann an den finalen Platz verschieben, so dass ADSync nie partielle Objekte einlesen kann. Denkbar ist, auch, dass Sie ADSync nur Objekte lesen lassen, die in einem bestimmtes Feld einen Wert haben, der erst ganz am Ende des Provisoining gesetzt wird.

2:2:2 -> 2:1:1 Heilung

Sollte es zu so einer Fehlsynchronisation gekommen sein, dann hilft es nicht an den Regeln zu schrauben oder einen "FullSync" zu versuchen. ADSync kann nachträglich im Metaverse nicht zwei Objekte zu einem Objekt zusammenführen. Die Lösung sieht so aus, dass ein Objekt aus der ADSync-Kette komplett entfernt wird und nach einem Sync wieder neu addiert wird.

Das Matching passiert nur genau einmal pro Objekt bei der Synchronisation aus dem Connectorspace in das Metaverse.

Allerdings gibt es nun natürlich mehrere Wege, die im Grund aber alle darauf basieren, das Objekt im Metaverse erst zu entfernen und neu replizieren zu lassen:

  • Objekt in der Quelle in eine nicht durch ADSync gelesene OU verschieben
    Wenn Sie mit ADSync nicht die komplette Domain sondern nur ausgewählte OUs einlesen, dann können Sie z.B. eine neue "STAGING"-OU anlegen, die nicht berücksichtig wird. Verschieben Sie das Objekt dann in diese OU, wird ADSync ein "Delete" erkennen und das Objekte aus dem Connectorspace entfernen und beim nächsten Sync dann auch im Metaverse. Danach können Sie es wieder zurückschieben, damit es frisch erfasst wird und ein JOIN startet
  • Sync Filter
    Etwas aufwändiger ist die Anpassung der Sychronization Rules, damit ein Objekt zwar noch in den Connectorspace aber nicht in das Metaverse repliziert wird. Sie können dann lokal im AD das Feld setzen, damit es beim nächsten Import im Connectorspace aktualisiert wird und beim Sync aus dem Metaverse und nachfolgenden Diensten verschwindet. Wenn Sie danach dann wieder das Feld zurückstellen, dann wird das Objekt erstmalig wieder ins Metaverse synchronisiert und ein JOIN ausgeführt
  • Remove-ADSyncCSObject
    Ganz schnell geht es aber auch mit dem PowerShell-Befehl "Remove-ADSyncCSObject", mit dem Sie direkt ein Objekt im Connectorspace löschen können. Dann ist ein Sync erforderlich, damit es auch im Metaverse verschwindet. Durch ein "FullImport" wird das Objekt wieder aus der Quelle in den Connectorspace eingelesen und beim nächsten Sync wird das Objekt wieder ins Metaverse repliziert und ein JOIN ausgeführt

Der Weg über "Remove-ADSyncCSObject" ist natürlich einfacher, da das Quell-Objekte dazu nicht verschoben oder über Filter ausgeschlossen werden muss. Sie brauchen natürlich den Namen des Connectors zur Vorgabe des Connectorspace und den Distinguishedname des AD-Objekts:

$Obj = Get-ADSyncCSObject `
          -DistinguishedName "<DN des Quellobjects" `
          -ConnectorName "Name des Connectos"

Remove-ADSyncCSObject ? 
   -CsObject $Obj `
   -Force

Der Befehl entfernt das Objekte hart aus dem Connectorspace aber nicht aus dem Metaverse. Erst mein nächsten DeltaSync oder FullSync wird ADSync die Löschung im Connectorspace als Anlass nehmen, um das Objekte auch im MetaVerse und dann später beim Export auch bei den anderen Diensten zu löschen.

Allerdings ist der normale Ablauf des ADSync ja "Import/Sync/Export". Wenn Sie aber nun einen "DeltaSync" des Connectors machen, dann wird das Objekt nicht neu aus der Quelle eingelesen, denn wenn das AD die Quelle ist, dann kann ADSync einfach die Änderungen direkt abfragen.

In dem Fall ist daher ein "FullImport" erforderlich, damit das im lokalen AD weiter vorhandene Objekte wieder in den Connectorspace eingelesen wird.

Wenn dann der Sync-Lauf das neue Objekt im Connectorspace sieht, dann triggert dies wieder klassisch ein Join an.

N:1:1

Die "Join"-Funktion ist natürlich nicht auf zwei Quellen beschränkt. Sie können ein Objekt aus sehr vielen Quelle über individuelle Connectorspaces und Synchronisierungsregeln wieder zu einem Objekt im Metaverse zusammenführen. Allerdings erlaubt der ADSync-Assistent bei der Auswahl der Felder zum Erkennen gleicher Objekte nur ein Feld.

In dem Fall würde ich vielleicht das Feld "MAIL" nutzen, welches dann überall vorhanden und identisch gefüllt sein sollte. Das liegt aber in ihrer Entscheidung. Aus technischer Sicht können Sie mit dem "Synchronization Rule Editor" natürlich auch die Join-Regeln pro Connectorspace individuell anpassen, um auch komplett unterschiedliche Felder als Quelle in ein Zielfeld zu mappen. Wichtig ist dann nur, dass dennoch alle Instanzen eines Objektes in den verschiedenen Verzeichnisdiensten in jeweils einem Feld eine eindeutige und übereinstimmende Information enthalten, die im Metaverse auf ein Feld verknüpft wird.

Wenn dann andere Felder in mehreren Quellen gefüllt sind, dann bestimmt die Reihenfolge der Synchronisierungsregeln (Niedrigste gewinnt), welche Information ins Metaverse übertragen wird.

Zusammenfassung

Auslöser dieses Artikels war, wie so oft, ein Kundensupport, bei dem das gleiche Objekt in mehreren Quellverzeichnissen durch ADSync nicht gemerged wurden. Stattdessen wurde ein Objekte bis zum AzureAD repliziert während das andere Objekt nur bis zum Metaverse geschrieben wurde und ausgehende Filter dann eine Weiterreplikation ins AzureAD verhindert haben. Im AzureAD was daher nur ein unvollständiges Objekt zu sehen.

Erst die Analyse der Synchronisation hat aufgezeigt, dass der Join nicht erfolgt ist aber auch nicht nachträglich erfolgt. Nachdem die Zusammenhänge dann verstanden waren, ist die Lösung schnell erfolgt. Wir mussten das nicht per Join verbundene Objekt im Connectorspace durch Ausschluss beim Import (z.B. OU-Filterung) oder "Remove-ADSyncCSObject" löschen und durch einen Sync im Metaverse entfernen lassen. Nachdem in der Quelle die korrekten Inhalte der für den Join relevanten Felder noch einmal geprüft wurde, konnte das Objekt wieder durch einen Import in den Connectorspace und beim nächsten Sync auf das bestehende Objekt im Metaverse verbunden werden. Beim nächsten Export zu Microsoft 365 waren dann auch alle erwarteten Einstellungen vorhanden.

Weitere Links