Skip to content

Releases: Nico77600/MessageTraceReport

Message Trace Report 1.1.0

Choose a tag to compare

@Nico77600 Nico77600 released this 02 Oct 17:44

Why a message was not delivered — for each recipient.

Added

  • Cause of each failure, in plain words: Blocked by DLP, Blocked by mail flow rule (ETR), Blocked by organization policy, Blocked by Tenant Allow/Block List, Recipient not found, Mailbox full, Sender not allowed by recipient, Sender authentication failed, Quarantined, Junk Email folder, Destination server unreachable, Rejected by remote server… (about 30), with the DLP or mail flow rule (name, or ID when the names are empty) and what to check. Decided from the component that rejected, the rule steps of the route, the codes reserved for mail flow rules (5.7.900–5.7.999), the enhanced status code and the answer of the remote server.
  • Route analysis (src\Engine.Route.cs): steps in order (events of the same second come back unordered from the service), facts of the XML data with readable labels (server, connector, TLS, SCL / SFV…), reason with SMTP and enhanced code, text, diagnostic, remote server, component and its Microsoft Learn page.
  • Where the routes split: the recipients of a message are grouped by identical route (Route A, Route B…); when some failed and others were delivered, the common steps and what happened next, side by side — in the HTML report and in the console.
  • Smarter route selection: a selection of at most Details.MaxDeliveries (now 100) is read completely; a larger one reads, newest message first, one recipient per problem status and one delivered recipient of the same message to compare (Details.CompareWithDelivered), then the other problems. Routes are read once and reused. -MaxRoutes changes the number for one run.
  • Console: the route of the messages of a small selection (Details.ConsoleMessages, 3), the causes and status codes of the run, a Causes line in the summary.
  • HTML report: Why deliveries were not delivered (one card per cause, then the status codes with their Learn page, click to filter), a Cause column, filters by cause, any recipient not delivered, partly delivered and route read, search in the reasons, a new message dialog (routes, split, cause box, steps with times and details).
  • Files: MessageTrace_Routes.csv (one row per step, Report.Files Routes); Cause and Reason columns at the end of the Messages and Deliveries CSV (and Route for Deliveries); route, outcome, causeId, cause, reason and events in the JSON files.

Changed

  • Details.MaxDeliveries 50 → 100; new keys CompareWithDelivered and ConsoleMessages.
  • The demonstration data and the in-memory API of the tests return the real shape of the routes (DLP, mail flow rule, restrictions, remote rejection, delay, quarantine, junk, group expansion). 59 Pester tests.

Upgrade: replace the files, keep your configuration (config\MessageTraceReport.config.psd1) and your data folder; the new Details keys have defaults. The CSV columns added are at the end.

Full guide: docs\MessageTraceReport-Guide.html in the zip.

Message Trace Report 1.0.0

Choose a tag to compare

@Nico77600 Nico77600 released this 02 Oct 16:12

Download MessageTraceReport-1.0.0.zip: only the files needed to run (configuration with empty tenant values, SQLite bundled), the HTML guide included. PowerShell 7.4+, Microsoft Graph v1.0, no module needed with a certificate.

First version, replacing Invoke-MessageTraceGraph.ps1.

Highlights

  • Four modes: Trace (default — collects only what the local database lacks, then writes the report), Collect (scheduled, whole tenant or a scope, history beyond the 90 days of Graph), Report (database only, any address pattern) and Status.
  • Query planner built on the real API behaviour: Graph keeps one value per property in $filter and silently ignores or. One query per address of the shorter list (senders AND recipients), per address (OR); the full filter is applied on the database, so the report is exact. *@domain, subject, status, message ID, source and destination IP.
  • Quota-aware: one rolling budget shared by the workers (90 requests / 5 minutes by default), Retry-After honoured, the requests of the last window remembered by the next run, live progress line.
  • Restartable: every page stored in SQLite as it arrives; Ctrl+C keeps what was received, the next run collects only the rest; recent hours read again to catch status changes.
  • Reports: Messages, Deliveries, Senders, Recipients CSV (Excel-safe, split above 1,000,000 rows), optional JSON with the Graph property names, self-contained HTML report (tiles, status, timeline, top 10, search and filters for 200,000 messages, recipients and route of each message with -IncludeDetails).
  • Authentication: certificate (client assertion built in), client secret from an environment variable, or interactive sign-in; tenant and permission checked before the first request.
  • Parameter names of Invoke-MessageTraceGraph.ps1 kept as aliases (-StartDate, -Senders, -RecipientsCsv …).

Measured in a lab tenant (same filter, same period)

Original script Message Trace Report
1 sender AND 3 recipients, 7 days 31.8 s — 1 recipient of 3 8.5 s — 3 recipients
20 senders, 7 days (558,945 deliveries) 17 min — 8,416 rows lost 6 min 22 s — every row
The same, run again 17 min 27 s

Requirements

Microsoft Graph application permission ExchangeMessageTrace.Read.All with admin consent, and the service principal of the Microsoft application 8bd644d1-64a1-4d4b-ae52-2e0cbf64e373 in the tenant — see the guide, chapter 7.

See CHANGELOG.md and the administrator guide.