Tracing Emails in the Cloud

Ten years ago, Paul Cunningham described how to search Exchange Server message tracking logs with PowerShell to find details of emails logged as they pass through the transport service. That article focuses on the Get-MessageTrackingLog cmdlet that doesn’t exist in Exchange Online. A different technique is needed to run Exchange Online message traces and find messages in the cloud where the Get-MessageTrace cmdlet does the heavy lifting. And while you can run a message trace through the Exchange admin center GUI, running traces through PowerShell allows you to pipe the results to other cmdlets, create reports, and so on (here’s an example of using message trace to create a report for management about external email).

One big thing to remember is that Get-MessageTrace can return information about messages for up to ten days after they’re sent. After that, the Start-HistoricalSearch cmdlet must be used. Another point is that it takes a couple of minutes after a message is sent before Exchange Online can trace its progress.

Paul’s article used an email about a payroll report sent to three recipients as its test case. Figure 1 shows my example:

A message that we want to trace

Exchange Online message trace
Figure 1: A message that we want to trace

Exchange Online Message Trace by Sender Email Address

The results returned by any search depend on the criteria used to find items. To begin, we can find the message sent by the user by including their primary SMTP address in the Sender parameter.

Get-MessageTrace -SenderAddress Terry.Hegarty@office365itpros.com -StartDate (Get-Date).AddHours(-1) -EndDate (Get-Date)

Received            Sender Address                    Recipient Address                  Subject
--------            --------------                    -----------------                  -------
11/06/2022 10:24:22 Terry.Hegarty@office365itpros.com james.ryan@office365itpros.com     Attention: May Payroll Details
11/06/2022 10:24:22 Terry.Hegarty@office365itpros.com chris.bishop@office365itpros.com   Attention: May Payroll Details
11/06/2022 10:24:22 Terry.Hegarty@office365itpros.com brian.weakliam@office365itpros.com Attention: May Payroll Details

This information doesn’t give the same insight as the Get-MessageTrackingLog cmdlet delivers in terms of how the Exchange transport system processed the message. You can add the Status parameter to the search to return messages with a certain processing status. For instance, this command only returns messages that have been successfully delivered. Other status values include Failed, Pending, and Quarantined.

Get-MessageTrace -SenderAddress Terry.Hegarty@office365itpros.com -StartDate (Get-Date).AddHours(-1) -EndDate (Get-Date) -Status Delivered

To see more detail about the steps in processing, we need the message trace identifier. Get-MessageTrace doesn’t show the message trace identifier unless you ask for it:

Get-MessageTrace -SenderAddress Terry.Hegarty@office365itpros.com -StartDate (Get-Date).AddHours(-1) -EndDate (Get-Date) | Format-table MessageTraceId, SUbject, RecipientAddress

MessageTraceId                       Subject                        RecipientAddress
--------------                       -------                        ----------------
1b312cde-f274-409e-7350-08da4b948d74 Attention: May Payroll Details james.ryan@office365itpros.com
1b312cde-f274-409e-7350-08da4b948d74 Attention: May Payroll Details chris.bishop@office365itpros.com
1b312cde-f274-409e-7350-08da4b948d74 Attention: May Payroll Details brian.weakliam@office365itpros.com

Now we can run Get-MessageTraceDetail to discover what happened to a message.

Get-MessageTraceDetail -MessageTraceId  1b312cde-f274-409e-7350-08da4b948d74 -RecipientAddress James.Ryan@office365itpros.com

Date                   Event                Detail
----                   -----                ------
11/06/2022 10:24:23    Receive              Message received by: PAXPR04MB8621.eurprd04.prod.outlook.com
11/06/2022 10:24:23    Submit               The message was submitted.
11/06/2022 10:24:27    Deliver              The message was successfully delivered.

Tracing Messages by Recipient Email Address

Searching by recipient works no matter what kind of recipient (TO, CC, or BCC) a message recipient is. Here we search for Chris Bishop (a CC address), and the search succeeds:

Get-MessageTrace -RecipientAddress Chris.Bishop@office365itpros.com -StartDate (Get-Date).AddHours(-1) -EndDate (Get-Date) | Format-List

Message Trace ID  : 1b312cde-f274-409e-7350-08da4b948d74
Message ID        : <DB6PR04MB3158B4FBF516094B399D23C0B4A99@DB6PR04MB3158.eurprd04.prod.outlook.com>
Received          : 11/06/2022 10:24:22
Sender Address    : Terry.Hegarty@office365itpros.com
Recipient Address : chris.bishop@office365itpros.com
From IP           : 2a01:cb1d:5b0:1500:fd9f:cfb5:a3e6:e6cb
To IP             :
Subject           : Attention: May Payroll Details
Status            : Delivered
Size              : 57013

You can specify multiple recipient SMTP addresses by separating the recipient addresses with a comma. When you do this the condition is an “or” not an “and”. In other words, any message sent to any one of the recipients is included in the results. In this case, we look for messages sent to two mailboxes, one of which is a recipient on the payroll email. The message trace finds two messages:

Get-MessageTrace -RecipientAddress Chris.Bishop@office365itpros.com, Ben.Owens@office365itpros.com -StartDate (Get-Date).AddHours(-1) -EndDate (Get-Date) | fl

