Inhaltsverzeichnis
Zielsetzung
Mit Windows Server 2019 als Betriebssystem kann ich gleichzeitig auf Exchange Server 2019 migrieren.
Die Migration wird durch ein Wipe & Load je Server durchgeführt. Dabei deinstalliere ich jeweils einen Exchange Server, entferne das alte Betriebssystem, installiere einen neuen Windows Server 2019 und installiere darauf den neuen Exchange Server.
Wichtig ist mir dabei, dass der Mailservice ohne Unterbrechung weiterläuft. Die fehlende Hochverfügbarkeit während der Umstellung kann ich akzeptieren.
Die Clients greifen intern wie extern über den Namespace email.ws-its.de zu. Beide Mailserver verwenden dafür ein externes Webserver-Zertifikat. Der Zugriff wird über einen Loadbalancer gesteuert. Dieser läuft auf meinen beiden virtuellen PFSense-Servern mit dem Service HAProxy. Beide PFSense-Systeme bilden einen Cluster.
Durch den HAProxy werden auch externe Mails an meine beiden Mailserver zugestellt.
Das ist meine Mailserver-Infrastruktur:
Den Loadbalancer erkennt man in dieser Grafik besser:
Der Mailserver WS-MX2 hat Probleme mit der Datenbank-Bereitstellung. Daher werde ich diesen zuerst neu installieren.
Vorbereitung
Den Server habe ich bereits mit dem neuen Namen erstellt. Damit passt dann auch der Pfad im Hyper-V-Volume. Damit es später keine Verwechslung gibt, ändere ich den Anzeigenamen:
Jetzt kopiere ich meine Basefile in das Verzeichnis der neuen VM. Darin ist ein installierter und (einigermaßen) aktueller Windows Server 2019 mit grafischer Oberfläche installiert. Das Betriebssystem hatte ich mit sysprep zurückgesetzt und generalisiert:
Jetzt binde ich die kopierte VHDX-Datei in die neue VM ein. Zusätzlich ändere ich noch ein paar andere Parameter wie die Anzahl der CPU-Kerne und die Integrationsdienste. Auch die Firmware-Starteinstellung wird modifiziert. Das geht aber erst nach dem Einbau der VHDX:
Danach kann ich mich auch schon anmelden. Weiter geht es mit den Windows Updates. Damit der Server an den Windows Update Server im Internet kommt, hänge ich ihn fix in ein freigeschaltetes Netzwerk. Und dann geht es auch schon los:
Weitere Dateien lege ich üblicherweise unter C:\Admin ab. Auch diese werden in ein Netzlaufwerk kopiert:
Meine Exchange Server laufen aktuell nicht fehlerfrei. Hier sind meine 4 Datenbanken sichtbar. Die DB-System hat auf dem Server WS-MX2 Probleme mit dem Suchindex. Dadurch kann ich die Datenbank nicht auf WS-MX2 bereitstellen:
In meinem Monitoring ist das ebenfalls als Problem sichtbar:
Für die Neuinstallation ist es auch immer interessant, welche Anwendungen auf dem alten Server installiert waren. Viel ist es nicht, da der Server nur für Exchange verwendet wird:
Die installierten Rollen und Features lese ich fix mit der Powershell aus:
Im DNS ist erkennbar, wie ich für interne Clients die interne Adresse auf den LoadBalancer konfiguriert habe: Es existiert dafür eine eigene DNS-Zone für den externen Namespace:
Früher verwendete ich dafür den zusätzlichen Namespace email.ws.its, dessen Konfiguration einfache HOST-A-Records in meiner Domain-Zone sind:
Mehr ist auf meinem Server WS-MX2 nicht zu finden.
Ebenso kontrolliere ich noch den aktuellen Sicherungsstatus meiner Datenbanken. Diese werden von einem System Center Data Protection Manager 2019 (DPM) gesichert. Hier ist alles gut:
In meiner PFSense starte ich im Modul HAProxy die Maintenance für HTTPS und SMTP für den Server WS-MX2:
Die Maintenance wird über das Backend eingestellt:
Nach wenigen Sekunden schwenken die Verbindungen der Clients auf den Server WS-MX1:
Es kann losgehen.
Entfernung der alten Exchange-Installation
Zuerst verbinde ich meine PowerShell-ISE mit dem Exchange Server:
Jetzt verschiebe ich die 2 noch aktiven Datenbanken auf den Server WS-MX1:
Nachdem nun alle 4 Datenbanken vom Server WS-MX1 bereitgestellt werden kann ich die 4 Datenbankkopien vom Server WS-MX2 entfernen. Jede Aktion wird manuell bestätigt
Der Befehl kann die Datenbank-Dateien im Dateisystem nicht löschen. Daher erhalte ich für jede entfernte Kopie eine Warnung. Diese kann ich ignorieren, da auch die virtuelle Festplatte darunter später entfernt wird:
Ein letzter Blick im Exchange Control Panel zeigt, dass alle Datenbanken ausschließlich auf Server WS-MX1 laufen:
Beide Mailserver laufen in einer Datenbankverfügbarkeitsgruppe. Ich entferne den Server WS-MX2 als Mitglied:
Als Ergebnis wird mir eine Warnung angezeigt. Das ist nicht normal:
Daher kontrolliere ich mit dem Failovercluster-Manager die Lage. Der Server wird nicht mehr als Clusterknoten aufgeführt. Es sollte also kein Problem sein:
Der Server WS-MX2 ist damit kein Mailboxserver mehr.
Die Receive-Konnektoren werden bei der Deinstallation automatisch entfernt, da sie serverbezogen sind. Hier sichere ich nur die aktuelle Konfiguration in einer Textdatei:
Damit ist auch die Rolle HTS für die Deinstallation vorbereitet. Die Client-Access-Rolle (CAS) ist ebenfalls serverbezogen und kann durch eine einfache Deinstallation des Exchange Servers entfernt werden.
Der Assistent startet:
Vor der Deinstallation wird eine Bereitschaftsprüfung ausgeführt. Diese zeigt aber einen seltsamen Fehler an:
Offensichtlich hat die Entfernung der DAG-Mitgliedschaft (diese wurde ja mit einer Warnung abgeschlossen) nicht funktioniert. Ich öffne erneut den Failovercluster-Manager und prüfe die Cluster-Events. Hier wurde der Server ausgetragen:
Vielleicht hilft ein Neustart? Normalerweise ist das nicht erforderlich, aber ich versuche es einfach mal. Doch auch der zweite Versuch der Deinstallation scheitert. Dank meines Screenshots von vorhin kann ich mir die Warnmeldung noch einmal genauer ansehen:
Es gibt eine Nacharbeit. Cluster.exe existiert aber nicht mehr. Daher verwende ich das PowerShell-Cmdlet für die Bereinigung. Leider hat auch dieser Befehl nur eine Fehlermeldung als Ergebnis. Das Cmdlet benötigt einen Kontakt zum Clusterdienst. Doch dieser wurde bereits beendet:
Und dann kommt mir eine Idee: Bis Windows Server 2019 konnte für die Authentifizierung in einem Cluster ausschließlich NTLM verwendet werden. Doch genau dieses alte Protokoll wird explizit für Mitglieder der AD-Gruppe „Protected Users“ abgeschaltet. Und genau in dieser Gruppe ist meine administrative T1-Kennung dauerhaftes Mitglied:
Also präpariere ich einen „ungeschützten“ Account mit den sonst erforderlichen Rechten:
Mit dieser Kennung starte ich eine PowerShell-ISE und versuche die Entfernung:
Aber auch hier muss der Cluster-Dienst gestartet sein. Also versuche ich die DAG-Mitgliedschaftsentfernung mit der Kennung meines Admin-Setup. Nur dieser Teil hatte ja schon funktioniert:
So macht das keinen Spass. Ich prüfe meine Möglichkeiten in der Webseite des Exchange Admin Centers. Hier wird der Server WS-MX2 sogar noch als Member der DAG gelistet. Daher versuche ich hier eine Entfernung. Die Fehlermeldung ist anders – das Ergebnis bleibt gleich:
Der Cluster-Dienst selber wird sich nicht mehr starten lassen. Ich versuche es trotzdem einmal. Das wird aber leider auch nichts:
Langsam gehen mir die Möglichkeiten aus. Es wird Zeit für einen Rollback. Der Cluster speichert seine Konfiguration in dem Verzeichnis c:\Windows\Cluster:
Diese Dateien stelle ich aus einer SystemState-Sicherung wieder her. Jeder Server sichert bei mir seine Betriebssystem-Partitionen mit der Windows Server Sicherung auf ein Netzlaufwerk. Hier liegen also die Sicherungsdateien. Dies sind normale VHDX-Dateien, die sich mit dem Windows Explorer bereitstellen lassen. Ich mounte die passende VHDX auf meinem Sicherungsserver:
Ggf. müssen die Laufwerksbuchstaben angepasst werden. Hier hilft die Datenträgerverwaltung:
Die Dateien unter S:\. sind wieder von heute Morgen:
Vor der Wiederherstellung sichere ich noch die aktuelle Datenbank in ein lokales Verzeichnis:
Dann stelle ich die Dateien wieder her. Da mein Exchange Server keinen direkten Zugriff auf meinen Sicherungsserver hat, stelle ich die Dateien über ein Austausch-Netzlaufwerk bereit:
Der Cluster-Dienst lässt sich leider immer noch nicht starten:
Daher versuche ich es jetzt mit einer Deinstallation des Features „Failover-Cluster“:
Interessanterweise hat die Entfernung funktioniert:
Es ist für den Abschluss ein Neustart erforderlich.
Wieder startet der Assistent und sucht nach verbliebenen Abhängigkeiten. Das Entfernen des Clusters hat funktioniert! Die Deinstallation kann gestartet werden:
Leider ist die Freude von sehr kurzer Dauer. Das System hat keinen ausreichenden Arbeitsspeicher:
Eigentlich ist der Server mit 14GB RAM ausgestattet und hat keine Last mehr. Das sollte doch genügen. Wo also wird der Arbeitsspeicher verbraucht? Ha: das Setup selber belegt 10GB!!!
Nach einer Neuanmeldung probiere ich es erneut. Dieses Mal läuft das Setup weiter. Der Prozess selber bindet wieder innerhalb von Sekunden fast den gesamten Arbeitsspeicher:
Die Meldung vom Betriebssystem lässt nicht lange auf sich warten. Aber das Setup läuft weiter und gibt auf einen Schlag den Arbeitsspeicher wieder frei. Was soll man davon halten…
Jetzt kommt die Deinstallation voran:
Nach einigen Minuten ist der Vorgang abgeschlossen. Ein Neustart steht aus:
Während der Server WS-MX2 neustartet, kontrolliere ich im Exchange Admin Center die Lage. Der Server wird nicht länger angezeigt:
Nachdem der Server seinen Neustart abgeschlossen hat, archiviere ich die Logfiles des Setups. Falls doch etwas schief gelaufen ist, kann ich hier im Nachgang den Fehler suchen:
Das Logfile-Archiv verschiebe ich in meine administrative Freigabe:
Jetzt ist auf dem Server WS-MX2 nichts mehr vorhanden.
… ebenso wie die virtuelle Maschine selber:
Der Name WS-MX2 ist nun frei. Daher benenne ich die vorbereitete virtuelle Maschine um:
Der neue Server erhält weitere Ressourcen. 16GB, 8 vCPU und eine neue virtuelle Festplatte für die Datenbanken kommen dazu:
Bereitstellung des neuen Mailservers (MX2019)
Wie üblich ist ein Neustart erforderlich. Während dieser Zeit bereite ich das Active Directory Computerkonto für die Übernahme vor:
Wieder angemeldet passe ich die IPv4-Konfiguration an. Auch die IP-Adresse 192.168.100.13/24 verwende ich wieder. So spare ich mir die Anpassungen in der Firewall und im LoadBalancer:
Für den Domain Join bereite ich einen Account vor:
15 Minuten sind dafür mehr als ausreichend. Ich nehme den neuen Server in die Domain auf. Dabei übernimmt er das Computerkonto und somit die Identität des alten Mailservers:
Nach einem weiteren Neustart werden die Gruppenrichtlinien angewendet. Ich starte noch einmal ein Windows Update. Dieses Mal kommen die Daten von meinem WSUS:
Durch die manuelle Aktivierung der Aktualisierung meldet sich der Server im WSUS:
Interessanterweise werden Updates auf dem WSUS gefunden. Eigentlich war ja schon alles installiert. Aber ok – dann installiere ich diese eben noch einmal:
Während der Aktualisierung kümmere ich mich um die neue Festplatte. Darauf erstelle ich eine neue Partition. Zuerst muss sie aber aktiviert werden:
Das neue Volume kann einfach mit dem Server-Manager erstellt werden:
Als Dateisystem verwende ich das von Microsoft für Exchange Server 2016+ empfohlende ReFS. Meine Datensicherung ist damit kompatibel:
Jetzt installiere ich noch ein paar Rollen und Features, die nicht zwingend zum Exchange Server gehören. Mit System Insights kann ich den Trend der Serverbelastung später mit dem Windows Admin Center überwachen. Und die Windows Server Sicherung soll später für die Datensicherung des SystemStates verwendet werden:
Die Rollen- und Feature-Installation und die Windows Updates erfordern einen Neustart:
Für den Zugriff auf das neue Volume erstelle ich im Active Directory zwei neue Gruppen GG-Admin-MX-Storage und LD-Admin-MX-Storage. Die GG ist in der LD als Mitglied verschachtelt:
Auf dem neuen Volume ändere ich die Stammberechtigung ab. Damit ist ein einfacher Zugriff auf das Volume nicht mehr möglich:
Diese Konfiguration ist für mein Rollenzugriffs-Konzept gedacht. So kann ich später den Zugriff auf die Datenbank-Partition explizit delegieren.
Der Sicherungstask wird mit einem Group Managed Service Account (gMSA) ausgeführt. Beim Speichern der Aufgabe habe ich einen Dummy-Account eingetragen, da ich das Passwort des gMSA nicht kenne – die Server holen sich diese Information geschützt vom Domain Controller. Aber ohne Passwort kann ich den Task nicht speichern:
Mit meiner PowerShell-GUI „gMSA-Admin“ konfiguriere ich nun den Sicherungstask remote vom Domain Controller aus neu:
Bevor ich mit der Installation beginne, starte ich die Datensicherung:
Sie dauert nur wenige Minuten. Mit dieser Sicherung kann ich ein Rollback durchführen, wenn bei der Installation vom Exchange Server etwas schief läuft.
Die Aktualisierung des Active Directory starte ich direkt vom zukünftigen Exchange Server WS-MX2 aus. Dafür werden die RSAT-Features für das Active Directory erforderlich. Diese installiere ich mit der PowerShell:
Eine weitere Voraussetzung ist das aktuelle .net-Framework 4.8. Dieses ist selbst auf einem Windows Server 2019 nicht standardmäßig installiert:
Mit einem Offline-Installer ist das aber schnell nachgeholt:
Nach dem Setup prüfe ich wieder mit Windows Updates auf Aktualisierungen. Natürlich wird auch hier etwas gefunden:
Das Setup und das Update beende ich mit einem Neustart. Jetzt passt die installierte Version:
Ich möchte die Vorbereitung des Active Directory losgelöst vom Exchange Server Setup durchführen. Das bietet sich immer an, wenn man mehr als einen Domain Controller verwendet. Anderenfalls könnte die Aktualisierung auf einem DC1 angewendet werden, das Setup aber mit dem DC2 fortfahren. Die Replikation der beiden Domain Controller ist aber keine Echtzeit. Und gerade nach Schema-Veränderungen wird sie zusätzlich verzögert. Das Setup des neuen Exchange Servers kann so in einen Fehler laufen. Das will ich gerne vermeiden. Daher starte ich die Aktualisierung meiner Domain und warte dann auf die Replikation der Domain Controller.
Die Aktualisierung wird mit dem Installations-ISO und dem Aufruf der darin enthaltenen setup.exe durchgeführt. Ich starte den Befehl auf dem neuen Exchange Server.
Ich starte den Befehl auf meinem neuen Exchange Server. Mein AD ist sauber. Und im Problemfall gibt es gleich eine Forest Recovery… Das ist der Befehl:setup.exe /prepareschema /IAcceptExchangeServerLicenseTerms
Der nächste Befehl aktualisiert die Configuration-Partition der Gesamtstruktur:
Abschließend starte ich noch die Aktualisierung der Domain Partition. Da ich nur eine Domain im meinem Active Directory Forest verwende muss ich den Befehl auch nur einmal starten:
Nach wenigen Minuten ist alles erledigt. Die beim Aktualisieren geschriebenen Logfiles im Verzeichnis c:\ExchangeSetupLogs archiviere ich im Admin-Share. Logfiles von relevanten Veränderungen sind später immer wertvoll bei der Fehlersuche:
Nach dem ausführlichen Lesen der EULA bestätige ich diese:
Ich möchte gerne die volle Kontrolle über den Installationsprozess. Daher wähle ich diese Option aus:
Im nächsten Fenster wähle ich die automatische Installation fehlender Komponenten aus. Bei den Rollen enthält die Rolle Mailbox seit Exchange Server 2016 die Datenbankrolle, den ClientAccess, das Unified Messaging und den Hubtransport-Service. Der Edge-Transport-Service ist wie in den Vorgängerversionen auch ein vorgelagerter SMTP-Server für die DMZ. Beide Rollen schließen sich gegenseitig bei der Installation aus:
Die Installation soll im Standardverzeichnis landen. So kann ich mit einem SystemImage und der Sicherung der Systempartition das Betriebssystem und den Exchange Server als eine Einheit sichern und wiederherstellen:
Die Prüfung auf Schadsoftware muss später manuell konfiguriert werden. Daher belasse ich die Einstellung unverändert:
Das Setup installiert die erforderlichen Rollen und Features und bleibt mit einer Auflistung fehlender Voraussetzungen stehen:
Beide Komponenten sind kein Problem. Sie können kostenlos bei Microsoft heruntergeladen werden. Ich habe beide bereits im Software-Share auf meinem Fileserver vorrätig:
Die Installationen waren wie immer sehr unspektakulär. Mit einer Wiederholung der Voraussetzungsprüfung kehre ich zum Setup des neuen Exchange Servers zurück. Dieses Mal sind alle Voraussetzungen erfüllt:
Bevor ich das Setup starte, deaktiviere ich den Windows Defender. Dieser ist sein Windows Server 2016 eine bereits installierte Schutzkomponente. Leider grätscht er gerne in das Setup rein. Daher beende ich ihn. Das geht bei mir nur mit einer Gruppenrichtlinie, da eine andere GPO den Defender aktiviert. Mit einem Sicherheitsfilter auf der GPO treffe ich nur den neuen Exchange Server:
Zusätzlich starte ich auf einem anderen Server ein PowerShell-Script. Dieses scannt im Sekundentakt das Active Directory auf ServiceConnectionPoints (SCP). Hier trägt jeder Exchange Server seine URL ein, die von Outlook-Clients und ActiveSync-Clients zum Auffinden der Server abgefragt werden können. Der Default-Wert der URL enthält dabei immer der FQDN des Servers: https://<FQDN>/autodiscover/autodiscover.xml
Ich starte das Script auf einem anderen Server: Jetzt sind alle Komponenten bereitgestellt. Ich starte das immer noch wartende Setup: Einige Minuten später ist es erfolgreich abgeschlossen und muss mit einem Neustart finalisiert werden: Auf dem anderen Server kontrolliere ich mein Script zur SCP-Korrektur. Im Logging finde ich den Zeitpunkt mit dem falschen Record. Und eine Sekunde später war er gefixt: Im Active Directory kann man mit ADSIEdit den Record natürlich auch sehen: Jetzt wird es auch wieder Zeit für den Defender. Ich entferne den Sicherheitsfilter der GPO und aktualisiere die Gruppenrichtlinien auf dem Server WS-MX2: Die vom Setup geschriebenen Logfiles archiviere ich wieder in meinem Admin-Share: Das Setup ist jetzt abgeschlossen. Jetzt folgt die Konfiguration der für mich relevanten Exchange Server Rollen.
Konfiguration der CAS-Rolle
Zuerst stelle ich in der PowerShell-ISE eine Verbindung zum Exchange Server her:
Intern wie extern verwende ich den gleichen Namespace. Die DNS-Server liefern dazu je nach Netzwerk die interne oder die externe IPv4-Adresse des LoadBalancers. Zeile 69 ändert übrigens den URL-Eintrag im Active Directory für das Autodiscover – der ServiceConnectionPoint, den mein Script vorhin schon veränderte:
Die Zeilen laufen anstandslos durch.
Jetzt kann ich das Zertifikat an die beiden Services SMTP und IIS binden. Die Warnmeldung zeigt die aktuelle Verwendung eines selbstsignierten Zertifikates an. Mit Freuden bestätige ich sie:
Eine kurze Kontrolle im Internet Information Service Manager (IIS-Manager) zeigt das eingebundene Zertifikat:
Ich starte auf dem neuen Exchange Server die Management Shell und starte das Script mit den 2 Befehlen:
Das war recht einfach. Eine kleine Kontrolle in der PowerShell-ISE bestätigt den Import:
Jetzt rekonfiguriere ich noch die relevanten virtuellen Verzeichnisse. Das hätte ich natürlich auch vorher schon erledigen können. Aber jetzt passt es besser rein:
Damit ist der ClientAccessService auf dem neuen WS-MX2 fertig konfiguriert.
Das war auch zu erwarten, da der Loadbalancer den neuen Server nicht anspricht. Man erkennt bei genauer Betrachtung dessen Maintenance-State:
Für meinen Test schwenke ich nun die beiden Server im Loadbalancer: damit verhindere ich den Zugriff auf den alten Mailserver und zwinge die Clients, eine Verbindung zum neuen Server herzustellen. In größeren Umgebungen geht das natürlich etwas anders…
Mein Outlook hat von der Aktion nichts bemerkt. Es ist einfach zu träge und zudem sind die Verbindungen auch nicht dauerhaft etabliert:
Im Loadbalancer sieht man deutlich, dass nun alle Verbindungen den neuen Server verwenden:
Einen weiteren Test nehme ich mit meinem Browser vor. Hier rufe ich intern die OWA-Webseite auf. Auch diese wird korrekt angezeigt:
Ebenso bleibt mein Smartphone mit den Mailboxen verbunden. Die Rolle CAS kann also auf dem neuen Server verwendet werden!
Jetzt werden die Verbindungen über beide Server verteilt:
Damit ist der Aufbau der ClientAccessServer-Rolle abgeschlossen.
Konfiguration der HTS-Rolle
Ich beginne mit der Verschiebung der Transport-Datenbank. Diese liegt natürlich im Systemlaufwerk. Sie kann aber durchaus sehr groß werden. Daher verschiebe ich sie auf die Partition mit den anderen Datenbanken. Der dazugehörige PowerShell-Befehl muss aber in der Exchange Management-Shell ausgeführt werden. Mein Script rendert dazu den Befehl:
Mit Copy & Paste übertrage ich den Befehl in die Management-Shell. Diese muss als Administrator privilegiert ausgeführt werden. Der Transport-Dienst wird dabei kurz angehalten. Das stellt aber kein Problem dar:
Und das war es auch schon.
Das erste Script möchte eine Verbindung zum Internet aufbauen, um neue Module herunterzuladen. Das scheint aber nicht zu funktionieren:
Die Ursache ist schnell gefunden: Meine Firewall blockiert die Downloads, da meine Mailserver wie alle anderen auch per Default keinen Internetzugriff haben:
Fürs Erste erlaube ich die Protokolle http und https. Später werde ich die erforderlichen URL zusätzlich beschränken. Diese beiden Regeln in meiner PFSense-Firewall sind für den Internet-Zugriff aus dem Server-VLAN zuständig. Die Quellserver habe ich dabei als Alias angelegt:
Nun editiere ich beide Aliase und trage den neuen Mailserver mit seiner IP-Adresse ein:
Ein Apply später wird die erste Verbindung aufgebaut:
Es dauert aber noch ein paar Minuten, bis das Script alles abgeschlossen hat:
Jetzt führe ich das Script zur Installation des AntiSpam-Agents aus:
Beide Scripte erfordern einen Neustart der Transport-Dienste:
Danach sind die Schutzkomponenten im HTS integriert:
Die Konfiguration ist bereits im Active Directory abgelegt. Daher muss hier nichts angepasst werden.
- Ich editiere zuerst den „Default Frontend“-Konnektor. Dieser nimmt normalerweise von allen IP-Adressen auf Port 25 Mails entgegen. Dabei wird aber immer der FQDN des Mailservers übertragen. Mein Serverzertifikat ist aber nur für den externen Namen email.ws-its.de ausgestellt. Den FQDN des System-Konnektors kann man nicht verändern. Daher reduziere ich im ersten Befehlsblock die IP-Adressen des Konnektors auf interne Adressen.
- Im zweiten Block aktiviere ich die Protokollierung auf allen Default-Konnektoren. Damit kann ich später Probleme im Mailfluss leichter erkennen.
- Im dritten Block baue ich einen neuen Empfangs-Konnektor. Dieser darf von allen IPv4-Adressen verwendet werden. Und als FQDN soll mein Mailserver den richtigen Namen – der auch im TLS-Zertifikat steht – verwenden.
- Sowohl mein Monitoring-Server mit der IP-Adresse 192.168.100.18 als auch der Loadbalancer mit der IP-Adresse 192.168.100.250 senden regelmäßige Verbindungsaufbauten zum Mailserver. Diese will ich nicht in meinem Logging haben. Daher baue ich für beide IPs einen weiteren Empfangs-Konnektor. Dieser hat dann keine Protokollierung.
So schicke ich die Befehle ab. Und hier sieht man die Ergebnisse:
Es fehlt noch der Zugriff auf den Sende-Konnektor. Dieser ist serverübergreifend. Also muss ich nur den neuen Server in die Liste der Source-Transport-Server mit aufnehmen:
Damit kann mein neuer WS-MX2 Mails senden und empfangen.
Das ist sehr schön im unteren, rechten Bereich erkennbar. Der alte Server hat Pause und der neue Server unterhält sich mit einem Server im Internet:
Das ist kein Zufall. Zuvor habe ich mit dem Test-Tool von mxtoolbox einen Mailversand vorbereitet. In der Webausgabe kann ich mir das Ergebnis ansehen:
Und auch mit meiner PowerShell-GUI kann ich den Mailfluss grafisch beobachten:
Hier funktioniert alles. Daher schalte ich die Rolle frei und aktiviere im Loadbalancer wieder beide Server:
Damit ist auch der Mailfluss konfiguriert.
Konfiguration der MBS-Rolle
Ich muss die Mailboxen, die in den alten Datenbanken enthalten sind, auf den neuen Server verschieben. Eine gemeinsame Datenbankverfügbarkeitsgruppe scheidet wegen der unterschiedlichen Betriebssysteme (Win 2016 und Win2019) und wegen der unterschiedlichen Exchange Server Versionen aus. Also erstelle ich neue Datenbanken auf dem neuen Server und verschiebe die Mailboxen. Danach kann ich die alten Datenbanken entfernen.
Wichtig ist aber, dass jede Datenbank einen eindeutigen Bezeichner hat. Da ich meine alten Namen später wiederverwenden möchte, hänge ich an jede neue DB einfach ein „-neu“ an. Die Pfade der Dateien im Dateisystem kann ich aber schon an den Zielnamen anpassen.
Die neue Default-Datenbank benötige ich nicht. Daher möchte ich sie löschen:
Da ist aber schon etwas enthalten. Mit der PowerShell lässt sich das Geheimnis schnell lüften:
OK, dann plane ich um. Die Datenbank erhält einen neuen Namen „DB-System-neu“ und wird auf die Partition der Exchange Datenbanken verschoben. So ist die erste der 4 neuen DBs fertig. Hier gibt es den neuen Namen:
Und hier ein neuen Zuhause:
Jetzt benötige ich noch 3 weitere Datenbanken. Nebenbei bemerkt: an einer solchen Stelle ist ein Redesign der Mailboxdatenbanken sehr gut platzierbar. Mein Layout passt mir aber. Die 3 neuen Datenbanken sind mit wenigen Zeilen angelegt:
Im Exchange Admin Center sind nun 8 Datenbanken enthalten:
Jede Datenbank hat diese Dateien auf der neuen Exchange-Partition. Auffällig ist bei Exchange Server 2019, dass der Indizierungsordner fehlt. Das ist eine lange ersehnte Verbesserung: Der Suchindex einer Datenbank ist nun IN der Datenbank enthalten und kann auch mit der Replikation in einer Verfügbarkeitsgruppe auf einen anderen Server repliziert werden. Vorher musste jeder Server die Datenbank lokal durchsuchen und indizieren!
Jetzt kommen noch ein paar Einstellungen auf alle neuen Datenbanken:
Eigentlich benötige ich für einen DAG-Cluster mehr als einen Server. Aber es ist nicht unmöglich.
Der alte Cluster hat eine Cluster-IP:
Den neuen Cluster erstelle ich ohne IP-Adresse mit einem anderen Namen. Den Zeugenserver kann ich aber weiterverwenden. Beim Anlegen der DAG erhalte ich eine Warnmeldung:
Ein Blick ins Active Directory zeigt an, dass die Gruppe tatsächlich kein Mitglied der lokalen Administratoren auf dem Fileserver WS-FS3 ist. Daher verschachtele ich sie in die richtige Gruppe.
Weiter geht es mit dem Aufbau der DAG. Bisher ist sie nur ein Datensatz im Active Directory. Erst mit dem ersten Mitglied wird sie erstellt:
Mit der im Hintergrund replizierten Gruppenmitgliedschaft konnte die neue DAG erstellt werden. Ohne eine Cluster-IP wird die Broadcast-Adresse als Platzhalter im EAC angezeigt:
Ich verändere die Schutzgruppe:
Die alten Sicherungseinträge entferne ich einfach:
Ein paar Klicks später ist die alte Schutzgruppe sauber:
Nun muss ich noch die alte Agent-Verbindung zum nicht mehr vorhandenen Windows Server 2016 WS-MX2 entfernen. Das geht leider nicht mit der grafischen Oberfläche. Daher verwende ich einen PowerShell-Befehl:
Jetzt hat der DPM den alten Mailserver vergessen:
Auf dem neuen Mailserver installiere ich den Agent des DPM. Das geht lokal einfach am besten. Auf meinem DPM hatte ich dazu eine Freigabe erstellt:
Nach der Installation muss der Agent auf seinen neuen DPM-Server vorbereitet werden. Dabei werden Firewall-Ausnahmen erstellt:
Für die Verbindung des DPM-Agents mit dem DPM-Server benötige ich eine Kennung, die administrative Rechte auf dem DPM-Server (Standard) und den Exchange Servern (MX) hat. Durch meine administrativen Trennungen mit den GPOs gibt es einen solchen Account aktuell nicht. Er wird aber nur kurz benötigt. Zudem darf er kein Mitglied der Gruppe „Protected Users“ sein. Für solche Fälle habe ich den Account „admin-setup“. Dieser hat keine statischen Gruppenmitgliedschaften. Mit meinem PAM-PowerShell-Script weise ich die zeitlich begrenzten Mitgliedschaften zu:
Weiter geht es im DPM in der Verwaltungsseite der Management-Konsole. Hier kann ich einen neuen Agent mit dem Schalter „Hinzufügen Server“ einrichten:
Wichtig ist, dass nur noch eine Verbindung aufgebaut werden muss. Der Agent ist ja bereits installiert:
Jetzt suche ich den Server aus der Liste aus. Nach dem Hinzufügen wird er nicht mehr angezeigt. Das ist ein Bug:
Anschließend gebe ich die Anmeldeinformationen des zuvor konfigurieren Admin-Accounts ein:
Und dann kann der DPM beginnen:
Der neue Mailserver wird angezeigt:
Weiter geht es mit der Konfiguration der Datensicherung. Ich möchte die Definitionen der aktuellen Schutzgruppe weiterverwenden. Also starte ich die Änderung:
Zu der alten DAG wähle ich die 4 neuen Datenbanken der neuen DAG aus:
Die Überprüfung mit eseutil muss ich an dieser Stelle herausnehmen. Ein DPM benötigt dazu explizit die passende eseutil.exe einer Exchange Server Version. Ich habe aber gerade eine Mischumgebung. Hier komme ich nach Abschluss der Migration noch einmal zurück.
Die 4 Datenbanken sollen mit einem Full-Backup gesichert werden: Der Speicherplatz wird in einem Pool organisiert: Die Sicherung darf sofort starten. Noch sind die Datenbanken klein. Das sollte nicht lange dauern: Und nach wenigen Minuten sind die leeren Datenbanken gesichert:
Die Verschiebungen plane ich mit ein paar PowerShell-Zeilen. Von jeder Mailbox lese ich den Namen der alten DB aus un d verschiebe sie in die DB mit dem alten Namen plus dem Suffix „-neu“. Archive werden dabei ebenfalls berücksichtigt. Damit es besonders schnell geht, weise ich die Verschiebung mit der Priorität „emergency“ an. Es gibt schließlich bald Abendessen!
Mit „emergency“ wandern die Mailboxen in Windeseile auf den neuen Server:
Abschließend entferne ich die Verschiebeanforderungen:
Damit ist auch die dritte Rolle produktiv. Die Mailboxbenutzer haben von den Verschiebungen übrigens nichts mitbekommen. Verbindungen von den Clients werden immer zum CAS-Server aufgebaut. Nur dieser muss die neue Location eines Mailbox-Elementes im Hintergrund lernen. Der Vorgang ist vollkommen transparent!
Nacharbeiten
Das hier ist der Aufruf in der geplanten Aufgabe. Alle Logfiles (auch die des IIS), die älter sind als 14 Tage, werden gelöscht:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe “& {Get-ChildItem -Path ‘C:\Program Files\Microsoft\Exchange Server\V15\Logging’,’C:\inetpub\logs\LogFiles’ -Include ‘*.log’,’*.bak’,’*.blg’ -Recurse | Where-Object { $_.LastWriteTime -le (Get-Date).AddDays(-14) } | Remove-Item -Confirm:$false -ErrorAction SilentlyContinue}”
Dazu zählt auch mein selbstgeschriebener PowerShell-Script-Sensor „BASE“. Mit diesem kann ich die typischen Werte des Betriebssystems überwachen:
Der von mir geschriebene Sensor „MX-CAS“ überwacht die einzelnen Webservices des Client-Access-Services:
Ebenfalls selbst geschrieben überwacht der Sensor „DB-Health“ den Zustand der Datenbanken. Und im Vergleich zu dem Standard-Sensor von PRTG kann er auch mit dem neuen Indizierungsmechanismus vom Exchange Server 2019 umgehen:
Und zuletzt liefert mir ein selbst programmierter Sensor alle ServerComponentStates des Servers:
Zusammenfassung
Den Artikel gibt es wie gewohnt hier als pdf zum downloaden. Und zusätzlich habe ich in diesem ZIP-Archiv die beiden PowerShell-Scripte meiner Migration bereitgestellt.
Stay tuned!
Hier geht es zum Übersichtsbeitrag meiner Serie „Migration auf Windows Server 2019“.