MiniSync 2

Projekt nicht weiter geführt
Diese Skriptentwicklung hatte ich Anfang 2005 angefangen und erste Versuche und Beispiele codiert aber bin dann an Grenzen gestoßen. Mit Exchange 2007 hat die PowerShell den Weg zu einer einfacheren und flexibleren Lösung geschaffen. Diese Seite besteht nur noch als Archiv.

Statt dessen plane ich das ganze als PowerShell Script flexibler zu gestalten. Siehe dazu auch CSVSync - Framework, CSV2EX, CSV2CSV

Schon viele Jahre gibt es das Skript MiniSync, mit welchem ich LDAP-Verzeichnisse miteinander abgeglichen habe. Und die Beschränkung auf LDAP und der "ONLINE-Verbindung" zu den beiden Systemen hat mich doch öfters beschränkt. Mit MiniSync2 habe ich daher komplett neu angefangen und wollte ursprünglich alles mit .NET 2.0 und Visual Studio Express entwickeln. Aber nach einiger Zeit hab ich mich dann für PowerShell entschieden, auch weil damit der "Code" weiter offen und änderbar bleibt, ohne gleich eine Version von Visual Studio nutzen zu müssen. zudem kommen wir mir die Commandlets "Export-CSV und Import-CSV" als auch Export-CliXML und Import-CliXML entgegen, die mir viel Arbeit abnehmen. Auf die prinzipielle Funktion eines Verzeichnisabgleich möchte ich hier nicht weiter eingehen sondern auf Verbinden von Organisationen und Verzeichnisabgleich verweisen. Hier sind die Klassen und deren Methoden beschrieben.

Funktionsprinzip

MiniSync2 besteht aus einer ganzen Gruppe von Klassen, die die verschiedenen System lesend und schreibend ansprechen. Auch wenn es verschiedene Klassen gibt, so unterstützen Sie alle die gleiche Methode. Damit ist es quasi durch wenige Änderungen möglich, die verschiedenen Quellen und Ziele miteinander zu verbinden.

Um zu verdeutlichen, wie ein SYNC ablaufen kann, habe ich hier ein Beispielcode für die Nutzung der Methoden und Funktionen bereit gestellt. Man startet ein VBScript oder schreibt ein .NET-Programm, welches eine Klasse als Quelle und eine andere Klasse als Ziel definiert und läuft dann durch alle Objekte, um diese optional verändert in das Ziel zu schreiben. Das könnte dann quasi wie folgt aussehen:

set source = new msxfaq.minisync.ldap
source.source = "GC://domain.tld"
source.Username =
source.passwort = 
source.filter = 
source.fields ="name,cn,sn,dn"

set target = new msxfaq.minisync.ldap
target.target = "LDAP://server/ou=test,dc=domain,dc=tld"
target.Username =
target.passwort =
target.type = EX55
target.matchfield = "mail"

while not source.eof
    if source.usn > target.lasthighestusn then
        target.bind(source.mail)
        target.SetProperty("displayname", source.GetProperty(displayname))
        target.SetProperty("sn",          source.GetProperty(sn))
        target.SetProperty("givenName",   source.GetProperty(givenName))
        target.SetProperty("displayname", source.GetProperty(displayname))
        target.write
    end if
    source.movenext
wend

target.removeorphaned("extensionAttibute13","DirSync1")
target.lasthighestusn = source.highestusn
set target = nothing
set source = nothing

Durch die Wahl der "richtigen" Klasse kann man so sehr schnell Import, Export oder Abgleichfunktionen entwickeln. Ich hoffe es wird aber auch klar, dass MIniSync2 keine Software ist, die durch einen Installer auf ihren Server kommt und per grafischer Konfiguration zu pflegen ist. MiniSync2 ist und bleibt aktuell ein Werkzeugkarten mit Material, mit dem Lösungen geschaffen werden können.

Ich habe mir schon überlegt, ob man das ganze nicht auch mit einem GUI versieht und als Dienst laufen lässt. Aber die Vielzahl der individuellen Anpassungen beim Abgleich von Feldern kann in einer GUI nur rudimentär realisiert werden. Bei BizTalk werden dazu "functionlets" eingesetzt. Das würde aber meine Arbeit sicher übersteigen.

Klassen und Aufruf

Das Prinzip "Minisync" steht und fällt natürlich mit der Verfügbarkeit der verschiedenen Klassen. Folgende Klassen sind vorgesehen. Natürlich können Sie unter Kenntnis der Schnittstellen jederzeit auch eigene Klassen entwickeln.

  • msxfaq.minisync.ldap
    Generische Klasse für LDAP Zugriff auf Active Directory (Exchange 2000/2007), aber auch Exchange 5.5, ADAM, Lotus Notes, OpenLDAP und andere Verzeichnisdienste
  • msxfaq.minisync.xml
    Abbildung von Kontaktinformationen als XML-Datei.
  • msxfaq.minisync.cdo
    Zugriff auf "Kontaktordner" in einer Exchange Mailbox oder öffentlichen Ordnern
  • msxfaq.minisync.odbc
    Nutzung von beliebigen ODBC-Verbindungen. Das kann eine Tabelle eines SQL-Servers sein aber auch eine einfache CSV-Datei.
  • msxfaq.minisync.ldif
    Nutzung einer LDIF-Datei als Quelle und Ziel

