Compare-GAL

Um das Adressbuch von zwei Exchange Umgebungen zu vergleichen, gibt es das folgende PowerShell-Script. Es liest die GAL aus und vergleicht Sie anhand der SMTP-Adressen um Unstimmigkeiten zu finden.

Anforderung

Sobald sie mehr als eine Exchange Organisation betreiben, dazu zählt auch der Exchange Hybrid Mode mit Exchange Online/Office 365, stellt sich sehr schnell die Frage, ob die Adressbücher der beiden Umgebungen die gleiche Information enthalten. Der Abgleich der GAL durch ADSync oder andere Tools ist für eine saubere Koexistenz erforderlich. Ansonsten beschweren sich im einfachsten Fall nur Nutzer, dass sie nicht alle Empfänger sehen. Wenn aber z.B. Empfänger fehlen und das Mitgliedschaften in Verteilern nicht aufgelöst werden können, werden Mails gar nicht erst zugestellt. Wenn Empfänger mit Weiterleitungsfunktionen fehlen, dann werden die Mails entweder über einen unsicheren oder zumindest ineffizienten Weg geroutet oder als Unzustellbar abgewiesen. Also gilt:

OnPrem Exchange Online Beschreibung

Mailbox

MailUser

Für jeden Benutzer mit einem Postfach auf dem lokalen Exchange Server muss es in Exchange Online einen MailUser gegen, dessen TargetAddress auf die OnPremises Mailbox verweist. Ansonsten funktionieren keine Frei/Belegt, Anzeige des OnPremises Kalender in Teams und Hybrid Migrationen.

Remote Mailbox

Mailbox

Postfächer in der Cloud müssen im lokalen Exchange Server als "Remote Mailbox" mit einer TargetAddresse auf die <tenant>.onmicrosoft.com-Domain konfiguriert sein, damit diese Empfänger im Adressbuch sind und das Mailrouting an die Cloud-Postfächer funktioniert

Mailcontact

Mailcontact

Wenn Sie, warum auch immer, im lokalen Exchange externe Postfächer als Kontakte pflegen, dann sollte die Cloud dies auch wissen. Denken Sie dabei aber auch an eventuell erforderliche SendConnectoren/OutboundConnectoren, damit die Mails an diese Domains wie gewünscht geroutet werden.

Verteiler

Verteiler

Natürlich müssen auch Verteiler mit den Mitgliedern auch in der Cloud vorhanden sind.

Mailcontact

Office Group/Teams Team

Office Groups und Microsoft Teams Teams sind auch per Mail erreichbar aber per Default verborgen, Sie können diese aber sichtbar machen und/oder mit einer Mailadresse aus ihrer Domain versehen. In diesem Fall sollten Sie diese Empfänger aber auch im lokalen AD anlegen. Das kann ADSync mit der Funktion Groups Writeback für Sie machen oder sie verwalten die Objekte unabhängig.

Der Abgleich und die Kontrolle der GALs ist daher ein sehr einfaches Hilfsmitteln, um Inkonsistenzen zwischen zwei Exchange Organisationen zu erkennen und ggfls. die Fehler zu korrigieren. Sie können auch ein Hinweis darauf sein, dass z.B. ADSync gar nicht alle Objekte repliziert, weil über Filter und Scoping bestimmte Bereiche des Quell-Forest absichtlich ausgeschlossen wurden. Das ist gerade am Anfang und bei Pilot-Phasen gerne der Fall und wird oft sehr spät bemerkt.

Gewisse Inkonsistenzen wird es aber immer geben, denn es gibt natürlich Empfänger, die nicht synchronisiert werden sollen oder können. Dazu zählen z.B. die Postfächer der Systemaufsicht und die Test-Postfächer für "Test-*"-Commandlets auf einem lokalen Exchange Server. Umgekehrt gibt es in der Cloud Postfächer, z.B. "Group"-Mailboxen, die es erst einmal nur in der Cloud und von ADSync nicht ins lokale Active Directory zurück repliziert werden.

Überlegung

