Tuesday, 5 February 2013

Querying Exchange Mailboxes with Powershell

Exchange and Powershell go hand in hand - as it is essentially what Exchange is built on top of, and is what the Exchange Management Console (EMC) uses to execute commands you choose through the GUI. (Ever noticed you get the Powershell command line equivalent for commands you execute in EMC?)

One of the most common things an administrator will need to do is query all the mailboxes within the system for certain criteria, which I will explain and breakdown in this blog entry.

The command Get-Mailbox is one of the most useful and powerful commands you can use (for information gethering). It can be used to retrieve all the properties for all the mailboxes in your system, or can be tweaked to only return some of the properties for some of the mailboxes within your system.

If you execute the command Get-Mailbox on its own, you will probably be flooded with 1000 responses, followed by the following warning message;

WARNING: By default only the first 1000 items are returned. To change the number of items returned, specify the parameter "-ResultSize". To return all items specify "-ResultSize Unlimited" (Note: Returning all items may take a 
very long time and consume a large amount of memory depending on the actual number of items). It is not recommended to store the results in a variable; instead pipe the results to another task or script to perform batch changes

As per the message, the command on its own will only return the first 1000 results. You can change this by adding -ResultSize Unlimited to it, so it would look like this;

Get-Mailbox -ResultSize Unlimited

If you run this command it will run through and display the first few properties for every mailbox within your system. While this can be useful, the command can be further tweaked to run faster and provide more accurate/informative results.

To get all the properties for a single users mailbox, you can use the following command

Get-Mailbox -Identity "Morrissey, Peter"

You can replace what is between the " " with any identifier for the mailbox - such as Primary SMTP Address, Display Name or Alias.

When you run this command it will only display the first few properties as it is presenting the information in a table format. If you change the command to display in list format (by adding | fl), you get MUCH more information:

Get-Mailbox -Identity "Morrissey, Peter" | fl

Now you can view ALL the properties for an individual users mailbox. These properties apply to every mailbox within the system, so you can once again, modify the Get-Mailbox command to search on any of the properties you see in this list.

For example, if I wanted to query all the mailboxes within my system, and only return those whose 'Name' property contain the text "Peter", I would run the following command

Get-Mailbox -ResultSize Unlimited | Where {$_.Name -like "*Peter*"}

You still need to include -Resultsize Unlimited because although you aren't expecting more than 1000 results to be returned, you do want the Get-Mailbox command to query more than the first 1000 mailboxes, which it will not do if this omitted.

You can replace the $_.Name with any of the other properties for a mailbox - it just needs to have the $_. before it.

The -like operator can also be changed to use -eq (equal to) -ne (not equal to) -gt (greater than) -lt (less than) -le (less than or equal to) -ge (greater than or equal to)

Next you can fine tune the properties that you wish to display for each object whos name contains "Peter". Say you want to only display the DisplayName, Alias, Database and PrimarySMTPAddress properties for each of the results. You could use the following line

Get-Mailbox -ResultSize Unlimited | Where {$_.Name -like "*Peter*"} | Select DisplayName, Alias, Database, PrimarySMTPAddress

The benefit of doing this is that by retrieving fewer properties for each object, it speeds up the time it takes for the query to run. It also makes looking through the results much faster as you aren't reading over information you don't need. Once again, you can replace the properties I used with any of the properties available for each mailbox, as we discovered earlier.

Finally, you  can export the results of your query to a CSV file

Get-Mailbox -ResultSize Unlimited | Where {$_.Name -like "*Peter*"} | Select DisplayName, Alias, Database, PrimarySMTPAddress | Export-CSV -path "C:\Export.csv" -notype

Once you have the information in a CSV file you can attach it to an email and send it to yourself (or someone else) as per my previous blog post


  1. Thanks Peter. This was helpful

  2. Do you know whether this script:

    Get-Mailbox -Server "xyzsvr01.exch.xyz.edu" | Search-Mailbox -SearchQuery 'Subject:"Info!!!"' -deletecontent

    Would the script delete only emails with the exact subject "Info!!!" or all emails with the word "Info" anywhere in the subject? Thank you.

  3. It would be so much more helpful if you would show the output as well as the commands - or at lease some of the output followed by a truncate indication.