Script repository

Message trace for Exchange Online mailbox

Updated on: Jan 18, 2026, Views: 1672

Exchange

The script retrieves message trace of an Exchange Online mailbox for the specified number of days and emails it as a CSV file. To execute the script, create a custom command with a parameter that will be used to specify the number of days for the trace.

Parameters

  • $daysNumberParameter - the name of the parameter used to specify the number of days for retrieving message trace. The name should be specified with the param- prefix. The parameter values must not exceed 10.
  • $csvFilePath - a path to the CSV file that will be created by the script.
  • $removeCsvFile - set to $true to remove the CSV file after emailing it.
  • $recipient- the address of the email notification recipient.
  • $subject - the email notification subject.
  • $from - the email address from which the notification will be sent.
  • $message - the email notification text.
  • $smtpServer - the SMTP server to use for sending the email.
$daysNumberParameter = "param-MyParam" # TODO: modify me

# CSV file settings
$csvFilePath = "C:\Scripts\Report.csv" # TODO: modify me
$removeCsvFile = $True # TODO: modify me

# Email settings
$recipient = "recipient@domain.com" # TODO: modify me
$from = "noreply@domain.com" # TODO: modify me
$subject = "My Subject" # TODO: modify me
$message = "My Message" # TODO: modify me
$smtpServer = "mail.domain.com" # TODO: Modify me

# Get parameter value.
$daysNumber = $Context.GetParameterValue($daysNumberParameter)

# Get email address.
if ($Context.TargetObject.RecipientLocation -eq "ADM_EXCHANGERECIPIENTLOCATION_NONE")
{
    $Context.LogMessage("The object does not have an Exchange mailbox", "Error")
    return
}

$mailboxParams = $Context.TargetObject.GetMailParameters()
$emailAddresses = $mailboxParams.EmailAddresses
for ($i = 0; $i -lt $emailAddresses.Count; $i++)
{
    $emailAddress = $emailAddresses.GetAddress($i,[ref]"ADS_PROPERTY_NONE")
    if ($emailAddress.Prefix -eq "smtp" -and $emailAddress.IsPrimary)
    {
        $recipientAddress = $emailAddress.Address
        break
    }
}

# Get trace end date.
$today = Get-Date
$tenDaysAgo = $today.AddDays(- $daysNumber)

# Connect to Exchange Online.
$Context.CloudServices.ConnectExchangeOnline() 

# Get the message trace.
try
{
    $messageTrace = Get-MessageTraceV2 -RecipientAddress $recipientAddress -StartDate $tenDaysAgo -EndDate $today -ErrorAction Stop | Sort Received -Descending
}
catch
{
    $Context.LogMessage("An error occurred while getting messages trace. Error: " + $_.Exception.Message, "Error")
    return
}

if ($NULL -eq $messageTrace)
{
    $Context.LogMessage("There were no messages sent.", "Information")
    return
}

$records = New-Object System.Collections.ArrayList
foreach ($item in $messageTrace)
{
    $record = New-Object PSObject -Property @{
        "SenderAddress" = $item.SenderAddress
        "Received" = $item.Received
        "Subject" = $item.Subject
    }
    $records.Add($record)
}

$records.ToArray() | Export-Csv -Path $csvFilePath -NoTypeInformation

# Send mail
Send-MailMessage -to $recipient -From $from -Subject $subject -Body $message -SmtpServer $smtpServer -Attachments $csvFilePath

if ($removeCSVFile)
{
    # Remove temporary file.
    Remove-Item $csvFilePath -Force
}

Comments 4

You must be signed in to comment.

  • Caleb

    Caleb

    When trying to run this script I get the error:
    You cannot call a method on a null-valued expression.
    At line:41 char:1
    + $Context.CloudServices.ConnectExchangeOnline()
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    when I run it on my local machine it works fine. Am I missing something on the adaxes side?

  • Grant

    Grant

    Hello,
    Just updating this since the Get-MessageTrace cmdlet has been deprecated and replaced by Get-MessageTracev2.

    • Support

      Support

      Hello Grant,

      Thank you for the update. We will consider updating the script accordingly.

Got questions?

Support Questions & Answers

We use cookies to improve your experience.
By your continued use of this site you accept such use.
For more details please see our privacy policy and cookies policy.