Weitere Klassen sind im Prinzip denkbar und liegen als eigenständige VBS-Dateien vor. Über die VBScript-funktion "EXECUTE" werden diese geladen und eingebunden.

Methoden

Alle Klassen nutzen die gemeinsamen Methoden, damit diese relativ leicht austauschbar sind. Natürlich sind nicht bei jeder Klasse alle Methoden erforderlich bzw. die Parameter abweichend zu erstellen.

  • Source
    Definiert die Quelle der Daten
    LDAP: "LDAP://server/ou=;filter;fields;"
    XML: Dateiname und optional den XML-Select
    CDO: Orderpfad in der Mailbox oder Public Folder
    ODBC: Datenbank und Tabellenname
    LDIF: Dateiname
  • Target
    Gibt das Ziel der Replikation an
    LDAP: ZielOU in der Form "LDAP://server/ou=;filter;fields;"
    XML: Dateiname
    CDO: Orderpfad in der Mailbox oder Public Folder
    ODBC: Datenbank und Tabellenname
    LDIF: Dateiname
  • Filter
    Bei der Quelle kann damit ein Filter für ausgewählte Objekte gesetzt werden
  • Fields
    Reduziert die Last auf der Quelle, wenn die erforderlichen Felder angegeben werden.
    z.B. bei LDAP und ODBC
  • Matchfield
    Bestimmt das Feld, welches im Ziel zur "Treffersuche" verwendet wird
  • GetProperty
    Holt das angegebene Feld aus der Quelle, oder dem aktuell gebundenen Zielobjekt
  • SetProperty
    Schreibt das angegebene Feld in das Zielobjekt.
  • write
    Schreibt den aktuellen Datensatz in das Ziel. Vorher sind alle Änderungen temporär.
  • ClearTargetContainer
    Löscht den kompletten Ziel-Kontainer (OU, MAPI.Ordner o.ä.) ohne Rücksicht auf bestehende Elemente
  • removeorphaned(feld,value)
    Weist die Zielklasse an, alle Objekte zu entfernen, die beim Synclauf nicht genutzt wurden. DAbei werden aber nur Objekte gelöscht, die im angegeben Feld den angegebenen Wert haben. Damit können mehrere Quellen in das gleiche Ziel repliziert werden und beim Cleanup werden nur die zu dieser Verbindung gehörenden Objekte geprüft und gelöscht
  • SetErrorHandler()
    Diese Funktion wird aufgerufen, wenn Fehler oder Warnungen zu melden sind. Zusätzlich geben die Klassen ihre Meldungen natürlich auch auf die Windows Debugschnittstelle aus.
  • Target.lasthighestusn, Source.highestusn
    LDAP: Erlaubt das Setzen der USN im Ziel um später bei Vergleichen und Updates "Zeit" zu sparen.

Jede Klasse kann natürlich weitere Methoden implementieren.

Konfiguration

Damit MiniSync2 sauber funktioniert, muss man eine ganze Menge Parameter festlegen. Zudem möchte man vielleicht die ein oder andere Zuweisung der Feldinhalte durchführen. Es macht natürlich keinen Sinn, all diese Daten direkt im Skript zu hinterlegen. Vor allem wenn man mehrere Verknüpfungen hat, muss man das Skript ja mehrfach pflegen. Daher sind Skript und Konfiguration von einander getrennt.

Das Skript selbst erwartet als einzigen Parameter eine VBS-Datei, die dynamisch in das Skript mit eingebunden wird. Diese Datei enthält im wesentlichen die Konfigurationen und die Funktion zur Umsetzung der Felder.

AD-Feld: "importedFrom"
Im Active Directory gibt es ein Feld "importedFrom"", welches diverse Abgleichprozesse (z.B. Notes Transporter Suite) gerne nutzen, um die Quelle eines Objekts zu hinterlegen. Oft ist hier eine GUID enthalten, auch wenn es genau genommen nur ein "String"-Feld ist. Hier sollte sich also auch MiniSync hinterlassen

Einschränkungen

MiniSync ist "einfach" und kann und soll auch nicht mit großen kommerziellen Produkten konkurrieren. Es ist eine Basis für eigene Anpassungen und Entwicklungen. Aber es gibt Einschränkungen, die sie können sollten:

  • FullSync
    Die größte Einschränkung ist sicher, dass beim Export immer alle Objekte ausgelesen werden. Natürlich könnte ich über "USN-Changed" eine Deltaliste der Änderungen erhalten, aber damit würde ich keine gelöschten Objekte finden und nicht alle Datenquellen unterstützen ein Deltafeld. Einen Vergleich auf der Quellseite mit einem "letzten Stand" könnte das lösen, aber macht MiniSync wieder komplexer
  • Kein GUI
    Es gibt keinen Installer und keine GUI. MiniSync ist VBScript und entsprechend müssen Sie die Parameter im Skript pflegen oder als Parameterdatei übergeben.

Aber für die bisher von mir genutzten Umgebungen war es immer ausreichend.

Weitere Links