Menu Close

Search and delete Exchange Emails

Exchange Server administrators often receive requests to delete emails from one or more user mailboxes. There can be many reasons for these requests, spam / virus emails sent to all users, accidental emails, etc. Most of the time, this will have to be done without the knowledge of the email users!

One way to accomplish this task is to manually delete email using Outlook Webmail (OWA). This is not a problem if you only have one or two users. But this is not practical in situations involving hundreds of users. The fastest and most effective way to accomplish this task is to use PowerShell.

To help administrators perform this task, Scridea has created an easy-to-follow PowerShell script. Follow the steps below to search and delete emails from Exchange Mailboxes.

Note:

To use this script on Exchange Online, you need to install the Exchange Online PowerShell V2 (EXO V2) module and make minor changes within the ‘Setup Exchange Remote Session‘ script block.

To learn more, read the Microsoft article, Connect to Exchange Online PowerShell.

Step 1: Prepare the script file

  • Copy the PowerShell script code below into a text file.
#Search and delete Exchange Emails - script by Scridea Solutions

#User inputs
$exchserver = "exchserver"            # Name or IP of your Exchange Server
$searchname = "DeleteMessages"        # Name of the search, give any name

$search_subject = "spam mail"           # Email subject to search for
$dateFrom       = "09/22/2021"          # Start date (mm/dd/yyyy)
$dateTo         = "09/23/2021"          # End date   (mm/dd/yyyy)

#Setup Exchange remote session
Clear-Host
Write-Host "Enter user name and password of Exchange Administrator" -ForegroundColor Cyan
$connectionuri = "http://" + $exchserver + "/PowerShell/"
$UserCredential = Get-Credential -Verbose $null
Clear-Host
Write-Host "Preparing remote session..." -ForegroundColor Cyan
try {
    $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $connectionuri -Authentication Kerberos -Credential $UserCredential -ErrorAction Stop
    Import-PSSession $Session -DisableNameChecking -ErrorAction Stop
}
catch {
    Clear-Host
    Write-Host $_.Exception.Message  -ForegroundColor Red
    pause
    return
}

#Start search
Clear-Host
Write-Host "Searching, Please wait..." -ForegroundColor Cyan
$query = '(subject:"' + $search_subject + '") AND (received>=' + $dateFrom + ') AND (received<=' + $dateTo + ')'
if (-not (New-ComplianceSearch -Name $searchname -ExchangeLocation all -ContentMatchQuery $query)) {
    #Remove-PSSession -Session $Session
    Write-Host "Error occured, Exiting..." -ForegroundColor Cyan
    pause
    return
}
Start-ComplianceSearch -Identity $searchname
Start-Sleep -s 5

#Check search status
$search_status = Get-ComplianceSearch -Identity $searchname | Select-Object -expand Status
while ($search_status -ne "Completed") {
    Start-Sleep -s 5
    $search_status = Get-ComplianceSearch -Identity $searchname | Select-Object -expand Status
}

$searchresult = Get-ComplianceSearch -Identity $searchname
$resultdata = $searchresult.SuccessResults

#clear and exit if no results
if ($searchresult.Items -le 0) {
    Remove-ComplianceSearch -Identity $searchname -Confirm:$false
    Remove-PSSession -Session $Session
    clear-host
    Write-Host "No results found for the search subject: $search_subject" -ForegroundColor Cyan
    pause
    return
}

#prepare search results
$mailboxes = @();
$lines = $resultdata -split '[\r\n]+'
foreach ($line in $lines) {
    if ($line -match 'Location: (\S+),.+Item count: (\d+)' -and $matches[2] -gt 0) {
        $mailboxes += new-object psobject -property @{Mailbox = $matches[1]; TotalEmails = $matches[2] }
    }
}

#show search results
clear-host
write-host ' Email search results' -ForegroundColor Cyan
Write-Host ' --------------------'
"Search Subject    : " + $search_subject
"Total Mailboxes   : " + $mailboxes.Count
"Total emails      : " + $searchresult.Items
"Failed mailboxes  : " + $searchresult.NumFailedSourcesd
$mailboxes | format-table
Write-Host 'Are you sure you want to delete these emails?' -ForegroundColor Red -BackgroundColor White
$confirm = Read-Host -Prompt 'Enter Y to confirm or press any key to cancel'

#delete emails if confirmed
if ($confirm -eq 'y') {
    clear-host
    Write-Host ' Deleting messages, Please wait...' -ForegroundColor Cyan
    New-ComplianceSearchAction -SearchName $searchname -Purge -Confirm:$false
    Start-Sleep -s 5
    $purgename = $searchname + "_purge"
    $deletestats = Get-ComplianceSearchAction -Identity $purgename |  Select-Object -expand Status 
    while ($deletestats -ne "Completed") {
        Start-Sleep -s 5
        $deletestats = Get-ComplianceSearchAction -Identity $purgename |  Select-Object -expand Status
    }
    $deleteresults = Get-ComplianceSearchAction -Identity $purgename | format-list -Property Results
}

#show results, clear and exit
Remove-ComplianceSearch -Identity $searchname -Confirm:$false
Remove-PSSession -Session $Session
clear-host
Write-Host "Task Completed." -ForegroundColor Cyan
if ($confirm -eq 'y') {
    $deleteresults
}
pause
  • Inside the script, under the User Inputs section, enter the name of an Exchange server and search parameters.
    • You can enter the entire subject text or part of it.
    • If you want to search for a single day, enter the same date for the variables, ‘$dateFrom‘ and ‘$dateTo
  • Save the text file as ‘DeleteExchangeEmails.ps1

Step 2: Run the script

  • Right-click on the script file and select Run with PowerShell.
  • When prompted, enter the username and password of an Exchange Administrator.
  • The script will create and start a new compliance search. Wait for the search to finish and the results to appear.
  • Review the results displayed. To delete emails, type ‘y‘ and press enter.
    [If you do not want to continue or delete emails, press Enter without typing anything. Then, wait for the script to exit the session.]
  • The deletion process will begin and the results will be displayed when completed.
  • Exit the script by pressing the Enter key.

Warning:

Do not close the script window during script execution. Always follow the script instructions and allow the script to stop automatically and exit. Otherwise uncleaned session data may later lead to errors.

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *