Using Search-Mailbox to look for items with a specific date


A question from a reader is often a good start to a useful discussion or to probe into a topic. Tim Read contacted me to discuss some problems he had with using the Search-Mailbox cmdlet (available in cloud and on-premises versions of Exchange). In this case, he was using Exchange 2013 CU5 and wanted to be able to search mailboxes for items that matched specific values for the sender, date, and subject attributes.

Apparently it was easy enough to run a search that found items that matched a combination of sender and subject but things got a little tricky when a date was thrown into the mix and not much joy was extracted from examples found on various sites.

Parser errors were reported when a date was specified, which indicated that the date was in a format unacceptable to Search-Mailbox. Some confusion arose on this point as it is natural to assume that search criteria have to be stated in KQL syntax because this is what is used by the Search Foundation, which provides the indexes that Exchange interrogates to perform mailbox searches.

However, the Search Foundation was only introduced in Exchange 2013 and code written for Exchange 2010 has to continue working on Exchange 2013 or in Office 365. The cmdlet therefore masks the change that occurred in the underlying search engines. Dates should be formatted like any other date consumed by Exchange according to the locale installed on the server.  So 1 October 2014 is “1/10/1014” in Ireland or the U.K. or “10/1/2014” in the U.S. Alternatively, you can pass a date like “14-Oct-2014” in either locale.

Now that we understand how to format dates, we can construct a Search-Mailbox command to do the work. This example creates a collection of mailbox objects from a database and searches them for items sent by a user called “Ben Andrews” (the SMTP email address for the user can also be used) on 13-Oct-2014 with “Interesting” in the message subject. Items in the Recoverable Items folder structure are included in the search.

Get-Mailbox –Database VIP –ResultSize Unlimited | Search-Mailbox -TargetMailbox AdminSearchMailbox -TargetFolder “Search Results” -SearchQuery {Subject:"Interesting" AND From:"Ben Andrews" AND Sent:"10/13/2014"} -LogOnly -LogLevel Full –SearchDumpster

This command will create a log of the discovered items in the target folder in the target mailbox. No items are copied unless the –LogOnly switch is removed. If the command is then rerun, Exchange creates a folder named after the searched mailbox and date and time in the target folder and copies the discovered items there, placing them in sub-folders corresponding to the folders in the source mailbox.

Search-Mailbox is often to remove unwanted items that arrive into user mailboxes. This is done by adding the –DeleteContent switch to a command. Clearly you should not rush into removing content from mailboxes until you are absolutely sure that your command targets the correct items, which is one good reason to run a command with the –LogOnly switch before proceeding to delete anything.

Exchange protects administrators against themselves by requiring those who want to delete content to possess the special “Mailbox Import Export” Role-Based Access Control (RBAC) role. As the role name implies, it is designed to allow administrative access to user mailbox data to import data from PSTs or export items to PSTs. In this instance, it’s used because deleting content is obviously something that should be controlled.

If your account does not hold the role, you won’t see the –DeleteContent switch or be able to use it with the Search-Mailbox cmdlet. You can either create a new RBAC role group containing the role and assign it to the appropriate users or add the role to an existing role group, which means that any user that is already part of the group will be able to use the switch. For instance, here’s how to add the role to the Organization Management role group, which is what I did for my Office 365 tenant.

New-ManagementRoleAssignment -Name "Import Export_Organization Management" -SecurityGroup "Organization Management" -Role "Mailbox Import Export"

You have to create a new EMS session to pick up the RBAC amendments because RBAC only evaluates a user’s permissions when EMS initializes. Once EMS is ready, I can run a command like this to remove the offending content.

Get-Mailbox –Database VIP –ResultSize Unlimited | Search-Mailbox -TargetMailbox AdminSearchMailbox -TargetFolder “Search Results” -SearchQuery {Subject:"Interesting" AND From:"Ben Andrews" AND Sent:"10/13/2014"} -DeleteContent -LogLevel Full –SearchDumpster

So there you are… A reader query that led to some interesting consideration of a very useful command and its various switches. Hopefully this will help others who struggle with similar challenges.

Follow Tony @12Knocksinna

About Tony Redmond

Lead author for the Office 365 for IT Pros eBook and writer about all aspects of the Office 365 ecosystem.
This entry was posted in Exchange, Exchange 2010, Exchange 2013 and tagged , , , , , . Bookmark the permalink.

