Es gibt eine Menge Tools da draußen, die diese Aufgabe erledigen. Aber: sobald auch nur ein Hauch an Flexibilität gefordert wird (z.B. ein Exclude-Filter auf die zu synchronisierenden Objekte -> keine Mailboxen die im ExtensionAttribute9 den Wert "VIP" stehen haben) wird die Auswahl an zumindest kostenlosen Lösungen dünn.
Andere wiederum erwarten vom "einfachen" Consultant oder Admin dass er eine nicht ganz triviale Erweiterung schreibt. Der eingebaute GalSync von FIM (Forefront Identity Manager) z.B. schreibt einem vor, wie der Remote PowerShell Connect in die fremde Org abzulaufen hat. Hier hat man keinen Einfluss auf Authentifizierungsmechanismen (Kerberos ist Pflicht) oder auf andere Optionen, wie "Ignore CRL-Checking". Das erschwert den Verbindungsaufbau durch eine Legion an Firewalls und anderen Gemeinheiten. Dabei geht das Ganze in den meisten Fällen eh nicht durchs Internet, sondern wird irgendwo auf der Strecke durch ein VPN geroutet und bringt somit schonmal ein schönes Maß an Sicherheit mit.
Also, hab ich mir gedacht - warum sich mit den Tools anderer rumschlagen, wenn man sowas auch relativ einfach selbst bauen kann und damit ein Maximum an Flexibilität gewinnt. Gesagt, getan - hier ist psGalSync:
psGalSync ist ein PowerShell script das ein Active Directory nach einem anzugebenden LDAP Filter durchforstet und die gefundenen Mail User und Mailboxen mit denen aus einer bestimmten OU im fremden Forest vergleicht und die Unterschiede entsprechend anpasst.
Das ganze geht immer nur in eine Richtung. D.h. wenn Unternehmen A seine Mailboxen zu Unternehmen B synced ist das eine Richtung. Will man auch von Unternehmen B zu Unternehmen A syncen, muss man eine zweite Instanz von psGalSync auf der Seite von Unternehmen B etablieren.
Für das Provisionieren wird lediglich remote PowerShell verwendet - also kommt man mit Port 443 bzw. 80 (falls man das wirklich will) aus. Welche Möglichkeiten es gibt Remote PowerShell Verbindungen aufzubauen steht u.a. hier.
psGalSync nimmt folgende command line Attribute:
Cmd Attribut
|
Kurz
|
Kommentar
|
ExportSource
|
ES
|
Es wird nur eine Export des lokalen ADs in ein Textfile gemacht. (In Abhängigkeit zum LDAP filter).
|
ExportTarget
|
ET
|
Es wird ein Export des Ziel ADs in ein Textfile gemacht (von der angegebenen OU)
|
ExportOnly
|
EO
|
Macht beide der eben beschriebenen Schritte
|
ProvisioningOnly
|
PO
|
Erwaret “outputsource.txt” und “outputtarget.txt”
im root Folder. Provisioning wird in der remote Org durchgeführt.
|
FullRun
|
FR
|
Es werden alle drei bisher erwähnten Schritte durchgeführt.
|
ManualSync
|
MS
|
Hier werden keine Exports gefahren. Es wird lediglich ein angegebener User gesynced. (dessen SamAccountName muss angegeben werden):
psGalSync ms samAccountName
|
Abb 1: Command Line Attribute
Exportieren von der Quelle (z.B.: psGalSync ES)
psGalSync exportiert aus dem lokalen AD mit der adsisearcher Funktion (darauf hat mich erst kürzlich Frank aufmerksam gemacht). Der LDAP Filter hierzu kann nach Belieben verändert werden. Die entsprechenden User müssen eine Email Adresse haben.
Die User werden in ein File exportiert, das "outputsource.txt" heißt. Darin befinden sich alle relevanten Informationen zum jeweiligen User - semikolon-getrennt:
Primary Key
Die Mailbox Guid wird hier sozusagen als "Primary Key" verwendet. Diese wird auf dem Kontakt auf der Gegenseite ins "Notes" Feld geschrieben, damit dieser der entsprechenden Mailbox auf der Source zugeordnet werden kann (alle anderen Properties inkl. der Email Adresse können sich ja theoretisch ändern).
Der Export aus dem Ziel erfolgt über das Cmdlet "get-contact" Alle Attribute, aller Kontakte werden in das File "outputtarget.txt" geschrieben.
Provisionierung (z.B.: psGalSync po oder psGalSync fr)
Nachdem sowohl das Source File als auch das Target File exportiert wurden können wir mit dem Provisioning beginnen. Zuerst werden hierbei beide Files in ein Dictionary geladen um besser verglichen werden zu können. Danach foreach-en wir durch das Source Dictionary und überprüfen ob die jeweilige objectGuid auch im Target File existiert.
- Wenn sie existiert werden die beiden Zeilen (aus dem Source- und aus dem Target File) verglichen. Wenn die gleich sind, ist alles gut - keine weitere Action. Wenn sie sich unterscheiden, wird ein Set-Contact im Remote Forest durchgeführt, um den Kontakt auf den aktuellen Stand zu bringen.
- Wenn die Zeile aus dem Source File im Remote File nicht gefunden wird, wird ein "new-MailContact" ausgeführt und der Contact damit angelegt.
- Das gleiche gilt, wenn die Zeile nur im Remote File zu finden ist und nicht mehr im Source File - dann wird eben eine Löschung des Kontakts angestoßen.
- $maxSimDeleteCount
- Diese Variable gibt an, wieviel Kontakte auf einmal gelöscht werden dürfen. ABER: angenommen der Wert ist auf 100 gesetzt, bedeutet das, dass bei jedem Run des Scripts 100 Kontakte gelöscht werden dürfen. Also, immer schön die Logfiles lesen!
- $expectdSourceOutputLength
- Einen zweiten Weichmacher stellt diese Variable dar. Man weiß ja ungefähr wie viele Mai Objekte bei einem Export aus dem lokalen AD zu erwarten sind. Die entsprechende Zahl minus einen Schwellenwert schreibt man in diese Variable. Wenn man also z.B. 13.000 Objekte hat kann man 11.500 reinschreiben - somit wird das Script nicht laufen, wenn im Source File weniger als 11.500 User gelistet sind.