-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path33-Get-UserMessageTrace.ps1
137 lines (117 loc) · 7.57 KB
/
33-Get-UserMessageTrace.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# Bitpusher
# \`._,'/
# (_- -_)
# \o/
# The Digital
# Fox
# https://theTechRelay.com
# https://github.com/bitpusher2k
#
# Get-UserMessageTrace.ps1 - By Bitpusher/The Digital Fox
# v2.8 last updated 2024-05-12
# Script to get message trace report of recent incoming & outgoing email for a given user.
#
# Usage:
# powershell -executionpolicy bypass -f .\Get-UserMessageTrace.ps1 -OutputPath "Default" -UserIds "compromisedaccount@contoso.com" -DaysAgo "10"
#
# Run with already existing connection to M365 tenant through
# PowerShell modules.
#
# Uses ExchangePowerShell commands.
#
#comp #m365 #security #bec #script #irscript #powershell #email #message #trace #exchange #online
#Requires -Version 5.1
param(
[string]$OutputPath,
[string]$UserIds,
[int]$DaysAgo,
[datetime]$StartDate,
[datetime]$EndDate,
[string]$Encoding = "utf8bom" # "ascii","ansi","bigendianunicode","unicode","utf8","utf8","utf8NoBOM","utf32"
)
if ($PSVersionTable.PSVersion.Major -eq 5 -and ($Encoding -eq "utf8bom" -or $Encoding -eq "utf8nobom")) { $Encoding = "utf8" }
$date = Get-Date -Format "yyyyMMddHHmmss"
## If OutputPath variable is not defined, prompt for it
if (!$OutputPath) {
Write-Output ""
$OutputPath = Read-Host "Enter the output base path, e.g. $($env:userprofile)\Desktop\Investigation (default)"
If ($OutputPath -eq '') { $OutputPath = "$($env:userprofile)\Desktop\Investigation" }
Write-Output "Output base path will be in $OutputPath"
} elseif ($OutputPath -eq 'Default') {
Write-Output ""
$OutputPath = "$($env:userprofile)\Desktop\Investigation"
Write-Output "Output base path will be in $OutputPath"
}
## If OutputPath does not exist, create it
$CheckOutputPath = Get-Item $OutputPath -ErrorAction SilentlyContinue
if (!$CheckOutputPath) {
Write-Output ""
Write-Output "Output path does not exist. Directory will be created."
mkdir $OutputPath
}
## Get Primary Domain Name for output subfolder
$PrimaryDomain = Get-AcceptedDomain | Where-Object Default -EQ $true
$DomainName = $PrimaryDomain.DomainName
$CheckSubDir = Get-Item $OutputPath\$DomainName -ErrorAction SilentlyContinue
if (!$CheckSubDir) {
Write-Output ""
Write-Output "Domain sub-directory does not exist. Sub-directory `"$DomainName`" will be created."
mkdir $OutputPath\$DomainName
}
## If UserIds variable is not defined, prompt for it
if (!$UserIds) {
Write-Output ""
$UserIds = Read-Host 'Enter the email address of account for message trace'
}
## If DaysAgo variable is not defined and StartDate/EndDate were also not defined, prompt for it
if (!$DaysAgo -and (!$StartDate -or !$EndtDate)) {
Write-Output ""
$DaysAgo = Read-Host 'Enter how many days back to retrieve ALL available message trace entries for specified account (default: 10, maximum: 90 - entries past 10 days ago will be in "historical" report)'
if ($DaysAgo -eq '') { $DaysAgo = "10" } elseif ($DaysAgo -gt 90) { $DaysAgo = "90" }
Write-Output "Will attempt to retrieve message trace entries going back $DaysAgo days from today."
} elseif ($DaysAgo) {
if ($DaysAgo -gt 90) { $DaysAgo = "90" }
Write-Output "Will attempt to retrieve message trace entries going back $DaysAgo days from today."
} elseif ($StartDate -and $EndtDate) {
Write-Output "Will attempt to retrieve message trace entries between $StartDate and $EndDate."
} else {
Write-Output "Missing date range information - Try running again with -DaysAgo or -StartDate and -EndDate parameters."
exit
}
if ($StartDate -and $EndtDate) {
Write-Output "Starting Get-MessageTrace..."
Get-MessageTrace -SenderAddress $UserIds -StartDate $StartDate -EndDate $EndDate | Export-Csv "$OutputPath\$DomainName\TraceSent_$($UserIds)_between_$($StartDate.ToString("yyyyMMddHHmmss"))_and_$($EndtDate.ToString("yyyyMMddHHmmss")).csv" -NoTypeInformation -Encoding $Encoding
Get-MessageTrace -RecipientAddress $UserIds -StartDate $StartDate -EndDate $EndDate | Export-Csv "$OutputPath\$DomainName\TraceReceived_$($UserIds)_between_$($StartDate.ToString("yyyyMMddHHmmss"))_and_$($EndtDate.ToString("yyyyMMddHHmmss")).csv" -NoTypeInformation -Encoding $Encoding
Write-Output "Starting historical search to retrieve traces of messages older than 10 days..."
Start-HistoricalSearch -SenderAddress $UserIds -StartDate $StartDate -EndDate $EndDate -reporttitle "Sender $UserIds historical search between $($StartDate.ToString('yyyyMMddHHmmss')) and $($EndtDate.ToString('yyyyMMddHHmmss'))" -ReportType messagetrace
Start-HistoricalSearch -RecipientAddress $UserIds -StartDate $StartDate -EndDate $EndDate -reporttitle "Recipient $UserIds historical search between $($StartDate.ToString('yyyyMMddHHmmss')) and $($EndtDate.ToString('yyyyMMddHHmmss'))" -ReportType messagetrace
Write-Output "Historical searches queued. Use 'Get-HistoricalSearch | Select ReportTitle,Status' to check the search status, then when complete download the reports from https://admin.exchange.microsoft.com/#/messagetrace"
Write-Output "Use 'Stop-HistoricalSearch -JobId <Guid>' to cancel."
} elseif ($DaysAgo -gt 10) {
$StartDate = (Get-Date).AddDays(-10)
$EndDate = (Get-Date).AddDays(1)
Write-Output "Starting Get-MessageTrace..."
Get-MessageTrace -SenderAddress $UserIds -StartDate $StartDate -EndDate $EndDate | Export-Csv "$OutputPath\$DomainName\TraceSent_$($UserIds)_going_back_10_days_from_$($date).csv" -NoTypeInformation -Encoding $Encoding
Get-MessageTrace -RecipientAddress $UserIds -StartDate $StartDate -EndDate $EndDate | Export-Csv "$OutputPath\$DomainName\TraceReceived_$($UserIds)_going_back_10_days_from_$($date).csv" -NoTypeInformation -Encoding $Encoding
$StartDate = (Get-Date).AddDays(- $DaysAgo)
$EndDate = (Get-Date).AddDays(1)
Write-Output "Starting historical search to retrieve traces of messages older than 10 days..."
Start-HistoricalSearch -SenderAddress $UserIds -StartDate $StartDate -EndDate $EndDate -reporttitle "Sender $UserIds historical search $DaysAgo days ago from $EndDate" -ReportType messagetrace
Start-HistoricalSearch -RecipientAddress $UserIds -StartDate $StartDate -EndDate $EndDate -reporttitle "Recipient $UserIds historical search $DaysAgo days ago from $EndDate" -ReportType messagetrace
Write-Output "Historical searches queued. Use 'Get-HistoricalSearch | Select ReportTitle,Status' to check the search status, then when complete download the reports from https://admin.exchange.microsoft.com/#/messagetrace"
Write-Output "Use 'Stop-HistoricalSearch -JobId <Guid>' to cancel."
} else {
$StartDate = (Get-Date).AddDays(- $DaysAgo)
$EndDate = (Get-Date).AddDays(1)
Write-Output "Starting Get-MessageTrace..."
Get-MessageTrace -SenderAddress $UserIds -StartDate $StartDate -EndDate $EndDate | Export-Csv "$OutputPath\$DomainName\TraceSent_$($UserIds)_going_back_$($DaysAgo)_days_from_$($date).csv" -NoTypeInformation -Encoding $Encoding
Get-MessageTrace -RecipientAddress $UserIds -StartDate $StartDate -EndDate $EndDate | Export-Csv "$OutputPath\$DomainName\TraceReceived_$($UserIds)_going_back_$($DaysAgo)_days_from_$($date).csv" -NoTypeInformation -Encoding $Encoding
}
## Potential additions:
# https://docs.microsoft.com/en-us/graph/api/resources/office-365-groups-activity-reports?view=graph-rest-1.0
# Get-MgReportOffice365GroupActivityDetail -OutFile
# https://docs.microsoft.com/en-us/powershell/module/microsoft.graph.reports/get-mgreportoffice365groupactivitydetail?view=graph-powershell-1.0
# Get-MgReportMailboxUsageDetail -OutFile
Write-Output "`nDone! Check output path for results."
Invoke-Item "$OutputPath\$DomainName"
exit