Remove specific email from ALL mailboxes in Exchange 2010 SP1

Have you ever had the situation where you had to quickly remove an email from all mailboxes in an organisation? Maybe it was an accidental email by an assistant to the whole company, or worse, inappropriate content sent by a disgruntled employee? I have not yet been put in this position but i wanted to be prepared for the gloomy day. This will help you if you are in the same position.

Well here are some steps that i have tested in an Exchange 2010 SP1 environment.
Note: there is a different method for Exchange 2007/2010 RTM versions that has not been documented here.

Prerequisites

Make sure the account running the PS command has the appropriate permissions; you need to specifically have access to the New-MailboxImportRequest cmdlet. By default, no-one has permissions to the cmdlet. If you don’t have the correct permissions you will get an error “The term ‘New-MailboxImportRequest’ is not recognized as the name of a cmdlet”.

To add the permission follow these simple steps:

  1. Create a Universal Security group in ADUC.
  2. Run the following command
    New-ManagementRoleAssignment -Name "Import Export Mailbox Admins" -SecurityGroup "*SecurityGroupName*" -Role "Mailbox Import Export"

Notes:

  • Change *SecurityGroupName* in the above cmdlet to the actual name of your group
  • The group needs to be a universal security group for the role assignment to work
  • The New-MailboxImportRequest cmdlet only works with UNC shares, not local drives
  • The “Exchange Trusted Subsystem” group should be granted read/write permission to the shared location

Use the Shell to search for messages and log the search results

The task uses a powerful/dangerous cmdlet that can do nasty things if incorrect, so i highly recommend running a test beforehand. Below is an example to test what you are going to delete. It will run a scan (based on what and where you searched) and give you a report of the output, along with the locations of the items and where they are located.

Get-Mailbox -Server  "*Server*" | Search-Mailbox -SearchQuery 'Subject:"*Subject*" and Body:"*Body*"' -targetmailbox "*SearchMailbox*" -targetfolder "*SearchFolder*" -logonly -loglevel full

The above code searches a particular server (and all the databases on it) for a query that meets a particular subject and body. It then sends the logs to the particular mailbox and folder.

Preview of the output:

Notes:

Use the Shell to search for and delete messages

All that is left to do now is run the command that will commit the process. There are many variations in what you can do so i will include several examples to suit the most common scenarios:

  • Delete all emails that meet the search query
    Get-Mailbox -Server  "*Server*" | Search-Mailbox -SearchQuery 'Subject:"*Subject*" and Body:"*Body*"' -deletecontent
  • Copy all emails to a single mailbox, then delete the emails
    Get-Mailbox -Server  "*Server*" | Search-Mailbox -SearchQuery 'Subject:"*Subject*" and Body:"*Body*"' -targetmailbox "*SearchMailbox*" -targetfolder "*SearchFolder*" -loglevel full -deletecontent

Resources that i helped me get here

Need to delete email from all users mailboxesNeed to delete email from all users mailboxes

Leave a comment ?

