Search-Mailbox: Unerwünschte Mails aus Postfächern suchen/entfernen

Bei einer SPAM-Welle ist es eventuell nötig, dass bestimmte Mails direkt aus dem Postfach der Benutzer entfernt werden müssen. Dazu ist eine Abstimmung mit dem DSB nötig, da es hier um einen direkten Eingriff in die Postfächer geht. Außerdem ist ein sehr umsichtiger Umgang mit diesem Befehl nötig, da durch die Eingabe von fehlerhaften Parametern ganze Postfächer geleert werden können!
Zum Einsatz kommt hier das cmdlet Search-Mailbox, welches von Microsoft offiziell abgekündigt wurde. Dieses wurde offiziell durch das cmdlet New-ComplianceSearch ersetzt, wird aber immer noch onPrem und in der Cloud unterstützt.
Warum verwende ich trotzdem das alte cmdlet?
Da das New-ComplianceSearch keinen DELETE mehr zulässt, sondern nur noch suchen kann (Datenschutzkonform).
Gibt es Beschränkungen des cmdlets?
Search-Mailbox hat eine Begrenzung von 10.000 Ereignissen pro Postfach und muss ggf. mehrfach ausgeführt werden.
Quelle Microsofts Docs: Search-Mailbox (ExchangePowerShell) | Microsoft Docs
Damit man das cmdlet überhaupt ausführen darf sind die zwei folgenden Exchange-Administrator-Rollen für den AD-Benutzer, welches den Befehl ausführt, nötig:
Discovery Management
Exchange Mailbox Import Export

Das cmdlet hat drei Funktions-Modis:
LogOnly = Es wird nur ein Bericht erstellt, aber keine Mail gelöscht/verschoben
ohne Parameter = Es wird ein bericht erstellt und die gefundenen Mails werden in die TargetMailbox kopiert bleiben aber auch im originalen Postfach vorhanden
DeleteContent = Es wird ein bericht erstellt und die gefunden Mails werden in die Target;ailbox verschoben - die Mail ist im originalen Postfach NICHT mehr vorhanden

Der Bericht sieht dann wie folgt aus:

Beispiele
Beispiel 1 - Postfach durchsuchen und nur Bericht erstellen
Hier wird das Postfach von MMustermann durchsucht nach Mails mit dem Betreff "Virus" und Eingang am 07./08.02.2022. Es wird nur ein Bericht erstellt und keine Mails gelöscht oder kopiert. Der Bericht erfolgt an mailadmin@xyz.de im Ordner SPAM
Search-Mailbox -Identity MMustermann -TargetMailbox mailadmin@xyz.de -TargetFolder "SPAM" -SearchQuery {Subject:"Virus" AND received:"07/02/2022..08/02/2022"} -LogLevel Full -LogOnly



Beispiel 2 - Postfach durchsuchen, Bericht erstellen, Mails kopieren, original Mails im Benutzerpostfach nicht löschen
Hier wird das Postfach von MMustermann durchsucht nach Mails mit dem Betreff "Virus" und Eingang am 07./08.02.2022. Es wird ein Bericht erstellt und die Mails in das Postfach mailadmin@xyz.de in den Ordner SPAM kopiert. Der Bericht erfolgt an mailadmin@xyz.de im Ordner SPAM. Die originalen Mails Bleiben beim Benutzer ERHALTEN.
Search-Mailbox -Identity MMustermann -TargetMailbox mailadmin@xyz.de -TargetFolder "SPAM" -SearchQuery {Subject:"Virus" AND received:"07/02/2022..08/02/2022"} -LogLevel Full



Beispiel 3 - Postfach durchsuchen, Bericht erstellen, Mails kopieren, original Mails im Benutzerpostfachr LÖSCHEN
Hier wird das Postfach von MMustermann durchsucht nach Mails mit dem Betreff "Virus" und Eingang am 07./08.02.2022. Es wird ein Bericht erstellt und die Mails in das Postfach mailadmin@xyz.de in den Ordner SPAM verschoben. Der Bericht erfolgt ebenfalls an mailadmin@xyz.de im Ordner SPAM. Die verschobenen Mails werden in Unterordner pro Postfach abgelegt inkl. der Ordner Struktur, in der sie gefunden wurden.
Search-Mailbox -Identity MMustermann -TargetMailbox mailadmin@xyz.de -TargetFolder "SPAM" -SearchQuery {Subject:"Virus" AND received:07/02/2022..08/02/2022} -LogLevel Full -DeleteContent -Force




Beispiel 4 - Postfachdatenbank durchsuchen, Bericht erstellen, Mails kopieren, original Mails im Benutzerpostfach LÖSCHEN
Hier werden alle Postfächer der Postfachdatenbank MBXDB1 nach Mails mit dem Betreff "Virus" und Eingang am 07./08.02.2022 durchsucht. Es wird ein Bericht pro Postfach erstellt und die Mails in das Postfach mailadmin@xyz.de in den Ordner SPAM verschoben. Der Bericht erfolgt ebenfalls an mailadmin@xyz.de im Ordner SPAM. Die verschobenen Mails werden in Unterordner pro Postfach abgelegt inkl. der Ordner Struktur, in der sie gefunden wurden.
Get-Mailbox -Database "MBXDB1" -resultsize unlimited | Search-Mailbox -TargetMailbox mailadmin@xyz.de -TargetFolder "SPAM" -SearchQuery {Subject:"Virus" AND received:07/02/2022..08/02/2022} -LogLevel Full -DeleteContent -Force


