Copy-ReceiveConnector

Während die Konfiguration von Send-Connectoren sehr einfach auf neue Exchange Server erweitert werden können, müssen Receive-Connectoren manuell angelegt werden, wenn Sie kein Skript zur Hand haben. Hier ist meine Lösung:

Hintergründe

Die Exchange Transport Rolle von Exchange ist für den Versand als auch für den Empfang von Mails über das Protokoll SMTP zuständig. Dazu gibt es entsprechende Send-Connectoren und Receive Connectoren. Wer sich die Exchange Konfiguration einfach in der Weberfläche anschaut, erkennt einen großen Unterschied:

Send-Connectoren sind Orgweit definiert, Receive-Connectoren sind pro Server konfiguriert.

Dass hat dann zur folge, dass sie für die Nutzung eines Send-Connectors auf einem neuen Server nur wenige Schritte tun müssen:

  • Firewall-Freischaltung
    Wenn zwischen dem neuen Server und den Zielen eine Firewall filtert, dann müssen Sie dort den neuen Server entsprechen zulassen
  • Zertifikat
    Sollte der SendConnector sich bei der Gegenseite per MTLS ausweisen, dann braucht er lokal ein installiertes Zertifikat, welches zum Namen im Parameter "TlsCertificateName" passt
  • SourceTransportServers
    Zuletzt müssen Sie nur noch den neuen Server in die Liste bei SourceTransportServers addieren, damit er die Konfiguration aktiviert

In die Empfangsrichtung ist es deutlich umständlicher, da die Receive-Connectoren pro Server verwaltet werden. Einen einfachen Weg die Konfiguration zu "klonen" gibt es nicht. Also geht es nur über das Auslesen der Informationen aus einem bestehenden Server und die Neuanlage eines Connectors bzw. Update eines bestehenden Connectors. Dabei gibt es noch zwei Besonderheiten, die gerne übersehen werden.

  • Binding IP
    Wenn die Connectoren auf explizite IP-Adressen gebunden sind, dann kann das schwer durch einen Automatismus erfolgen.
  • AD-Permissions
    Es gibt neben den Einstellungen im Connector selbst noch "besondere" Berechtigungen, die als ADPermission hinterlegt werden, z.B. "ms-Exch-SMTP-Accept-Any-Recipient" für "offenes Relay" oder die Umgehung von Spamfiltern mit "ms-Exch-Bypass-Anti-Spam".
    Leider ist die Liste der Rechte für Exchange schon sehr umfangreich und gar nicht einfach manuell zusätzlich vergebene Rechte zu finden

Hier muss man also abwägen, was man möchte um bestehende Einstellungen nicht kaputt zu überschreiben.

Make or Buy/Copy

Ehe sie ein eigenes Skript entwerfen wollen, sollten sie einfach einmal suchen, ob es nicht schon fertige Skripte oder Anleitungen gibt. Und tatsächlich habe ich gleich mehrere Quellen gefunden, die das gleiche Problem angegangen sind.

Es gibt noch weitere aber letztlich gibt es einfache beschränkte Lösungen bis zum Export in Datei und Reimport. So richtig überzeugt hat mich es aber nicht.

Umsetzung

Ich hatte das Ziel, auf einmal mehrere Connectoren der Quelle auf mehrere neue Server zu übertragen. Mein Skript sollte aber auch bestehende Connectoren aktualisieren etc., d.h. ein Server würde der "Master" sein und dessen Konfiguration kann ich dann auf andere Server übertragen. Das soll auch für die "Default Connectoren" gelten. Zudem gibt es ja noch durchaus "besondere Rechte", die mit Add-ADPermission auf dem Connector addiert werden, z.B.

Ms-Exch-SMTP-Accept-Any-Recipient

Ich wollte anfangs sogar eine Pipeline einrichten, dass ich die Quelle von einem "Get-ReceiveConnector | Copy-ReceiveConnector -targetserver <servername>. Aber da war mir dann das Risiko zu hoch, dass jemand ohne Angabe eines Server auf einen Schlag alle Connectoren der Umgebung an das Skript sendet. Parameter sind da besser zu handhaben. So hat mein Skript drei wichtige Parameter bekommen:

  • Identity
    Damit können Sie genau den einen ReceiveConnector in ihrer Umgebung spezifizieren, von dem die Daten geladen werden. Sie brauchen dann nur noch den TargetServer. Ein SourceServer kann nicht angegeben werden
  • SourceServer
    Wenn Sie alle Connectoren eines Servers laden wollen, dann geben Sie einfach den SourceServer an. Das Skript liest dann alle Connectoren dieses Servers aus. Der Parameter "Identity" gibt es dann nicht
  • TargetServers
    Der Zielserver muss immer angegeben werden, da dort ein gleichnamiger Connector angelegt oder aktualisiert wird. Überall, wo der "SourceServername" erscheint, wird dabei der Zielserver addiert. Einen abweichenden Ziel-Connector habe ich nicht implementiert

Über "Parameterset" habe ich bestimmt, dass Sie nur Identity für genau einen Connector oder SourceServer für alle Connectoren eines Servers nutzen können aber nicht beide Parameter gleichzeitig. TargetServer ist aber immer verpflichtend. Natürlich gibt es noch weitere Parameter, z.B.: um die zu kopierenden Felder zu steuern, ob ein Connector überschrieben werden darf o.ä.

Ein Großteil des Skripts sind Überprüfungen, Bildschirmausgaben etc. Würde ich all diese Sicherheiten weglassen, könnte es auf wenige Zeilen schrumpfen. So ist es aber hoffentlich lesbar. Ein Aufruf könnte also sein:

# Kopieren aller ReceiveConnectoren von Servr EX01 auf EX02

Copy-ReceiveConnector -SourceServer EX01 -TargetServer EX02

# Kopieren eines COnnectors
Copy-ReceiveConnector -Identity "EX01\Default" -TargetServer EX02

Download

Dies ist noch eine relativ früher Version des Skripts. Es hat mir bei meinem Projekten bislang gute Dienste geleistet aber ich habe keine exzessiven Unit-Test durchlaufen. Sie sollten es daher nicht nutzen um einfach mal eine große Menge an Connectoren auf viele neue Server anzulegen oder zu aktualisieren. Vor allem würde ich die Exchange "Default"-Connectoren nicht über das Skript kopieren sondern einen Umzug nutzen, um eigene Connectoren für besondere Aufgaben anzulegen.

Copy-ReceiveConnector.ps1

Kontrolle

Ob denn das Kopieren alles so perfekt geklappt hat, vergleiche ich natürlich danach. Mit einem Get-ReceiveConnector kann ich Quelle und Ziel sehr einfach abfragen aber wollen Sie alle Parameter von Hand vergleichen? Leider liefert die PowerShell kein passendes Werkzeug mit. Es gibt zwar ein "Compare-Object", aber zumindest ist es mir noch nicht gelungen, einen geeigneten Vergleich damit zu erzeugen.

Daher gibt es mit Compare-PSObject ein Script, welches Objekte anhand der einzelnen Properties vergleicht. Das funktioniert soweit ganz gut aber manchmal scheint Exchange die Einträge im Array "RemoteIPRanges" in der Sortierung zu ändern, so dass hier Unterschiede gemeldet werden, die keine Sinn.

Weitere Links