[Update]: This article was last updated on April 22, 2024.
Applies to: Exchange 2019, Exchange 2016, Exchange 2013, Exchange 2010. For Exchange Online, this method is no longer supported. Learn how to use the new version of Search-Mailbox to search and delete mailbox content in Exchange Online, Exchange 2019 and Exchange 2016
In this article, I am going to show you how to use the Search-Mailbox PowerShell cmdlet together with the -DeleteContent switch to delete email (and other item types) from multiple mailboxes on Microsoft Exchange Online, as well as on-premises Exchange.
I will also discuss the -SearchQuery parameter to manage item scopes and target specific content.
Contents
- Required permissions
- Searching and deleting content from one mailbox
- Limiting the scope of deleted items
- Examples of condition queries
- Deleting emails from multiple mailboxes
- Additional switches and parameters
- Suggested tools
Required permissions
The minimum required permissions to be able to perform searches and deletions are:
You can assign them via Exchange admin center, Permissions, admin roles (Exchange 2010: ECP, Roles & Auditing, Administrator Roles).
- Mailbox Search is by default part of the Discovery Management role.
- Mailbox Import Export is not part of any of the default role groups, so you have to either add it to e.g. Discovery Management or create a custom role group for Mailbox Search and Mailbox Import Export.
To assign the roles directly to a user via PowerShell, run:
New-ManagementRoleAssignment -Role "Mailbox Import Export" -User "<user name or alias>"
New-ManagementRoleAssignment -Role "Mailbox Search" -User "<user name or alias>"
After you assign the permissions, restart the PowerShell console. Otherwise, Search-Mailbox won’t be available for you.
Learn more about Role Based Access Control
Searching and deleting content from one mailbox
Before we discuss deleting items from multiple mailboxes, lets take a look at a very basic Search-Mailbox command that lets you delete all content from a single mailbox:
Search-Mailbox -Identity "<User's Name, Alias, DN, GUID, SMTP email or UPN>" -DeleteContent
Tip 1: To skip the confirmation prompt use the -Force switch. Otherwise, PowerShell will prompt you to confirm that you want to delete mailbox content:
Tip 2: To check how much data you will be deleting, first run the Search-Mailbox command with the -EstimateResultOnly switch first, instead of using -DeleteContent right away (you can have the same information sent to a selected mailbox using the -LogOnly switch, but keep in mind that it requires you to provide a target mailbox and folder).
Limiting the scope of deleted items
You can limit the scope of the search & delete process using these parameters:
-SearchQuery
In Exchange 2010, 2013, 2016 and 2019, the range of queryable item properties and operations you can perform on them is quite wide.
You can use all properties listed in this article and the operations you can perform on them come courtesy of KQL (Keyword Query Language). Specific examples of queries in section below.
Note: Exchange 2010 uses a query language, which is slightly less agile. Learn more in this Microsoft documentation.
-SearchDumpster
By default the Recoverable items folder of a mailbox is searched. To exclude it add -SearchDumpster:$false
to your script.
-DoNotIncludeArchive
Excludes the archive of a given mailbox (switch).
-SearchDumpsterOnly
Limits the search and deletion to the Recoverable items folder of a given mailbox (switch).
Examples of condition queries
The section below contains excerpts of scripts targeting types of items that I think will be most useful. If you would like to see an addition to this list, please let me know in the comments.
Deleting emails with #keyword# in the subject received from someone outside of your domain
Search-Mailbox ... -SearchQuery 'subject:#keyword# AND from<>#Your domain#' -DeleteContent
Deleting emails and calendar events received prior to a specified date
Search-Mailbox ... -SearchQuery '(kind:email OR kind:meetings) AND received<#Date in MM/dd/yyyy format#' -DeleteContent
Deleting emails with total size of attachments over #number# bytes
Search-Mailbox ... -SearchQuery 'hasattachment:true AND size>#number#' -DeleteContent
IMPORTANT: Since the size attribute only checks the size of the entire message, this query may target a slightly larger scope of items with attachments than just the ones with total size of attachments exceeding #number#.
List of properties you can query using Search-Mailbox
Deleting emails from multiple mailboxes
To extend the search and delete process to multiple mailboxes you can use PowerShell’s pipeline or foreach loop mechanism.
For example, the below commands delete content that matches #Your query# from all mailboxes that can be found in an organization:
Get-Mailbox | Search-Mailbox -SearchQuery '#Your query#' -DeleteContent
foreach ($mailbox in (get-mailbox)) {Search-Mailbox -id $mailbox -SearchQuery '#Your query#' -DeleteContent -Force}
NOTE: When using the foreach method, I recommend appending the command with a -Force switch. Otherwise you will have to confirm the content deletion for each individual mailbox.
The result of the two above commands is identical in terms of deleted content.
If you add a target mailbox and folder to the command (see Additional switches and parameters below), the Get-Mailbox pipeline will generate 1 search summary and log file, while the foreach loop will generate separate search summaries and log files for each mailbox.
Both methods allow for limiting the scope of mailboxes on which the search and delete operation is performed.
The Get-Mailbox pipeline also lets you perform simple scoping operations, such as limiting the output to a defined mailbox database, organizational unit, domain, or mailboxes of a certain type. For further details see this Microsoft documentation.
Additional switches and parameters
After you run the Search-Mailbox command with the -DeleteContent switch, the output is going to contain a very basic summary of the process (example in below image).
-EstimateResultOnly
As I mentioned earlier, you can use this switch to get the above type of summary, before using the -DeleteContent switch. Note that -EstimateResultOnly cannot be used together with -DeleteContent. Example:
Search-Mailbox ... -SearchQuery '#Your query#' -EstimateResultOnly
-LogOnly
By default the -LogOnly switch sends the exact same basic information as -EstimateResultOnly to a specified mailbox. This is because the default log level is ‘Basic’. You can change this by raising the log level to full.
Note that, when using the -LogOnly switch, you have to define the target mailbox and folder and you cannot use the -DeleteContent switch. Example:
Search-Mailbox ... -SearchQuery '#Your query#' -LogOnly -LogLevel:full -TargetMailbox #Mailbox id# -TargetFolder #Folder name#
-LogLevel
You can also use the -LogLevel parameter together with the -DeleteContent switch to obtain detailed information about what has been deleted. Like above, you will have to raise the log level to full and specify a target mailbox and folder.
After the search and delete process succeeds, in the specified location you will find an email with a zipped CSV file attached containing a list of deleted items.
Search-Mailbox ... -SearchQuery '#Your query#' -DeleteContent -LogLevel:full -TargetMailbox #Mailbox id# -TargetFolder #Folder name#
Hello Adam,
While running the query
“Search-Mailbox [email protected] -SearchQuery ‘from:[email protected]’ -DeleteContent” getting below error. I already assigned all the required permission to my user.
Error “Search-Mailbox : 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:1
+ Search-Mailbox user1 -SearchQuery ‘from:@domain.com’ -Dele …
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Search-Mailbox:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException”
Thanks Hafiz,
That’s true, Microsoft decided to sunset this search method after a while of keeping it unsupported but working. Take a look at the article that shows a replacement cmdlet: https://www.codetwo.com/admins-blog/new-compliancesearch-new-version-of-search-mailbox/
Hi,
Is there any way to also delete folders created by users? I want to delete everything from every mailbox and leave it blank. I succeded with the deletion of all the emails using your guide but i cannot find a way to delete custom folders created by users.
Unfortunately, the cmdlet used in this article cannot target folders. Currently, there is no simple cmdlet that would allow you to delete mailbox folders, you would have to use, for example, an EWS-based script.
I’m migrating mailboxes to Exchange Online from GroupWise and having to reset some mailboxes by deleting all of their contents. I’m trying “search-mailbox username -deletecontent” .. is that still the valid command? Of course I get warnings about unspported and to use New-MailboxSearch but not sure theres an equivalent delete command. Help appreciated!
The last time I checked, Search-Mailbox still worked like a charm, despite all the warnings. The alternative, New-ComplianceSearch & New-ComplianceSearchAction is described in this article. It’s not perfect though, as by default it deletes up to 10 items. It means that you either have to loop it and hope for the best, or check if Search-Mailbox still works in your environment, since it is a quick, easy and highly effective method.
Please, is there a way, the Email can be deleted, declaring a Subject without affecting the Reply emails on the same Subject Email from the recipient
Ideally, it should work if you use Subject=”exact subject” format in the Search Query (as opposed to Subject:”exact subject”, which checks if the subject contains your phrase). However, it would be best to test it thoroughly with the -EstimateResultOnly parameter before actually purging mailboxes’ content.
https://docs.microsoft.com/en-us/powershell/module/exchange/search-mailbox?view=exchange-ps
“Note: In cloud-based environments, the Search-Mailbox cmdlet is being deprecated in favor of New-ComplianceSearch and related eDiscovery cmdlets.”
https://www.codetwo.com/admins-blog/new-compliancesearch-new-version-of-search-mailbox/
“New-ComplianceSearchAction is not intended for a mass cleanup of mailboxes, as it only deletes 10 items per mailbox at a time.”
If CodeTwo would add functionality for emptying mail boxes that would be a killer feature.
Hi, is there a powershell for exchange online to deleted all the emails only in the deleted folder for one particular mailbox.
When i menualy try deleting the emails from the deleted folder it reappears again.
Unfortunately, Search-Mailbox doesn’t allow you to filter by folders.
If you are using desktop Outlook, you can try Outlook on the web instead. If that doesn’t help, you can target those emails by Search-Mailbox or eDiscovery by subject and date and purge them that way.
Hello, was hoping you might be able to assist with a task we do regularly. We get a lot of phishing / spam, when it goes to a bunch of users we do a compliance search for the email then delete the email from everyone’s mailbox via powershell. Is it possible to search for the email based on date / subject / sender and list whats found eg using the EstimateResultOnly parameter. If everything is captured and nothing else valid, then delete them vs needing to do the compliance search which takes some time.
Hello Michael,
When you specify the -SearchQuery to your liking, instead of using the -DeleteContent switch, use -TargetMailbox, -TargetFolder, -LogOnly and -LogLevel Full attributes to get detailed information about what the search returns. While not perfect, it might go a lot quicker than the Compliance Search.
What about needing to clear out more than the 10,000 item limit. It says use “new-mailboxsearch” but I cannot find any clear coding to remove emails older than XX from a single mailbox.
Any ideas?
The easiest way to cope with this limit is to perform purging in batches. It depends on what filters you already use, and how many items you need to delete in general.
It’s still much better than the 10 item limit in New-ComplianceSearch.
Hello,
I have a problem, and I can see that it is already discussed here, I would like to delete the contents of the mailbox everything older than 01/01/2020 – for this I use the command:
Get-Mailbox [email protected] | Search-Mailbox -SearchQuery 'received<=01/01/2020' -DeleteContent
unfortunately it does not work, my console says that:
A parameter cannot be found that matches parameter name ‘DeleteCntent’.
+ CategoryInfo : InvalidArgument: (:) [Search-Mailbox], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Search-Mailbox
+ PSComputerName : servername.domain.local ;)
is this a syntax issue in the context of exchange? my exchange is 15.1
Hi,
Judging from the error, you just need to change -DeleteCntent to -DeleteContent
If you still cannot use the cmdlet, check if your account is assigned all the necessary permissions.
Hi Adam,
Great post!
How would I utilize this to make sure the message/attachments are also deleted from the Exchange DBs?
Search-Mailbox with the -DeleteContent switch, is designed to purge content from Exchange DBs. When content is no longer discoverable with Search-Mailbox or New-ComplianceSearch, it is no longer available on the server level.
hello i have a question, can i retrieve or recover the deleted message, i used this command to delete the messages
get-mailbox -resultsize unlimited | search-mailbox -SearchQuery “news clippings” -DeleteContent
and we dont have any back up of the database
thank you.
If the items are no longer found using the Search-Mailbox command (with the -EstimateResultOnly switch) and there is no backup, I’m afraid you will not be able to recover them.
Hi
I want to delete my old mails permanently and keep more space open. Pls advice how to do
tnks
Ben
Hi Benny,
If you are an admin with access to PowerShell, Search-Mailbox is still the way to go, for example the following cmdlet:
Search-Mailbox '[email protected]' -SearchQuery '(kind:email OR kind:meetings) AND received <01/01/2020' -DeleteContent
will delete emails and meetings received before 01/01/2020.
If you are a user, you can use retention policies to delete older items. This method is very useful, as you can apply different policies to different items and protect some items from being deleted.
Hi Guys,
i have accidentally deleted mailbox content using below PowerShell
Search-Mailbox -Identity “Email Address here” -DeleteContent -force
Is there a way to restore ? please help
thank you
Miki
Hi Miki,
If Search-Mailbox/eDiscovery no longer returns those mailbox items, they are gone for good. Did you have backup?
Get-Mailbox -Identity user -DomainController “domaincontroller” | Search-Mai
lbox -SearchQuery ‘”Kind:email AND Received:01/20/2020..01/20/2020″‘ -DeleteContent -Force -DomainController “domaincontroller”
I runned above commands but i result 0KB. Where ise problem?
Try the following syntax of the searchquery: -SearchQuery ‘(received:01/10/2020..01/20/2020) AND (kind:email)’
This is GREAT!! Would you recommend how this might be set up as a scheduled process to routinely clean this mailbox?
Hi Christopher,
You could create a script, set it to delete emails received more than 90 days ago {(Get-Date).AddDays(-90)} and configure it as a scheduled task, but you would need to refine the SearchQuery not to delete emails which should stay in mailboxes.
Keeping mailboxes clean might be a bit easier with retention policies, especially because you can set different policies for different folders, which would allow for an easy way for users to keep some email content without the troublesome PST archives, which are nearly impossible to manage.
Hi,
Thanks for this post. Anyways can I do a search mailbox having a -searchquery for fake hyperlinks in body? Please help!
Hi,
What do you mean by fake hyperlinks? You can use Search-Mailbox to look for any hyperlinks in the body of emails (-SearchQuery ‘body:”http://’), but I’m afraid that there is no “advanced searching feature”, unless you have a list of those links.
Adam,
terrific information. I am in the process of looking and try to set something up at our clients Exchange server.
we have barracuda in place, but every now and then something falls thru the cracks, and spam gets delivered. they are using employees names to attack, so it appears its good, but its not. so I end up blocking the domains at barracuda level, but I then end up having spam emails sitting on the users mailboxes waiting for someone to click on the link (not good news) I wanted to check a command to go into exchange and run so it finds the subject on all inboxes and deletes the item. I then thought, maybe I need subject, and sender as the email can be then be part of forwards and then how can I track it down for my work.
I wanted to know if its possible to setup some type of brainless .bat file that can ask other techs for subject line, and sender, so they can type those two, and then exchange takes care of the rest.
thanks in advance for your time and awesome blog you got going on!
Hi Adam, i am keeps trying but getting error, please let me know what’s wrong:
1- how can verify “Mailbox Import Export” roles? – have added successfully via powershell.
2- here is error i am getting:
Identity : SSO Email
TargetMailbox :
Success : False
TargetFolder :
ResultItemsCount : 0
ResultItemsSize : 0 B (0 bytes)
How to fix this issue?
Below is command:
Search-Mailbox -Identity “sso” -SearchQuery ‘Subject:”[Password modified] user sso changed the password via Reset Portal”‘ -DeleteContent
Hi Naveed,
The easiest way to verify if your account has the Mailbox Import Export role is to look it up in Exchange Admin Center > permissions. You can define a new admin role group with the Mailbox Import Export role and assign your account to this group. Retry the Search-Mailbox cmdlet, then.
Hello, when I try to run the search-mailbox, success is set to false, it does not give error, it only gets false, what can it be?
This error usually occurs when the admin does not have sufficient permissions. Please make sure the admin has “Mailbox Search” and “Mailbox Import Export” permissions assigned.
Also verify if a memeber of “Organization Management” role group (with “Mailbox Import Export” role added manually) gets “false” in the report, as well.
It appears that the “-EstimateResultsOnly” should be “-EstimateResultOnly” – eg: There is no S after result
Thank you, you are right! I have just corrected this in the article. Well, that will teach me to copy the scripts directly from the console and not type them from memory…
Running Exchange Online with archive mailboxes
Is there a way to specify just the archive mailbox of a user
Looking to delete data only in the archive mailbox for the user
I tried specifying the archive GUID of the mailbox in the search-mailbox -identity but does not seem to work.
Any ideas when we will have a switch which says “IncludeArchiveOnly”
Appreciate your thoughts. as always gr8 post
Trying to purge all mailboxes “Deleted Items” folder. Can you advise what syntax is for removing all mail from a specific folder?
The problem is, -SearchQuery does not allow you to limit results to a certain folder. You can specify the deleted items retention to the minimum and the deleted items folder should be purged automatically. See this TechNet article for details.
Running Exchange 2013
I’m trying to delete all emails, using participant and receive. I cannot get the received query to work with < symbol for example if I run this on a test mailbox, it succeeds but I get zero results. There are emails in there from 12/2016.
Search-Mailbox -identity "user" -SearchQuery 'Received:<01/01/2017' -deletecontent
Hi David,
I’ve tested your cmdlet and it worked when used without a colon, like that:
Search-Mailbox -identity "user" -SearchQuery 'Received<01/01/2017' –deletecontent
Please check if you’re getting any results now.
Hi Adam
Firs method not working for me.
but anyway we found solution,
get-mailbox -resultsize unlimited | search-mailbox -SearchQuery ‘subject:”ტესტი”‘–DeleteContent
it ”ტესტი” will appear as ?????? i exchange console but it swill works!
Thanks for support!
we are using this command to delete messages tought subject:
get-mailbox -resultsize unlimited | search-mailbox -SearchQuery ‘subject:”free sex”‘–DeleteContent -Force
but unfortunately we didn’t know how to delete message if subject is whitened in Unicode for example if subject is “ტესტ” this word is not recognized exchange command line :(
please help how to solve this problem
Hi Mitxujan,
Please try applying this solution: http://silentcrash.com/2012/05/how-to-add-hebrew-to-powershell-or-command-cmd-console/ and then simply running:
... Search-Mailbox -SearchQuery 'subject:' ...
Other methods you could try is importing the subject into a variable from a Unicode file, e.g.:
$subject = Get-Content
or getting it from message tracking logs:
$subject = (Get-MessageTrackingLog -MessageID [email protected] | Select -First 1).MessageSubject
And then running:
... Search-Mailbox -SearchQuery 'subject:$subject' ...
Let me know if this helps,
Adam