46 Comments.

  1. Corbett Enders

    Awesome tip, thank you. Easy to use. Finally got rid of a SPAM email that was driving me crazy (as all of the staff were forwarding it to me).

  2. This is exactly what we need! Unfortunately, only the search and log command works. When running the commands to delete all emails or copy all emails to mailbox then delete, I get the error “The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
    + CategoryInfo : InvalidArgument: (.:PSObject) [Search-Mailbox], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,Search-Mailbox”

    Help!

    Thanks in advance 🙂

  3. Very cool. And a little scary too. Thanks!

    I used this command to limit the scope for a trial run:

    Get-Mailbox -Database “DatabaseName” | Search-Mailbox -SearchQuery ‘Subject:”*Subject*”‘ -targetmailbox “*SearchMailbox*” -targetfolder “*SearchFolder*” -loglevel full -deletecontent

    Worked great.

  4. Very good article. I will be experiencing a few of these
    issues as well..

  5. Very good write up i also found it useful to use the attachment command as well?

    Get-Mailbox -Server “ws-vafb-mbx01” | Search-Mailbox -SearchQuery ‘attachment:”*FileName.pdf*”‘ -targetmailbox “MailBox.Name” -targetfolder “FolderName” -loglevel full -deletecontent

  6. Found this post after a Google search. Very clear and sorted the issue we had after a user sent a rather large email to over 400 staff!

  7. Thanks Ivan, this helped us get rid of an email a naughty student sent around school. We had to enable the command first, we referenced http ://www .techieshelp .com/delete-mail- from-multiple-mailboxes/ for anyone who has the same issue

    • Hi Ben,
      Not sure if you noticed but my article specifies how to enable the command as well. Its the first bit of code in the article under Prerequisites.
      The difference between the two articles is that I recommend using AD security groups to manage the permissions. I feel it gives you more flexibility and uniformity.
      Either way, hope the article was useful for you.
      Cheers,
      Ivan

  8. I received the same error as Susan. the commands I had run was the create new group, give them permissions, ran the create log, which all worked as expected. Then when I ran
    Get-Mailbox -Server “Mail” -resultsize unlimited | Search-Mailbox -SearchQuery ‘Subject:”Meeting-Confidential” -targetmailbox “edward” -targetfolder “inbox” -loglevel full -DeleteContent

    I got the error
    The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
    + CategoryInfo : InvalidArgument: (.:PSObject) [Search-Mailbox], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,Search-Mailbox

    for every mailbox in the organization.

    • Hi Edward,
      Its hard to diagnose why it doesn’t work from my end so I suggest you try the following:
      – Create new mailbox and add some emails to it. Re-Run the script above but target the above mailbox to make sure the searching works. eg:
      Get-Mailbox -identity ‘testuser’ | Search-Mailbox -SearchQuery ‘Subject:”*” -targetmailbox “edward” -targetfolder “inbox” -loglevel full
      The above should report EVERYTHING in that mailbox into your mailbox.
      -Test the targetfolder to be other than “inbox”
      I have never tried to go directly to the inbox – I always used a descriptive name.
      -Exchange – what version are you running? I have only tested this (from memory) on Exchange 2010 SP1 Update Rollup 2, and Exchange 2010 SP2.

      Let me know how that goes, and if its still a prob ill look into it some more for you.
      Cheers,
      Ivan

  9. Edward …

    you are missing the ending single quote character.

  10. What am i doing Wrong??
    [PS] C:\Windows\system32>Get-Mailbox -Server “TITAN” -ResultSize unlimited | Search-Mailbox -SearchQuery ‘subject:”Re: [#63] IT NOTIFICATION :- Network Outage – 21-22 December 2012″‘ -DeleteContent
    The term ‘Search-Mailbox’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check
    the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At line:1 char:67
    + Get-Mailbox -Server “TITAN” -ResultSize unlimited | Search-Mailbox <<<< -SearchQuery 'subject:"Re: [#63] IT NOTIFICA
    TION :- Network Outage – 21-22 December 2012"' -DeleteContent
    + CategoryInfo : ObjectNotFound: (Search-Mailbox:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

  11. How can you count how many mailboxes have that specific message?

    • Hi Val, it produces a csv when in logging mode, which you can easily then count the number of rows of the csv or similar. Let me know if you get stuck.

      I also updated the PowerShell script to display in colour coding – may help understand it better for users learning PowerShell.
      Cheers,
      Ivan

  12. This works great, thank you!

  13. Very awesome. Saved me big time. Thank you for this!!!

  14. I also had the ‘The term ‘Search-Mailbox’ is not recognized as the name of a cmdlet, function, script file, or operable program’ error.
    I found the solution on Stack Overflow, but will summarize here:
    This problem happens because your account is not a member of the Discovery Management role. Since your account does not have permission to perform searches, Powershell does not import the Search-Mailbox cmdlet.

    In Active Directory, add the account to the Discovery Management group, then close and restart your Powershell session.

  15. Is it working in Exchange 2010 without service pack?

    • Hi Mik,
      I suspect it may not work with Exchange 2010 without SP1. To validate it, try to use it.
      Also make sure the following cmdlets are available in PowerShell:
      – Search-Mailbox
      – New-ManagementRoleAssignment
      Please reply back if it works. Would love to know.
      Cheers,
      Ivan

  16. can the -SearchQuery parameter search on multiple properties? Like can I search for an email with a specific subject received or sent on a certain date or date range at the same time. So far I’ve not figured out how to do that

    • Hi Johnathan,
      Yes it can do that. You can have very granular queries that include sender, recipient, subject, body, attachment etc. The trick is to get the syntax right. I will put some more examples on the search queries that you might be interested in and post them up in the coming days.
      Lastly sorry for the very long delay in replying – is very rude of me and i apologise.

      Ivan

  17. Bill Parrish

    Hello Ivan,
    I was wondering if one of the -SearchQuery parameters could be MessageID? Ive used this procedure but found it would be easier after identifying the messages to delete it from all datatbases via MessageID.

  18. is there a way to do this but use a message ID instead of Subject and body strings?

  19. Thanks Ivan, this has helped lots.

    Is it possible to search for multiple subject lines? I’ve tried subject:”bah” -and “blahblah”‘ which didn’t work and also without the – in front of the -and but no luck.

    • Hi Mark,
      Your mentioned search query would not work, and based on the comments I have received I will write a separate article with many examples to help explain Advanced Query Syntax (AQS). For now try the following:
      Search-Mailbox -SearchQuery ‘(subject:”the sky is blue”) OR (subject:”they sky is red”)’
      This would return you all messages with either of the two subjects lines. If you want to search subject lines with specific words you could try the following:
      Search-Mailbox -SearchQuery ‘subject:(sky blue red)’
      This will return all emails that contain any of the words. So your search results may be higher than the first string.

      Cheers,
      Ivan

  20. I wanted to drop in some commands that I use daily to do this type of thing..to search for attachment type, subject and from.

    Get-Mailbox -ResultSize Unlimited | Search-Mailbox -SearchQuery ‘Attachment:”filename.zip”‘ -TargetMailbox UserName -TargetFolder Discovery -LogOnly -LogLevel Full

    Get-Mailbox -ResultSize Unlimited | Search-Mailbox -SearchQuery ‘Subject:”Vacation Trip (Help Needed)”‘ -TargetMailbox UserName -TargetFolder Discovery -LogOnly -LogLevel Full

    Get-Mailbox -ResultSize Unlimited | Search-Mailbox -SearchQuery ‘From:”name@company.com”‘ -TargetMailbox UserName -TargetFolder Discovery -LogOnly -LogLevel Full

    Few specifics:

    – Username – replace with your login\name for Exchange
    – Discovery – This makes a folder and drops everything in it on MY Inbox
    – LogOnly – This scans for it only. I then go into the Discovery folder and have a .zip file with the results. I open it to make sure I have the results I want and THEN change LogOnly to DeleteContent. I want to be 100% sure each time I mass delete that the info is what I expect. Its worth it to wait a few minutes to scan then delete then deal with a mass delete catastrophe.

    WARNING: In my experience using wildcards * is very dangerous and one wrong typo could mass delete emails. I always run the scan first, then delete. We have about 700 users and each scan takes a few minutes.

    • Hi Keith,
      Thanks for this – i wil be creating a new post with many variations for others to use – ill include the ones you have created there as well (once i get around to writing it).
      Cheers,
      Ivan

  21. Thanks Ivan, what if you want to delete messages from a specific date range, is that possible?

    • Hi Lance,
      Yes this is absolutely possible. Note there are differences between EX2010 and EX2013 commands on doing this. I will write a separate post with many examples including date rages soon. Keep an eye out (hopefully in the next week or two).
      Cheers,
      Ivan

  22. I really want to search a mailbox, forward all messages in that mailbox to an external email and then delete all emails in the mailbox. Any tips? I can’t just forward.

  23. Hi all,
    I could really use some help with a couple of commands to help me search and destroy specific emails. I need a way to get at the emails.In the past I have been able to create the syntax – but I seem to be hitting a wall. In short order I would like help in getting the correct exchange 2010 syntax for the following lines:

    Thanks in Advance
    Lance

    Export-Mailbox -identity user -StartDate ’01/01/2000′ -EndDate ’08/10/2013′ -SenderKeywords “sender@domain.org” -DeleteContent -allowDuplicates -Confirm:$false

    • Hi Lance,
      Im not sure if you have actually read my blog post. The command Export-Mailbox was used in Exchange 2007, and possibly Exchange 2010 RTM.

      If you are using Exchange 2010 SP1 or higher, the command should be similar to the following:
      Get-Mailbox -Server “*Server*” | Search-Mailbox -SearchQuery ‘Subject:”*Subject*” and Body:”*Body*”‘ -targetmailbox “*SearchMailbox*” -targetfolder “*SearchFolder*” -loglevel full -deletecontent
      Now there are additional -SearchQuery parameters that allow you to search for the sender and recipient, as well as date ranges.

      Hope that helps,
      Ivan

  24. Thanks Ivan – great post as usual! I often read your blog, always good info, well detailed.

  25. Michael Chapman

    Thank you for your post! I had a user that sent 37 MB of pictures out to 200 users! 7 GB of space occupied by pictures! Your post allowed me to get rid of the email(s).

Leave a Reply

QR Code Business Card
%d bloggers like this: