When troubleshooting email delivery issues or auditing message flows in Office 365, administrators often need complete SMTP conversation logs. The native Message Trace feature provides basic information, but sometimes you need the raw SMTP protocol-level details for deeper analysis.
Before attempting to export SMTP logs, ensure you have:
- Office 365 Administrator privileges
- Exchange Online PowerShell Module installed
- Sufficient storage for log files
For comprehensive SMTP logs, we'll leverage Exchange Online's diagnostic capabilities:
# Connect to Exchange Online Connect-ExchangeOnline -UserPrincipalName admin@yourdomain.com # Enable protocol logging for all connectors Get-ReceiveConnector | Set-ReceiveConnector -ProtocolLoggingLevel Verbose Get-SendConnector | Set-SendConnector -ProtocolLoggingLevel Verbose # Export SMTP logs for a specific domain (last 7 days) $startDate = (Get-Date).AddDays(-7) $endDate = Get-Date $results = Get-MessageTrace -SenderAddress *@yourdomain.com -StartDate $startDate -EndDate $endDate -Status Delivered | Get-MessageTraceDetail # Export to CSV $results | Export-Csv -Path "C:\SMTP_Logs_Domain.csv" -NoTypeInformation
For more detailed protocol-level logging:
# Enable EWS logging (Exchange Web Services) Set-WebServicesVirtualDirectory -Identity "EWS*" -LogLevel Verbose # Collect logs from IIS $logPath = (Get-WebServicesVirtualDirectory -Identity "EWS*").LogFile.Directory Get-ChildItem -Path $logPath -Filter "*.log" | Copy-Item -Destination "C:\SMTP_Logs\"
To focus on messages to/from a specific domain:
# PowerShell filtering example Import-Csv "C:\SMTP_Logs_Domain.csv" | Where-Object { $_.Sender -like "*@targetdomain.com" -or $_.Recipient -like "*@targetdomain.com" } | Export-Csv -Path "C:\Filtered_Logs.csv"
For environments where PowerShell isn't available:
- Navigate to Security & Compliance Center
- Go to Reports > Dashboard > Email & collaboration
- Select "Message trace"
- Apply domain filters and export
- Log retention periods vary by Office 365 plan
- Verbose logging may impact performance
- Always disable diagnostic logging when not needed
- Consider third-party solutions for long-term log retention
When troubleshooting email delivery issues or auditing communication patterns with external domains, administrators often need complete SMTP transaction logs. Office 365's native tools provide limited visibility, making PowerShell the preferred method for comprehensive log extraction.
Before proceeding, ensure you have:
- Office 365 Global Admin or Compliance Admin rights
- Exchange Online PowerShell Module (V2 recommended)
- Azure AD module for authentication
First establish a PowerShell session:
Install-Module -Name ExchangeOnlineManagement -Force -AllowClobber
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName admin@domain.com
For domain-specific analysis, use the Get-MessageTrace cmdlet with precise filters:
Get-MessageTrace -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date)
-SenderDomain "yourdomain.com" -RecipientDomain "targetdomain.com" |
Export-Csv -Path "C:\SMTP_Logs.csv" -NoTypeInformation
For more granular control over exported data:
$Filter = "FromIP LIKE '192.168.%' AND Status LIKE 'failed'"
Get-MessageTrace -StartDate 01/01/2023 -EndDate 12/31/2023
-PageSize 5000 -Page 1 -Filter $Filter |
Select-Object Received, SenderAddress, RecipientAddress, Subject, Status, Size |
Export-Csv -Path "C:\Filtered_Logs.csv" -Encoding UTF8
For environments with heavy email traffic:
$AllResults = @()
$Page = 1
do {
$Results = Get-MessageTrace -Page $Page -PageSize 5000 -StartDate 01/01/2024
$AllResults += $Results
$Page++
} while ($Results.Count -eq 5000)
$AllResults | Export-Csv -Path "C:\Full_Logs.csv"
Create a scheduled task with this script:
$Params = @{
StartDate = (Get-Date).AddDays(-1)
EndDate = (Get-Date)
SenderDomain = "yourdomain.com"
RecipientDomain = "partnerdomain.com"
}
$Logs = Get-MessageTrace @Params
$Logs | Export-Csv -Path "C:\Daily_Logs_$(Get-Date -Format yyyyMMdd).csv"
For programmatic access:
$Uri = "https://graph.microsoft.com/v1.0/auditLogs/messageTraces"
$Params = @{
Method = "Get"
Uri = $Uri
Headers = @{Authorization = "Bearer $Token"}
Body = @{
startDateTime = "2024-01-01T00:00:00Z"
endDateTime = "2024-01-31T23:59:59Z"
'$filter' = "senderDomain eq 'contoso.com'"
}
}
Invoke-RestMethod @Params | ConvertTo-Json -Depth 5 | Out-File "graph_logs.json"