Exchange Powershell: Prüfen der Exchange Schema Version

Problem:
Bei der Installation eines kumulativen Updates der Exchange Server ist meistens nicht ganz klar, ob ein Schema Update nötig ist oder nicht. Microsoft gibt meistens die nötige Schema Version an.

Lösung:
Um zu prüfen, ob ich die richtige Version bereits verwende, habe ich mir ein PowerShell-Skript geschrieben, das die Exchange Schema Version ausgibt:

# Exchange Schema Version

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn

$sc = (Get-ADRootDSE).SchemaNamingContext
$ob = "CN=ms-Exch-Schema-Version-Pt," + $sc
$ru = "RangeUpper: $((Get-ADObject $ob -pr rangeUpper).rangeUpper)"

$dc = (Get-ADRootDSE).DefaultNamingContext
$ob = "CN=Microsoft Exchange System Objects," + $dc
$ovd = "ObjectVersion (Default): $((Get-ADObject $ob -pr objectVersion).objectVersion)"

$cc = (Get-ADRootDSE).ConfigurationNamingContext
$fl = "(objectClass=msExchOrganizationContainer)"
$ovc = "ObjectVersion (Configuration): $((Get-ADObject -LDAPFilter $fl -SearchBase $cc -pr objectVersion).objectVersion)"

Write-Output $ru $ovd $ovc


Eine schöne Übersicht der jeweiligen Schema Version findet ihr bei Ali:
Ali Tajran: Exchange schema versions (up to date list)

Exchange 2016: Fehler "Version mismatch was detected" beim Verschieben von Postfächern

Problem:
Ich habe bei der Migration von Exchange 2013 auf 2016 beim Versuch Postfächer zu verschieben folgende Fehlermeldung bekommen:
Ich konnte keine Postfächer auf den neuen Exchange 2016 verschieben

Lösung:
Das Problem ist, dass das Migration-Postfach erst auf den neuen 2016er verschoben werden muss und sich damit auch die Version anhebt. Erst dann ist eine Migration von anderen Postfächern möglich. Das Migrationspostfach ermitteln Sie mittels Powershell:
Get-Mailbox Migration* -Arbitration

Ich habe das Postfach dann einfach in die neue Datenbank auf dem Exchange 2016 verschoben:
Get-Mailbox Migration* -Arbitration | New-MoveRequest -TargetDatabase "Datenbankname"

Nach der erfolgreichen Migration kann man sich auch die Versionsnummer anzeigen lassen. Diese sollte nun nicht mehr 15.0 sondern 15.1 lauten:
Get-Mailbox Migration* -Arbitration | ft Name,AdminDisplayVersion

Jetzt kann man die anderen Postfächer problemlos migrieren.
Generell empfiehlt es sich die Systempostfächer zuerst umzuziehen. Um diese zu ermitteln habe ich auch ein Skript geschrieben: Microsoft Exchange: Ermittlung aller System-Postfächer (Monitoring, Arbitration etc.)

Exchange 2013/2016: Installationsanleitung für einen Exchange CU auf einen Single Server (kein DAG)

Hier meine Anleitung zur Installation eines Exchange CU auf einen einzelnen Exchange Server(kein DAG) - ist wahrscheinlich nicht vollständig, aber für mich steht hier das Wichtigste drin.

Vorher eventuelles Schema-Update prüfen und ggf. durchführen. Für ein sicheres Schema-Update habe ich auch bereits eine Anleitung geschrieben:
HTH: ActiveDirectory: Sicheres Schema-Update (ADPREP) mittels Replikations-Pause

Danach geht es mit den Vorbereitungen und Installation weiter:

- Benutzerspezifische Konfigurationsdateien sichern (z.B. Microsoft.Exchange.Store.Worker.exe.config)
- Backup-Zeiten prüfen und ggf. anhalten
- NAT für SMTP deaktivieren - Keine Mails kommen mehr herein, keine Client-Verbindungen mehr von extern
- HTTPS in NAT auf Firewall deaktivieren - Keine externen Client-Verbindungen mehr (nur wenn kein Reverse Proxy vorhanden)
- Reverse Proxy deaktivieren, falls vorhanden - kein OWA, ActiveSync und Outlook Anywhere
- Server herunterfahren und Snapshot erstellen (Sicherheit)
- Server neu starten - schließt auch alle eventuellen Installationsroutinen ab (Updates etc.)
- Virenscanner deaktivieren bei Installation (z.B. Defender: Set-MpPreference -DisableRealtimeMonitoring $true)
- Powershell Restriction deaktivieren: Set-ExecutionPolicy Unrestricted
- Server neu starten - zur Sicherheit
- AV-Status prüfen erneut prüfen: Get-Mppreference
- ISO mounten
- CMD als Administrator öffnen (Wichtig, wegen UAC)
- Setup aus CMD starten und erfolgreich durchlaufen lassen – kann dauern... (ca. 1 Stunde)
- Zuvor gesicherte, benutzerspezifische Konfigurationsdateien prüfen und ggf. wiederherstellen (Filedate prüfen)
- Serverneustart durchführen um Installation abzuschließen und wiederhergestellte Konfiguration zu aktivieren
- ReverseProxy bzw. HTTPS im NAT auf der Firewall wieder aktivieren
- NAT für SMTP wieder aktivieren - Testmail schicken!!
- Nach Update Funktionen prüfen: OWA, ActiveSync, Outlook Anywhere
- Backup ggf. wieder aktivieren
- Virenscanner aktivieren (z.B. Set-MpPreference -DisableRealtimeMonitoring $false)
- Snapshot löschen

