Using PowerShell to Delete Outlook Emails that Contain Certain Strings

I have found a variety of use cases for a script that could pull emails from a folder in my Outlook and delete them based on certain strings being in the body of the email.

As I wrote about in my previous blog post about interacting with Outlook using PowerShell and COM, a reminder that COM is not always reliable. In a folder full of thousands of emails, I found I had to run a script 3-4 times to delete all the emails matching my filter.

Taking Control of Outlook

First, I needed the script to take control of Outlook using PowerShell. I wrote about these code segments in a different blog post. In short, I found this code on the PowerShell blog and found it useful as it will gracefully take control of an Outlook instance that is already running.

try
{
$outlook = [Runtime.Interopservices.Marshal]::GetActiveObject('Outlook.Application')
    $outlookWasAlreadyRunning = $true
}
catch
{
    try
    {
        $Outlook = New-Object -comobject Outlook.Application
        $outlookWasAlreadyRunning = $false
    }
    catch
    {
        write-host "You must exit Outlook first."
        exit
    }
}

Putting this part at the end of the script will close Outlook only if it was not running before.

# Close outlook if it wasn't opened before running this script
if ($outlookWasAlreadyRunning -eq $false)
{
    Get-Process "*outlook*" | Stop-Process force
}

Matching Email from a Folder and Deleting

Then, I defined a list of strings that if found in the body of an email, I wanted the email deleted.

$bodytext = "campaign is on its way to your subscribers", "i am off today", "i am currently working", "i'm currently working", "closed to the public", "suspending operations", "tentative reopening", "i will be away", "covid", "vacation", "holiday", "out of the office", "out of office", "i will be away", "i am away", "i'm away", "i am currently away", "currently closed", "as soon as possible", "get back to you", "working from home", "remotely", "maternity leave", "working virtually"

The place I volunteered at had an Outlook folder filled with emails that were automatic responses from a mailing list. They wanted to delete all out of office and other emails related to temporary leave or closure.

So now we need to interact with Outlook.

$namespace = $Outlook.GetNameSpace("MAPI")
$workingfolder = $namespace.Folders.Item(1).Folders.Item("Name of the folder goes here")

$emails = $workingfolder.Items
$counter = 0

ForEach ($email in $emails)
{
    ForEach ($filter in $bodytext)
    {
        $lowercase = $email.Body.ToLower()
        if ($lowercase.Contains($filter))
        {
            $counter = 1
        }
    }
    if ($counter -eq 1)
    {
        $email.Delete()
        write-host "Deleted" $email.Subject $email.SenderEmailAddress
        $counter = 0
    }
}

On Line 2, this is where I input the name of the folder the script needs to access. In this case, the folder I was dealing with was at the root of the mailbox. This might not work for a folder inside a folder.

The $counter variable here is being used because I honestly forgot about breaks. So instead of using a break, the counter lets the script check if the body contained any of the strings and deletes the email outside of the loop. I will insert a re-write of the code to use a break at a later date.

Conclusion

So that’s the script! I have not included links to the full script on my Gitlab because of the portion of code from the PowerShell blog is not my own and does not have a license. Please contact me if you have any questions about the script.