Alles was Exchange hinsichtlich der GAL interessiert sind die Empfänger. Das dazu passende Commandlet ist "Get-Recipient", welches per Exchange PowerShell eine Liste aller Empfänger liefert. Das Commandlet ist sogar On-Premises und in Exchange Online vom Namen her gleich und von den Parametern her fast identisch.

Die Rückgaben sind auch ziemlich gleich. Leider sind sie nicht ganz identisch, da bestimmte Werte in der Exchange Online PowerShell direkt als "String" geliefert werden während die On-Premises PowerShell ein SMTP-Adressobjekt liefert. Für einen Vergleich muss eine Konvertierung erfolgen. Dennoch sind die Mailadressen natürlich optimal für einen Abgleich geeignet, denn sie ist zumindest innerhalb einer Umgebung eindeutig und einmalig. Nur On-Premises könnte es doppelte Adressen geben, wenn ein Administrator z.B. per LDAP an jedem Support vorbei direkt die Feldinhalte ändert oder auf unterschiedlichen Domain Controllern sehr kurz hintereinander Objekte verändert und damit die Exchange Commandlets die Eindeutigkeit nicht sicherstellen können. Darauf nehme ich aber erst einmal keine Rücksicht, da solche Dubletten schon durch unzustellbare Mails und Eventlog-Meldungen auffallen.

Umsetzung

Da das Commandlet "Get-Recipient" in beiden Welten gleich heißt und ich für einen Abgleich sowieso mit Hashtabellen arbeiten will, habe ich im Skript zuerst die relevanten Informationen der einen Seiten in eine Hashtabelle übertragen und danach mit den Werten der anderen Seite abgeglichen. Am Ende kommt dann eine Ausgabe als CSV-Datei heraus, in der ich für jedes Objekt ermittle, ob es nur auf der einem Seite, der anderen Seite oder auf beiden Seiten InSync vorhanden ist. Primärer Schlüssel ist dabei die primäre SMTP-Adresse. Da diese aber manchmal abweichen kann, führe ich eine zweite Hashtabelle mit, mit denen die sekundären Adressen auf das primäre Objekt verweisen. So kann ich beim zweiten Durchlauf auch Unstimmigkeiten in den ProxyAddresses auf das gleiche Objekt zurück führen.

Aktuell beschränke ich mich aber auch auf diesen Abgleich und vergleiche noch nicht alle weiteren Stammdaten wie Straße, Ort, Hausnummer, Telefon etc. Das ist sicher noch leicht zu erweitern, wenn Sie diesbezüglich die Daten weiter verifizieren wollen. Ich habe aber bei dem Abgleich mehrerer Exchange Organisationen als auch Hybrid-Umgebungen häufiger erlebt, dass bestimmte Felder nicht oder nur verändert repliziert wurde. So wurde oft der Firmenname im Ziel statisch überschrieben, Mobilrufnummern ausgeschlossen oder die Durchwahl unkenntlich gemacht. Solche Unstimmigkeiten müssten Sie dann schon selbst noch einbauen.

Aufruf

Da das Skript primär für den Einsatz in einer Exchange Hybrid Umgebung gebaut wurde, starte ich das Skript auf einem Exchange Server in der PowerShell. Das Skript lädt bei Bedarf selbst die lokal Exchange PowerShell nach, um die lokalen Empfänger zu ermitteln. Zuerst fragt es aber nach den Exchange Online Credentials, denn im zweiten Schritt verbindet es sich mit der Exchange Online PowerShell. Aktuell ist noch kein MFA implementiert. Über den "Parameter "AdminUsername" müssen Sie den UPN eines Exchange Online Administrator vorgeben.

Weitere Parameter sind nicht erforderlich. Die Verarbeitung kann je nach Größe ihrer Umgebung etwas dauern und alle Aktionen und Vergleiche werden auf der Konsole ausgegeben. Wenn alles gut läuft, dann sehen Sie überwiegend "grüne" Meldungen.