Microsoft Exchange: Ermittlung aller System-Postfächer (Monitoring, Arbitration etc.)

Wenn ich einen Exchange Server migriere und alle Postfächer verschoben habe, dann passiert es mir regelmäßig, dass ich eines der Systempostfächer "vergesse" zu moven und bekomme dann beim löschen der Postfach-Datenbank einen Fehler.
Hier mal alle Befehle um die entsprechenden Postfächer zu finden und ggf. zu migrieren.
WICHTIG: Das muss man PRO Postfach-Datenbank machen, da z.B. die Monitoring-Postfächer pro Datenbank erstellt werden!

Vorweg mal der Befehl um alle Postfach-Datenbanken mit Namen anzuzeigen:
Get-MailboxDatabase -Status | ft name, databasesize


Hier nun die Befehle um die System-Postfächer anzuzeigen:
Get-Mailbox -Database "Name Postfachdatenbank" -Monitoring
Get-Mailbox -Database "Name Postfachdatenbank" -AuditLog
Get-Mailbox -Database "Name Postfachdatenbank" -Arbitration
Get-Mailbox -Database "Name Postfachdatenbank" -Archive
Get-Mailbox -Database "Name Postfachdatenbank" -RemoteArchive
Get-Mailbox -Database "Name Postfachdatenbank" -PublicFolder
Get-Mailbox -Database "Name Postfachdatenbank" -AuxAuditLog
Get-Mailbox -Database "Name Postfachdatenbank" -GroupMailbox

Exchange: Postfach per Powershell in PST exportieren (Eventuell Fehler: CommandNotFoundException)

Ich möchte gerne alte Postfächer von ausgeschiedenen Mitarbeiter in PST-Dateien exportieren. Das möchte ich aber ohne Outlook und zentral vom Server aus machen. Die Lösung findet man mit Powershell! Aber hier gibt es auch einen Fallstrick, den man wissen muss!

Es ist wichtig zu wissen, dass standartmäßig erst mal kein Benutzer berechtigt ist Postfächer in PST zu exportieren - auch der Administrator nicht! Man muss also einem Benutzer erstmal die Berechtigung geben. Dies erfolgt mit dem cmdlet New-ManagementRoleAssignment und der Rolle "Mailbox Import Export". Mit folgendem Befehl gebe ich dem Administrator die Berechtigung:
New-ManagementRoleAssignment –Role “Mailbox Import Export” –User domain\Administrator

Wenn man das vergißt, dann erhält man beim ersten Export folgenden Fehler:

The term 'New-MailboxExportRequest' is not recognized as the name of a cmdlet, function, script file, or operable progr
am. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:25
+ New-MailboxExportRequest <<<< -Mailbox 123456 -FilePath \\server\pstexport\export.pst
+ CategoryInfo : ObjectNotFound: (New-MailboxExportRequest:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

Nachdem man die Berechtigung vergeben hat, kann man mittels dem cmdlet New-MailboxExportRequest ein Postfach exportieren. Hier ein Beispielt für einen vollständigen Aufruf:
New-MailboxExportRequest -Mailbox misterx –FilePath \\server\pstexport\misterx.pst 

Falls es Probleme mit Zugriffsrechten auf das Export-Verzeichnis gibt, dann einfach einen Pfad auf dem Exchnage-Server wählen (z.B.: \\mailserver\c$\temp).
Der Export-Request startet dann und wird beim System, je nach Auslastung, abgearbeitet. Den Status des Exports erhält man mit folgendem Befehl:
Get-MailboxExportRequest

Status InProgress = läuft noch, Status Completed = Export abgeschlossen
Da die abgeschlossenen Export-Requests nicht automatisch gelöscht werden, würde ich diese zeitnah manuell löschen, da ab einer bestimmten Anzahl keine mehr angenommen werden (ähnlich wie bei den Mailbox-Move-Requests).
Um den z.B. alle erfolgreichen Export-Request zu löschen verwenden Sie folgenden Befehl:
Get-MailboxExportRequest -Status Completed | Remove-MailboxExportRequest
“Das einzig sichere System müsste ausgeschaltet, in einem versiegelten und von Stahlbeton ummantelten Raum und von bewaffneten Schutztruppen umstellt sein.”
Gene Spafford (Sicherheitsexperte)