Message Trace ID  : 92827190-e015-4faf-586f-08da4b972420
Message ID        : <DB6PR04MB315846EE7664C474A7435554B4A99@DB6PR04MB3158.eurprd04.prod.outlook.com>
Received          : 11/06/2022 10:42:54
Sender Address    : Terry.Hegarty@office365itpros.com
Recipient Address : ben.owens@office365itpros.com
From IP           : 2a01:cb1d:5b0:1500:fd9f:cfb5:a3e6:e6cb
To IP             :
Subject           : Business Development Meeting
Status            : Delivered
Size              : 12933

Message Trace ID  : 1b312cde-f274-409e-7350-08da4b948d74
Message ID        : <DB6PR04MB3158B4FBF516094B399D23C0B4A99@DB6PR04MB3158.eurprd04.prod.outlook.com>
Received          : 11/06/2022 10:24:22
Sender Address    : Terry.Hegarty@office365itpros.com
Recipient Address : chris.bishop@office365itpros.com
From IP           : 2a01:cb1d:5b0:1500:fd9f:cfb5:a3e6:e6cb
To IP             :
Subject           : Attention: May Payroll Details
Status            : Delivered
Size              : 57013

Message Tracing for Wildcard Values or Partial Matches

The Get-MessageTrackingLog cmdlet doesn’t support wildcard searches against the SenderAddress and RecipientAddress parameters. However, Get-MessageTrace can run searches like this (the example finds any message sent to a microsoft.com address in the defined period):

Get-MessageTrace -RecipientAddress *@microsoft.com -StartDate 3-June-2022 -EndDate 10-June-2022 -Status Delivered

You can also run a wildcard search against sender addresses. For instance, here’s how to find all the messages delivered to my tenant from quest.com in the last week. The results cover all messages sent from quest.com addresses to any mail-enabled recipient in the tenant:

Get-MessageTrace -SenderAddress *@quest.com -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date) -Status Delivered | ft senderaddress, recipientaddress, subject, status

Message Trace by Subject

Unfortunately, the Get-MessageTrace cmdlet doesn’t include a Subject parameter to allow a search for a specific message with a matching subject. This deficit is easily overcome by piping the results of the search to the Where-Object cmdlet. For instance, here’s how to take the set of messages received from Quest.com and match only those containing the string “Zero-day” in the message subject:

Get-MessageTrace -SenderAddress *@quest.com -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date) -Status Delivered  | ? {$_.Subject -like "*Zero-day*"}

Summary

Message tracing is different in the cloud. On-premises servers generally have more control over how long logs remain available whereas cloud systems tend to keep information online for more limited periods. The use of Get-MessageTrace cmdlet differs from the Get-MessageTrackingLog cmdlet, but it doesn’t take much to become fluent in its capabilities.

About the Author

Tony Redmond

Tony Redmond has written thousands of articles about Microsoft technology since 1996. He is the lead author for the Office 365 for IT Pros eBook, the only book covering Office 365 that is updated monthly to keep pace with change in the cloud. Apart from contributing to Practical365.com, Tony also writes at Office365itpros.com to support the development of the eBook. He has been a Microsoft MVP since 2004.

Comments

  1. Alberto

    The Real Person!

    Author Alberto acts as a real person and verified as not a bot.
    Passed all tests against spam bots. Anti-Spam by CleanTalk.

    The Real Person!

    Author Alberto acts as a real person and verified as not a bot.
    Passed all tests against spam bots. Anti-Spam by CleanTalk.

    Hi, would it be possible to delete trace logs of emails older than 7 days? The Company where I work is Italian and the privacy guarantor requires the application of this rule. Thank you

    1. Avatar photo
      Tony Redmond

      Nope. You’ll have to ask Microsoft if this is possible. I can’t help with it because I know of no way to remove the data from the Microsoft service.

  2. Aleg

    all of this does not work in case of using delivery to big audiense >30000 recipients.

    1. Avatar photo
      Tony Redmond

      I suspect that running a message trace for > 30,000 recipients is likely to consume a lot of resources. If the cmdlet can’t handle this amount of recipients, you should file a support incident with Microsoft so that an engineer can investigate and update the cmdlet if necessary.

  3. Beto Schmitt

    Amazing!!
    Thank’s for your time. I really enjoyed your information.
    I would like to know if the received message has been read or not.
    It is possible?
    Once again, thanks for your help.

  4. jay

    Sir,
    I want full day summary report via email in my admin email address in table format. For all the emails flow in my organization.

    1. Avatar photo
      Tony Redmond

      I’m sure that you do want a summary report. Have you tried to generate one with PowerShell?

  5. Steve Freitag

    Is there a way to determine what message traces have been run tenant wide and by whom they were run?

    1. Tony Redmond

      It doesn’t look as if either the mail admin audit log or unified audit log (Search-AdminAuditLog and Search-UnifiedAuditLog) capture audit events for message tracing. At least, I did some traces and looked for audit records and couldn’t find anything.

  6. S.Groom

    Great article. Thanks for the detailed examples, they’ve enabled me to start improving observability into our fairly recent migration to Exchange Online. It does bring a question though… With on premises, I was able to pull specific metrics other than Sent and Received; t be specific, Deferred, Bad Mail, Dropped and Queued. I’m unable to find a way to collect similar message traffic metrics from Exchange Online. The powershell commands I’ve been using for years simply don’t apply/exist in Exchange Online. Suggestions?

    1. Avatar photo
      Tony Redmond

      I don’t believe that these statistics are available in Exchange Online.

      1. S.Groom

        Thanks Tony. I’ll keep looking for a different way and advise if I find something viable.

  7. bueschu

    Hi
    I appreciate your work, your articles and all the very helpfull information you give to the community.

    Many thanks – Bueschu

Leave a Reply