Message Tracking
Nachrichten im Tracking-Log suchen und den Zustellweg belegen: Exchange on-prem, Exchange Online und Postfix.
Nach Absender und Empfänger suchen
Die Standardsuche: alle Ereignisse zu einer Absender-Empfänger-Kombination im gewählten Zeitraum, chronologisch sortiert.
Letzte 48 Stunden
Exchange on-prem
Get-MessageTrackingLog (Exchange) Bordmittel
Get-TransportService | Get-MessageTrackingLog -WarningAction 0 `
-Sender "sender@example.com" -Recipients "empfaenger@example.com" `
-Start (Get-Date).AddHours(-48) -End (Get-Date) -ResultSize Unlimited |
Where-Object { $_.Sender -notmatch "HealthMailbox" -and $_.Recipients -notmatch "Health" } |
Sort-Object Timestamp |
Format-Table Timestamp, EventId, Source, Sender, @{N="Recipients";E={$_.Recipients -join ","}}, MessageSubject -AutoSize journalctl / grep (Postfix) Bordmittel
journalctl -u postfix --since "48 hours ago" | grep -iE "from=<sender@example.com>|to=<empfaenger@example.com>" | tail -40
# Ohne systemd-Journal direkt im Log, dann aber ohne Zeitfilter:
grep -iE "from=<sender@example.com>|to=<empfaenger@example.com>" /var/log/mail.log | tail -40 Exchange Online
Get-MessageTraceV2 Zusatztool
Connect-ExchangeOnline
Get-MessageTraceV2 -SenderAddress "sender@example.com" -RecipientAddress "empfaenger@example.com" `
-StartDate (Get-Date).AddHours(-48) -EndDate (Get-Date) |
Sort-Object Received |
Format-Table Received, SenderAddress, RecipientAddress, Subject, Status -AutoSize Get-MessageTrace (alt) Zusatztool
# Vor der Umstellung auf V2; identische Parameter, kleinere Ergebnisgrenzen.
Get-MessageTrace -SenderAddress "sender@example.com" -RecipientAddress "empfaenger@example.com" `
-StartDate (Get-Date).AddHours(-48) -EndDate (Get-Date) Fenster am Vormittag
- Von (Datum und Uhrzeit)
-
2026-08-09T08:00Im Generator ändern → - Bis (Datum und Uhrzeit)
-
2026-08-09T12:00Im Generator ändern →
Exchange on-prem
Get-MessageTrackingLog (Exchange) Bordmittel
Get-TransportService | Get-MessageTrackingLog -WarningAction 0 `
-Sender "sender@example.com" -Recipients "empfaenger@example.com" `
-Start (Get-Date "2026-08-09 08:00") -End (Get-Date "2026-08-09 12:00") -ResultSize Unlimited |
Where-Object { $_.Sender -notmatch "HealthMailbox" -and $_.Recipients -notmatch "Health" } |
Sort-Object Timestamp |
Format-Table Timestamp, EventId, Source, Sender, @{N="Recipients";E={$_.Recipients -join ","}}, MessageSubject -AutoSize journalctl / grep (Postfix) Bordmittel
journalctl -u postfix --since "2026-08-09 08:00" --until "2026-08-09 12:00" | grep -iE "from=<sender@example.com>|to=<empfaenger@example.com>" | tail -40
# Ohne systemd-Journal direkt im Log, dann aber ohne Zeitfilter:
grep -iE "from=<sender@example.com>|to=<empfaenger@example.com>" /var/log/mail.log | tail -40 Exchange Online
Get-MessageTraceV2 Zusatztool
Connect-ExchangeOnline
Get-MessageTraceV2 -SenderAddress "sender@example.com" -RecipientAddress "empfaenger@example.com" `
-StartDate (Get-Date "2026-08-09 08:00") -EndDate (Get-Date "2026-08-09 12:00") |
Sort-Object Received |
Format-Table Received, SenderAddress, RecipientAddress, Subject, Status -AutoSize Get-MessageTrace (alt) Zusatztool
# Vor der Umstellung auf V2; identische Parameter, kleinere Ergebnisgrenzen.
Get-MessageTrace -SenderAddress "sender@example.com" -RecipientAddress "empfaenger@example.com" `
-StartDate (Get-Date "2026-08-09 08:00") -EndDate (Get-Date "2026-08-09 12:00") Zeitraum auf die Minute genau über die beiden Datumsfelder; bleiben sie leer, nimmt der Befehl die letzten 48 Stunden. Get-TransportService fragt alle Transportserver ab, nicht nur den lokalen. Die HealthMailbox-Zeilen (Microsofts eigene Überwachungsnachrichten) sind herausgefiltert, sonst gehen echte Treffer darin unter. Für Exchange Online braucht es das Modul ExchangeOnlineManagement; Get-MessageTraceV2 hat dort Get-MessageTrace abgelöst.
Nach Betreff suchen
Findet Nachrichten über einen Teil des Betreffs: der übliche Weg, wenn der Anwender nur «meine Rechnung von gestern» sagen kann.
- Betreff (Teil)
-
RechnungIm Generator ändern →
Exchange on-prem
Get-MessageTrackingLog (Exchange) Bordmittel
Get-TransportService | Get-MessageTrackingLog -WarningAction 0 `
-MessageSubject "Rechnung" `
-Start (Get-Date).AddHours(-48) -End (Get-Date) -ResultSize Unlimited |
Where-Object { $_.Sender -notmatch "HealthMailbox" } |
Sort-Object Timestamp |
Format-Table Timestamp, EventId, Sender, @{N="Recipients";E={$_.Recipients -join ","}}, MessageSubject -AutoSize journalctl / grep (Postfix) Bordmittel
journalctl -u postfix --since "48 hours ago" | grep -i "Rechnung" | tail -40
grep -i "Rechnung" /var/log/mail.log | tail -40 Exchange Online
Get-MessageTraceV2 Zusatztool
# V2 kennt keinen Betreff-Parameter, darum nachträglich filtern.
Get-MessageTraceV2 -StartDate (Get-Date).AddHours(-48) -EndDate (Get-Date) |
Where-Object { $_.Subject -like "*Rechnung*" } |
Format-Table Received, SenderAddress, RecipientAddress, Subject, Status -AutoSize On-prem sucht -MessageSubject als Teilzeichenkette. In Exchange Online filtert der Befehl nachträglich, weil Get-MessageTraceV2 keinen Betreff-Parameter kennt.
Eine Nachricht verfolgen
Zeigt alle Stationen einer bestimmten Nachricht anhand ihrer Message-ID, über alle Transportserver hinweg.
Message-ID aus dem Kopf
- Message-ID
-
<a1b2c3@example.com>Im Generator ändern →
Exchange on-prem
Get-MessageTrackingLog (Exchange) Bordmittel
Get-TransportService | Get-MessageTrackingLog -WarningAction 0 `
-MessageId "<a1b2c3@example.com>" `
-Start (Get-Date).AddHours(-48) -End (Get-Date) -ResultSize Unlimited |
Sort-Object Timestamp |
Format-Table Timestamp, ServerHostname, EventId, Source, SourceContext, @{N="Recipients";E={$_.Recipients -join ","}} -AutoSize grep (Postfix) Bordmittel
qid=$(grep -F "<a1b2c3@example.com>" /var/log/mail.log | grep -oE "[A-F0-9]{8,}" | head -1)
echo "Queue-ID: $qid"
grep "$qid" /var/log/mail.log Exchange Online
Get-MessageTraceV2 Zusatztool
Get-MessageTraceV2 -MessageId "<a1b2c3@example.com>" `
-StartDate (Get-Date).AddHours(-48) -EndDate (Get-Date) |
Format-List Received, SenderAddress, RecipientAddress, Subject, Status, MessageTraceId Die Message-ID steht im Kopf der Nachricht (unser Mail-Header-Analyzer zeigt sie). Spitze Klammern mitgeben, genau so wie im Header.
Zustellweg mit Zeitversatz
Der Zustellweg einer Nachricht als Kette mit Sekunden seit dem ersten Ereignis: zeigt, an welcher Station die Zeit verloren ging.
- Message-ID
-
<a1b2c3@example.com>Im Generator ändern →
Exchange on-prem
Get-MessageTrackingLog (Exchange) Bordmittel
$log = Get-TransportService | Get-MessageTrackingLog -WarningAction 0 `
-MessageId "<a1b2c3@example.com>" -Start (Get-Date).AddHours(-48) -End (Get-Date) -ResultSize Unlimited |
Sort-Object Timestamp
$first = $log[0].Timestamp
$log | Select-Object @{N="+Sek";E={[math]::Round(($_.Timestamp - $first).TotalSeconds,1)}},
Timestamp, ServerHostname, EventId, Source, @{N="Detail";E={$_.RecipientStatus -join " "}} |
Format-Table -AutoSize
# Kette: RECEIVE -> SUBMIT -> TRANSFER -> SEND (nach aussen) bzw. DELIVER (ins Postfach). grep / awk (Postfix) Bordmittel
qid=$(grep -F "<a1b2c3@example.com>" /var/log/mail.log | grep -oE "[A-F0-9]{8,}" | head -1)
grep "$qid" /var/log/mail.log | awk '{ print $1, $2, $3, $6, $7, $8, $9, $10 }' Exchange Online
Get-MessageTraceDetailV2 Zusatztool
$m = Get-MessageTraceV2 -MessageId "<a1b2c3@example.com>" -StartDate (Get-Date).AddHours(-48) -EndDate (Get-Date)
$m | ForEach-Object {
Get-MessageTraceDetailV2 -MessageTraceId $_.MessageTraceId -RecipientAddress $_.RecipientAddress |
Format-Table Date, Event, Action, Detail -AutoSize
} Die EventId-Kette liest sich als RECEIVE, SUBMIT, TRANSFER und zuletzt SEND (nach aussen) oder DELIVER (ins Postfach). FAIL oder DEFER markieren den Abbruch.
Fehlgeschlagene Zustellungen
Gruppiert die FAIL-Ereignisse nach Fehlergrund und zeigt die häufigsten zuerst: findet das Muster hinter einer Störung statt Einzelfälle.
Letzte 48 Stunden
Exchange on-prem
Get-MessageTrackingLog (Exchange) Bordmittel
Get-TransportService | Get-MessageTrackingLog -WarningAction 0 -EventId FAIL `
-Start (Get-Date).AddHours(-48) -End (Get-Date) -ResultSize Unlimited |
Where-Object { $_.Sender -notmatch "HealthMailbox" } |
Group-Object { $_.RecipientStatus -join " " } -NoElement |
Sort-Object Count -Descending | Select-Object -First 15 Count, Name grep (Postfix) Bordmittel
grep "status=bounced" /var/log/mail.log |
grep -oE "said: [0-9]{3}[ -][0-9.]* [^)]*" | sort | uniq -c | sort -rn | head -15 Exchange Online
Get-MessageTraceV2 Zusatztool
Get-MessageTraceV2 -Status Failed -StartDate (Get-Date).AddHours(-48) -EndDate (Get-Date) |
Group-Object RecipientAddress -NoElement | Sort-Object Count -Descending | Select-Object -First 15 Langsame Zustellungen finden
Rechnet je Nachricht die Dauer vom Eingang bis zur Zustellung aus und zeigt die langsamsten: die belastbare Antwort auf «die Mails sind so langsam».
Exchange on-prem
Get-MessageTrackingLog (Exchange) Bordmittel
$log = Get-TransportService | Get-MessageTrackingLog -WarningAction 0 `
-Start (Get-Date).AddHours(-48) -End (Get-Date) -ResultSize Unlimited |
Where-Object { $_.Sender -notmatch "HealthMailbox" }
$log | Group-Object MessageId | ForEach-Object {
$recv = ($_.Group | Where-Object EventId -eq "RECEIVE" | Sort-Object Timestamp | Select-Object -First 1).Timestamp
$done = ($_.Group | Where-Object { $_.EventId -in "DELIVER", "SEND" } | Sort-Object Timestamp | Select-Object -Last 1).Timestamp
if ($recv -and $done) {
[pscustomobject]@{ Sekunden = [math]::Round(($done - $recv).TotalSeconds, 1); Betreff = $_.Group[0].MessageSubject }
}
} | Sort-Object Sekunden -Descending | Select-Object -First 15 grep (Postfix) Bordmittel
grep -oE "delay=[0-9.]+" /var/log/mail.log | cut -d= -f2 | sort -rn | head -15
# delay = Gesamtzeit von der Annahme bis zur Zustellung in Sekunden. Exchange Online
Get-MessageTraceV2 Zusatztool
# EXO liefert keine Laufzeit je Nachricht; die Detailansicht zeigt die Stationen mit Zeitstempel.
Get-MessageTraceV2 -StartDate (Get-Date).AddHours(-48) -EndDate (Get-Date) |
Sort-Object Received -Descending | Select-Object -First 25 Received, SenderAddress, RecipientAddress, Subject, Status Top-Absender und -Empfänger
Zählt das Volumen je Absender und Empfänger: nützlich bei Lastfragen und beim Verdacht auf ein kompromittiertes Postfach.
Exchange on-prem
Get-MessageTrackingLog (Exchange) Bordmittel
$log = Get-TransportService | Get-MessageTrackingLog -WarningAction 0 -EventId RECEIVE `
-Start (Get-Date).AddHours(-48) -End (Get-Date) -ResultSize Unlimited |
Where-Object { $_.Sender -notmatch "HealthMailbox" }
"--- Top-Absender ---"
$log | Group-Object Sender -NoElement | Sort-Object Count -Descending | Select-Object -First 10
"--- Top-Empfaenger ---"
$log | ForEach-Object { $_.Recipients } | Group-Object -NoElement | Sort-Object Count -Descending | Select-Object -First 10 grep (Postfix) Bordmittel
grep -oE "from=<[^>]+>" /var/log/mail.log | sort | uniq -c | sort -rn | head -10
grep -oE "to=<[^>]+>" /var/log/mail.log | sort | uniq -c | sort -rn | head -10 Exchange Online
Get-MessageTraceV2 Zusatztool
$t = Get-MessageTraceV2 -StartDate (Get-Date).AddHours(-48) -EndDate (Get-Date)
"--- Top-Absender ---"
$t | Group-Object SenderAddress -NoElement | Sort-Object Count -Descending | Select-Object -First 10
"--- Top-Empfaenger ---"
$t | Group-Object RecipientAddress -NoElement | Sort-Object Count -Descending | Select-Object -First 10 Nach EventId filtern
Zeigt alle Ereignisse eines Typs, etwa nur FAIL, DEFER oder DELIVER.
- EventId
-
FAILIm Generator ändern →
Exchange on-prem
Get-MessageTrackingLog (Exchange) Bordmittel
Get-TransportService | Get-MessageTrackingLog -WarningAction 0 -EventId FAIL `
-Start (Get-Date).AddHours(-48) -End (Get-Date) -ResultSize Unlimited |
Sort-Object Timestamp |
Format-Table Timestamp, ServerHostname, Sender, @{N="Recipients";E={$_.Recipients -join ","}}, MessageSubject -AutoSize
# Gaengige EventIds: RECEIVE SEND DELIVER FAIL DEFER RESOLVE EXPAND REDIRECT DROP SUBMIT TRANSFER grep (Postfix) Bordmittel
grep -oE "status=[a-z]+" /var/log/mail.log | sort | uniq -c | sort -rn Exchange Online
Get-MessageTraceV2 Zusatztool
# EXO kennt keine EventIds, sondern einen Status:
# Delivered, Failed, Pending, Quarantined, FilteredAsSpam, Expanded
Get-MessageTraceV2 -Status Failed -StartDate (Get-Date).AddHours(-48) -EndDate (Get-Date) |
Format-Table Received, SenderAddress, RecipientAddress, Subject, Status -AutoSize Exchange Online kennt keine EventIds, sondern einen Status (Delivered, Failed, Pending, Quarantined, FilteredAsSpam).
Server-Überblick
Zählt die Ereignisse eines einzelnen Servers nach Typ und zeigt, ob das Tracking-Log überhaupt aktiv ist und wie lange es aufbewahrt wird.
- Exchange-Server
-
mbx01.example.comIm Generator ändern →
Exchange on-prem
Get-MessageTrackingLog (Exchange) Bordmittel
Get-MessageTrackingLog -Server mbx01.example.com -WarningAction 0 `
-Start (Get-Date).AddHours(-48) -End (Get-Date) -ResultSize Unlimited |
Where-Object { $_.Sender -notmatch "HealthMailbox" } |
Group-Object EventId -NoElement | Sort-Object Count -Descending Get-TransportService Bordmittel
Get-TransportService | Select-Object Name, MessageTrackingLogEnabled, MessageTrackingLogPath, MessageTrackingLogMaxAge Exchange Online
Get-ConnectionByClientTypeReport Zusatztool
# EXO hat keine einzelnen Server; die Auswertung laeuft ueber Mandant-Berichte.
Get-MailTrafficATPReport -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date) | Format-Table Date, EventType, MessageCount Standardmässig hält Exchange die Tracking-Logs 30 Tage; ältere Vorfälle sind damit nicht mehr belegbar.
Export für Tickets
Schreibt das Suchergebnis als CSV mit Semikolon und UTF-8: direkt in Excel zu öffnen und an ein Ticket anzuhängen.
Exchange on-prem
Export-Csv (Exchange) Bordmittel
Get-TransportService | Get-MessageTrackingLog -WarningAction 0 -Sender "sender@example.com" `
-Start (Get-Date).AddHours(-48) -End (Get-Date) -ResultSize Unlimited |
Where-Object { $_.Sender -notmatch "HealthMailbox" } |
Select-Object Timestamp, ServerHostname, EventId, Source, Sender,
@{N="Recipients";E={$_.Recipients -join ";"}}, MessageSubject,
@{N="Status";E={$_.RecipientStatus -join " "}} |
Sort-Object Timestamp |
Export-Csv .\tracking.csv -NoTypeInformation -Encoding UTF8 -Delimiter ";" grep / awk (Postfix) Bordmittel
grep -iE "from=<sender@example.com>" /var/log/mail.log |
awk '{ print $1" "$2" "$3";"$4";"$6" "$7" "$8 }' > tracking.csv
head -5 tracking.csv Exchange Online
Export-Csv (Exchange Online) Zusatztool
Get-MessageTraceV2 -SenderAddress "sender@example.com" `
-StartDate (Get-Date).AddHours(-48) -EndDate (Get-Date) |
Export-Csv .\trace.csv -NoTypeInformation -Encoding UTF8 -Delimiter ";" Die Ausgabe enthält Absender, Empfänger und Betreff. Vor dem Weitergeben prüfen, ob das für den Empfängerkreis in Ordnung ist.