60 Responses to Using Search-Mailbox to look for items with a specific date

  1. Pingback: Weekly IT Newsletter – October 13-17, 2014 | Just a Lync Guy

  2. Pingback: NeWay Technologies – Weekly Newsletter #117 – October 16, 2014 | NeWay

  3. Pingback: NeWay Technologies – Weekly Newsletter #117 – October 17, 2014 | NeWay

  4. Rich says:

    How can you use a variable for say the subject? I’ve tried every which way but cannot get it to work when I insert a variable. It just returns nothing.
    $subject =”interesting”
    Get-Mailbox –Database VIP –ResultSize Unlimited | Search-Mailbox -TargetMailbox AdminSearchMailbox -TargetFolder “Search Results” -SearchQuery {Subject:”‘$subject'” AND From:”Ben Andrews” AND Sent:”10/13/2014″} -DeleteContent -LogLevel Full –SearchDumpster
    .
    running it without the variable returns the correct results, running it with the variable returns 0 results

    • I was able to run a search using a variable with:

      Search-Mailbox -Id MailboxToSearch -TargetMailbox AdminSearchMailbox -TargetFolder “Search Results” -SearchQuery {Subject:$Subject -AND …}

      Putting the variable inside quotes stopped PowerShell resolving its value.

    • Dilip says:

      hi Rich,

      I have the same issue for $subject variable inside searchquery. Tried all permutations and combinations with single quotes, double quotes, braces etc. No luck. Did you find a solution?
      foreach ( $line in $info ) {
      Search-mailbox -id $line.RecipientAddress -SearchQuery { “Subject:$($line.Subject)” } -TargetFolder Purge -TargetMailbox **** -LogLevel Full
      }

      • Try using Invoke-Command. This code worked for me:

        $Users = import-csv “C:\temp\people.csv”
        ForEach ($i in $Users) {
        $Search = “Subject: ” + $i.Subject
        $Command = { Search-Mailbox -Identity $i.Name -SearchQuery $Search -TargetFolder Search -TargetMailbox CServices -LogLevel Full }
        Invoke-Command -ScriptBlock $Command }

  5. DamianD says:

    You should really try out Lookeen (www.lookeen.com). It is a great search outlook plugin that finds everything from text passages to dates or attachments in no time. Really handy tool. There is a 14 day full version trial so just try it out.

    Disclaimer: I work for the developer of Lookeen

    • Shah says:

      Lookeen is more for Outlook Mail Search. Can it sear Exchange MB Databases?

    • MR ARTWELL MATIZA says:

      Hi Tony
      Thank you for this. Am trying to do a search for emails with 5 search terms either in the body or subject field sent between a combination of 6 users over a period of 6 months. The search result need to be a pst file. Can you please assist me with the script to use? Our environment is hybrid and we use an on prem exchange server.

  6. Steven Saporito says:

    Tony,

    Thanks for the article. Was just wondering if there’s an AQS keyword for the folder? And if so a syntax example would be killer. I’d like to use New-MailboxSearch to get estimates of items in specific folders (particularly Inbox & Sent Items) within given date ranges. Unfortunately there doesn’t seem to be an include/exclude folder parameter as there is with New-MailboxExportRequest.

    Any information you can provide would be very appreciated. Thanks.

    Steven

  7. Sonny Sonikar says:

    Great Article, had to use it today, works, but the date field cannot be in Quotes. You need to have Sent:01/15/2015 (Or Received:01/15/2015).

  8. Pingback: Using PowerShell to Remove Specific Emails | Exchange Source Book

  9. notesbytom says:

    Reblogged this on Notes by Tom and commented:
    I don’t usually Reblog posts, but I found this Search-Mailbox article from Tony Redmond and it’s better than what I would write myself. Enjoy!

  10. Chen says:

    Great. Thank you!. Any way to search for certain words in message header? Also any way to delete all messages under one folder?

  11. Yaniv Schiff says:

    Great Info Tony. I was wondering if it’s possible to run a search bassed on a Conversation ID or IntMsgID or ConversationIndex.

  12. James Lipinski says:

    Is there a way to modify the mail search to look for email from a specific sender prior to a certain date?

    Thanks for the info.

    • What version of Exchange? With Exchange 2013 or Exchange Online you should be able to pass a date range to specify what you want. For example, -SearchQuery {Received:”01/01/2013..01/01/2015″}

      • James Lipinski says:

        I think I figured it out. Here is what I was able to come up with to do the search on Exchange 2010. This will only do the search and not copy the items or delete them. I thought I would share it back. Thank you for pointing me in the right direction.

        Get-Mailbox -ResultSize unlimited | Search-Mailbox -SearchQuery “from:noreply@contoso.com and Received:> $(’01/01/2014′) and Received:< $('12/31/2014')" -TargetMailbox "searchresults@contoso.com" -TargetFolder "SearchResults" -LogOnly -loglevel full

  13. btallon says:

    We ran this Search-Mailbox -identity username@contoso.com -searchquery {(Received:> 01/01/2015 and Received:< 01/03/2015)} -DeleteContent

    Unfortunately it also picks up contacts, calendars tasks and notes. Essentially everything. Is there any way to delete just email and leave the rest alone? Thanks for the article.

  14. BowDownToZod says:

    Is it only possible to restrict the search by date? Or can we narrow the results even further by adding a time parameter? For instance, if I want to return a messages that were sent 07/01/2015 15:34. Is this possible?

  15. Pingback: Removing on-hold items from Exchange and SharePoint: unsupported but doable | WebSetNet

  16. RobM says:

    Hi Tony. I am trying to search for the number of “Deleted Items” for a date range, in particular, the number and size of emails that were deleted more than 14 days ago. I DON’T need the information for the ‘recoverable items’, just what in the “Deleted Items” folder. I can’t seem to find anything to allow me to do this. Do you have any suggestions?

    I am using a similar script on Exchange 2010 to locate number and size of “Sent” emails older than 13 months (395 days).

    $today=(get-date).adddays(-395)
    $users = (Get-Content C:\psscripts\CheckMailAge\valid_users.txt)

    foreach ($user in $users){
    write-host “Working on mailbox for ” $user
    search-mailbox -identity $user -targetmailbox ‘Test User1’ -targetfolder ‘NBFCMailsent-395’ -searchquery “Sent:< $($today)" -logonly -loglevel full | select identity, displayname, database, ResultItemsCount, ResultItemsSize | ft -hidetableheaders DisplayName,Database,ResultItemsCount,ResultItemsSize | out-file -Append -NoClobber .\AllUsersSentItems-395Days.txt
    }

    Much appreciated!
    Rob.

  17. Panzerbjrn says:

    Great article, thanks.

    Is there a way to output the results, i.e. all messages with a certain subject?
    Just the good stuff like sender, recipients, subject, attachments and so on?

    Thanks,
    Lars

  18. Martin Wells says:

    Tony,

    Is there anyway to seach for email with a certain MessageID instead of by subject? Thanks for the great article btw!

  19. Ken says:

    Tony,

    I need to search mailboxes for emails with a specific subject, and a from address but I only want to use the domain, not the email address for the from value. Is this possible?

  20. PowerMapi says:

    For those that find themselves on this thread and still get tripped up on this, there’s a better alternative now: PowerMapi (http://powermapi.com/cmdlets).

    PowerMapi is a .NET compiled powershell module that provides direct access to MAPI.
    For example, to get the results requested by the title of this post with PowerMapi:

    import-module PowerMapiLoader
    $sess=new-MapiSession OutlookProfileName
    $inbox=get-MapiFolder $sess Inbox
    $found=search-MapiItems $inbox “PR_SUBJECT -has redmond -and PR_MESSAGE_DELIVERY_TIME -btw 12/1/2016::1/1/2017”

    In the above, which is hopefully simple to understand, the -btw operator is ‘between’. The search feature in PowerMapi is a “brute force” search meaning that it is not based on the limitations of MAPI’s ‘restriction’ structures (for those MAPI devs out there :). This means that the list of operators and how it works is more flexible and feature rich, including Regular Expression matching, courtesy of the .NET framework!
    So, it’s possible to do something like: search-MapiItems $inbox “PR_SUBJECT -match regex pattern goes here -and attach(PR_ATTACH_FILENAME -match regex pattern here also)”
    This will search for subjects AND attachment names!

    • Courtney Piratzky says:

      YES!! Can this tool take action on items in the folder “Top of Information Store” and be done by an admin as opposed to MFCMapi requiring a profile using the user creds? I’m wanting to move items out of “Top of Information Store” and into an actual folder.

      • PowerMapi says:

        It’s possible, but it is mapi and still requires a profile.
        The key to this is permissions up front. if you create a new user account in the domain/environment and either give it full access permission to all the mailboxes you want to open, or give this account Receive-As (and possibly Administer Information Store for system privilege) to the database(s) of the mailboxes, you can open the mailboxes you want from a single profile.

        this would be done by the Open-MapiExchangeMailbox cmdlet.

        once you get the reference to a user’s mailbox store, you can get the IPM_Subtree (aka “Top of Information Store”) quite easily and then get to any contents.

  21. dixonjaimy@sbcglobal.net says:

    How do you stop a search-mailbox -deletecontent command from running if someone used the -force parameter?

  22. Sandy Wood says:

    We’re looking to search for specific strings like CI or SP but all our testing has shown that eDiscovery on Exchange 2013 returns everything with ci or sp in it. Has anyone grappled with this and found a solution?

  23. Pingback: Using Different Queries When Processing Multiple Mailboxes with Search-Mailbox - Office 365 for IT Pros

  24. Michelangelo says:

    If I have a list of recipients, let´s say Mailx.txt I usually were doing a Get-Content Mails.txt | Search-Mailbox …….

    now I do not why but the cmdlet runs and only runs the search on the last user of the mails.txt. How do I do to make the search to run on each of the addresses in that Mails.txt

  25. Owen Frederick says:

    Tony,
    I’m just an average user, and I’m trying to search my mailbox for emails sent to John Doe, or Jane Doe, or Jim Doe, but no one else. The problem I’m running into is excluding emails which are to one of those individuals, but also include anyone else.

    (to:(”Doe, John” OR ”Doe, Jane” OR “Doe, Jim”) AND (NOT( NOT to:(”Doe, John” OR ”Doe, Jane” OR “Doe, Jim”))

    Any help you can offer would be appreciated.

  26. Pingback: 具有多个短语的Exchange 2013电子邮件搜索 - 实战宝典

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.