Gelbe Meldungen sagen, dass da Objekte nur in EXO oder nur onPrem gefunden wurden. Am Ende des ersten und zweiten Abschnitts sehen Sie auch eine kurze Statusausgabe mit der Anzahl der Objekte.

Das Skript ist aktuell nur für den "Interaktiven" Betrieb vorgesehen. Durch die Eingabe der Anmeldedaten aber auch das komplette Fehlen von Error-Behandlungen etc. können Sie es nicht als Teil eines Monitoring als geplanten Task starten.

Ausgabe

Wichtiger ist aber die Ausgabe der Hash-Tabelle in den beiden CSV-Dateien, die im gleichen Verzeichnis wie das Skript abgelegt werden.

  • gallist.csv
    Hier gibt es für jedes Objekte genau eine Zeile mit den Details zum Objekt in beiden Welten bzw. auch, wenn es die Objekte nicht gibt. Ich habe hier die Datei mit Excel geöffnet, die Spalten am "Komma" getrennt und zur Lesbarkeit farblich markiert
  • proxyaddresslist.csv
    Diese Datei liefert eine Zeile pro ProxyAdresse. Ein Objekt kann also mehrfach vorkommen.

    Damit versuche ich auch fehlende ProxyAddresses zu erkennen. Aber hier fange ich noch nicht alle Sonderfälle an. Die Liste ist noch nicht verlässlich.

Für einen Vergleich der GAL ziehe ich aber sowieso nur die Datei gallist.csv heran, um Unstimmigkeiten genauer zu analysieren.

Download

Wie immer ist der Einsatz des Skripts auf eigene Gefahr. Allerdings ist das Risiko sehr gering, da das Skript nur eine Exchange PowerShell verbindet und die Liste der Empfänger mittels "Get-Recipient" ausliest und das Ergebnis in lokale Dateien  speichert. Daher ist maximal ein "Konto Lockout" denkbar, wenn Sie absichtlich mehrfach falsche Anmeldedaten eingeben würden.

compare-gal.ps1

Das Skript ist nicht digital signiert und könnte daher bei der Übertragung oder einen lokalen Virus verändert werden. Es ist immer eine gute idee fremde Skript zumindest grob zu kontrollieren.

Offen

Das Skript ist eine erste Version, die bislang eine schnelle Prüfung erlaubt hat, wie komplett der Abgleich durch AADConnect/ADSync ist. Das ist insbesondere dann hilfreich, wenn man nur Administrator für Exchange Online ist aber keinen Zugriff auf den ADSync-Server selbst hat. Es gibt aber schon noch Potential für mehr, z.B.

  • Bug in proxyaddresslist.csv
    Die Unstimmigkeiten hier muss ich in größeren Umgebungen noch mal untersuchen.
  • Ausnahmen für System-Postfächer
    Aktuell werden die On-Premises Systempostfächer noch als "fehlend in der Cloud" berichtet. Das könnte man korrigieren, in dem das Skript diese Postfächer einfach von vorneherein ausschließen.
  • Graph statt Exchange PowerShell
    Wer weiß wie lange noch die Exchange PowerShell genutzt werden kann. Vielleicht ist Graph zukünftig der bessere Weg. Auch aus Sicherheitsüberlegungen könnten Sie dann dem Skript als Applikation die Rechte geben und müssten nicht mehr als "Exchange Online Admin" arbeiten.
  • MFA und Credential Speicher
    Ich mache es ungerne, aber wer den Check automatisieren will, muss irgendwo die Anmeldedaten hinterlegen. ich könnte mir aber auch vorstellen
  • Compare-GAL als Client
    Nur um die Empfänger zu vergleichen müsste man gar nicht per PowerShell an die Admin-Schnittstelle gehen. Die GAL kann auch Outlook (MAPI) EWS und Graph lesen. Und dazu würde ein normaler Benutzer reichen, wenn man versteckte Elemente mal ignoriert.

Allerdings weiß ich nicht, wann ich diese Erweiterungen ergänzen kann oder ob diese überhaupt erforderlich werden.

Weitere Links