Skip to content

Instantly share code, notes, and snippets.

@robderickson
Created January 14, 2020 21:11
Show Gist options
  • Save robderickson/5bed6387d56298f8b6c756c929ad9ea7 to your computer and use it in GitHub Desktop.
Save robderickson/5bed6387d56298f8b6c756c929ad9ea7 to your computer and use it in GitHub Desktop.
Combine Get-MessageTrackingLog with Search-Mailbox for finding and removing malicious mail items.
function Search-ExchangeLogAndMailbox {
# TODO: Write help
[CmdletBinding(DefaultParameterSetName='Trace')]
param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$Sender,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$MessageSubject,
[Parameter(ValueFromPipelineByPropertyName=$true,
ParameterSetName='Trace')]
[switch]$MessageTraceOnly,
[Parameter(ValueFromPipelineByPropertyName=$true,
ParameterSetName='Search')]
[switch]$SearchOnly,
[Parameter(ValueFromPipelineByPropertyName=$true,
ParameterSetName='Delete')]
[switch]$SearchAndDelete,
[Parameter(ValueFromPipelineByPropertyName=$true,
ParameterSetName='Search',
Mandatory=$true)]
[Parameter(ValueFromPipelineByPropertyName=$true,
ParameterSetName='Delete',
Mandatory=$true)]
[string]$TargetMailbox,
[Parameter(ValueFromPipelineByPropertyName=$true,
ParameterSetName='Search',
Mandatory=$true)]
[Parameter(ValueFromPipelineByPropertyName=$true,
ParameterSetName='Delete',
Mandatory=$true)]
[string]$TargetFolder,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string[]]$TransportServers = (Get-ExchangeServer | Select-Object -ExpandProperty Name)
# TODO: Support Sent date/range parameter
)
PROCESS {
# Throw error if neither $Sender or $MessageSubject are defined
# TODO: Replace this condition with Parameter Sets? Twelve Parameter Sets?
if ($Sender -eq $null -and $MessageSubject -eq $null) {
Write-Error "Command requires at least the Sender or MessageSubject parameters be defined."
throw
} else {
$results = Foreach ($server in $TransportServers) {
# Set parameters for Get-MessageTrackingLog
$MessageLogSplat = @{
Server = $server
EventID = 'Deliver'
}
if ($Sender) {
$MessageLogSplat['Sender'] = $Sender
}
if ($MessageSubject) {
$MessageLogSplat['MessageSubject'] = $MessageSubject
}
# Search message tracking logs
Get-MessageTrackingLog @MessageLogSplat
}
}
if ($SearchOnly -or $SearchAndDelete) {
# Get collection of mailboxes to search
$Mailboxes = $results | Select-Object -ExpandProperty Recipients | Foreach-Object {Get-Mailbox $_}
# Set the SearchQuery
if ($Sender -and $MessageSubject) {
# Query for both Sender and Subject
$SearchQuery = "From:'$Sender' Subject:'$MessageSubject'"
} elseif ($Sender -and -not $MessageSubject) {
# Query just for Sender
$SearchQuery = "From:'$Sender'"
} elseif (-not $Sender -and $MessageSubject) {
# Query just for Subject
$SearchQuery = "Subject:'$MessageSubject'"
} else {
Write-Error "What the heckin' heck!?"
}
# TODO: Add condition for including Sent date/range in $SearchQuerey here
# Set parameters for Search-Mailbox
$SearchMailboxSplat = @{
TargetMailbox = $TargetMailbox
TargetFolder = $TargetFolder
SearchQuery = $SearchQuery
LogLevel = 'Full'
}
if ($SearchOnly) {
$SearchMailboxSplat['LogOnly'] = $true
}
if ($SearchAndDelete) {
$SearchMailboxSplat['DeleteContent'] = $true
$SearchMailboxSplat['Force'] = $true
}
# Execute search
$Mailboxes | Search-Mailbox @SearchMailboxSplat
} else {
# Default to displaying Get-MessageTrackingLog results
$results
}
}
}
@robderickson
Copy link
Author

robderickson commented Jan 14, 2020

I am often asked to find and delete messages from phishing campaigns that make it to our mailboxes. I can almost always find recipients of these messages using Get-MessageTrackingLog with some combination of the sender and subject. Then I have to search mailboxes for instances of the message with Search-Mailbox, and ultimately delete them.

Find recipients with Get-MessageTrackingLog:

$SearchParams = @{
    Sender = '[email protected]'
    MessageSubject = 'This is totally not legit'
}
Search-ExchangeLogAndMailbox @SearchParams

Find messages in recipients' mailboxes (but do not delete):

$SearchParams = @{
    Sender = '[email protected]'
    MessageSubject = 'This is totally not legit'
    SearchOnly = $true
    TargetMailbox = 'Bad Stuff'
    TargetFolder = "Bad Stuff $(Get-Date -Format 'yyyy-MM-dd')"
}
Search-ExchangeLogAndMailbox @SearchParams

Find messages in recipients' mailboxes, and delete:

$SearchParams = @{
    Sender = '[email protected]'
    MessageSubject = 'This is totally not legit'
    SearchAndDelete = $true
    TargetMailbox = 'Bad Stuff'
    TargetFolder = "Bad Stuff $(Get-Date -Format 'yyyy-MM-dd')"
}
Search-ExchangeLogAndMailbox @SearchParams

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment