Returning Exchange Online Mailbox Information


Summary: Use Windows PowerShell to Manage Office 365 using Windows PowerShell cmdlets, scripts, and batch processes.

To give you a feel for some of the things you can do with Exchange Online and Windows PowerShell, let’s take a look at user mailboxes. As you might expect, you can easily get information about a single user mailbox; for example, here’s a command that returns some information about Ken Myer’s mailbox:

Get-Mailbox -Identity "Ken Myer"

That will bring back something similar to this:

Name      Alias       ServerName      ProhibitSendQuota
----      -----       ----------      -----------------
kenmyer   kenmyer     bn1pr02mb038    49.5 GB (53,150,220,288 bytes)

Now that’s nice: at a glance you can see things like Ken’s alias and his mail quota. But there’s so much more to an Exchange Online mailbox that just the four properties returned by the Get-Mailbox cmdlet. How do we access all that information?

Here’s how:

Get-Mailbox -Identity "Ken Myer" | Select-Object *

The syntax Select-Object * instructs Windows PowerShell to return all the information that can be returned by the Get-Mailbox cmdlet; for a user mailbox that turns out to be about 200 different properties and property values. As we’ve already seen, if we run the command Get-Mailbox –Identity "Ken Myer" then we only get back the small subset of information that the Get-Mailbox cmdlet returns by default. And, of course, you can always use the Select-Object cmdlet to specify a specific set of property values to be returned. You say you’re just interested in the litigation hold-related properties for Ken Myer? Then why didn’t you say so:

Get-Mailbox -Identity "Ken Myer" | Select-Object DisplayName, LitigationHoldEnabled, LitigationHoldDate, LitigationHoldOwner, LitigationHoldDuration

And here’s a handy little tip: you can use wildcard characters when working with the Select-Object cmdlet. For example, all the litigation hold properties start with the letters lit. That means we can retrieve this same information by using this command:

Get-Mailbox -Identity "Ken Myer" | Select-Object DisplayName, Lit*

That command tells Get-Mailbox to retrieve the value of Ken’s DisplayName property along with the values of any properties that have names that begin with the letters lit. Take a look at what we get back:

DisplayName            : Ken Myer
LitigationHoldEnabled  : False
LitigationHoldDate     :
LitigationHoldOwner    :
LitigationHoldDuration : Unlimited

In fact, we could make our command even shorter by using a wildcard for the DisplayName property as well:

Get-Mailbox -Identity "Ken Myer" | Select-Object Disp*, Lit*

And before you ask, yes, we could have shortened Lit* to just L*:

Get-Mailbox -Identity "Ken Myer" | Select-Object DisplayName, L*

The one drawback to that? You’ll get back all the property values that start with the letter L:

DisplayName             : Ken Myer
Location                :
LitigationHoldEnabled   : False
LitigationHoldDate      :
LitigationHoldOwner     :
LitigationHoldDuration  : Unlimited
Languages               : {en-US}
LinkedMasterAccount     :
LastExchangeChangedTime :
LegacyExchangeDN        : /o=ExchangeLabs/ou=Exchange Administrative 

That might be more information than you really want.

That’s also information about just a single mailbox. Can you return information about multiple mailboxes? Of course you can. All you have to do is leave out the Identity parameter:


Or, pipe that data to the Select-Object cmdlet to return a few specified property values:

Get-Mailbox | Select-Object DisplayName, LitigationHoldEnabled

That’s very nice, and very handy. On the other hand, there are going to be times when you want to look at just a subset of your mailbox accounts. For example, suppose you are asked to come up with a list of all the mailboxes that have been assigned a litigation hold. How quickly can you come up with that list? Well, if you have to return all your mailbox accounts, and then look through them one-by-one in order to find the accounts where litigation hold has been enabled, that could take a while (assuming that you have more than a handful of users). A better approach is to add a filter to your Get-Mailbox command, like this:

Get-Mailbox -Filter '(LitigationHoldEnabled -eq $True)'

Ah, good question: why didn’t we pipe the returned mailbox information to the Where-Object cmdlet, similar to what we did when we were working with Office 365 user accounts? Won’t this command work equally well:

Get-Mailbox | Where-Object {$_.LitigationHoldEnabled -eq $True}

To be honest, that depends on what you mean by “equally well.” The two commands will definitely return the exact same information. However, when you pipe something to the Where-Object cmdlet the process works like:

  1. The Get-Mailbox cmdlet contacts the server and retrieves all the available mailbox information.

  2. All that information is transferred over the network to your local computer.

  3. The information is then filtered on your local computer, with the “excess” data being discarded.

And what happens if you use the Filter parameter instead? This is what happens:

  1. The Get-Mailbox cmdlet contacts the server and the mailbox information is filtered on the server.

  2. Only that filtered information (which typically represents a very small subset of the total mailbox information) is transferred over the network to your local computer.

In other words, with the Filter parameter you let the server do most of the work, and you greatly reduce the amount of information that must be carried across the network. Which is just another way of saying that any time you have an Office 365 cmdlet that supports the Filter parameter you should use that parameter instead of Where-Object.


Well, depending on what you’re trying to filter on. Not all properties values can be used in a filter.

With that in mind, let’s try another filtered example. Maybe you’d like to know which users have enabled mail forwarding on their mailbox. Can you do that just as quickly? See for yourself:

Get-Mailbox -Filter '(DeliverToMailboxAndForward -eq $False)'

And if you’d like to limit the returned data to just the user’s display name and the address where his or her mail is being forwarded, well, why not:

Get-Mailbox -Filter '(DeliverToMailboxAndForward -eq $True)' | Select-Object DisplayName, ForwardingSmtpAddress

How about another one? Suppose you’d like to make sure that all of your users have the junk email rule enabled. Here’s a quick way to determine if any of your users don’t have that rule enabled:

Get-Mailbox | Get-MailboxJunkEmailConfiguration | Where-Object {$_.Enabled -eq $False}


Why didn’t we use the Filter parameter in this example? That’s an easy one to answer: we couldn’t use the Filter parameter because the Get-MailboxJunkEmailConfiguration cmdlet doesn’t support that parameter.

You know that’s a good point: everyone should have the junk email rule enabled, shouldn’t they? Not only that, but everyone should have included on their blocked senders and domains list. So what are you waiting for:

Get-Mailbox | Set-MailboxJunkEmailConfiguration -Enabled $True -BlockedSendersAndDomains @{Add=""}

Or maybe some of your users have listed on the blocked list and they really shouldn’t have on their blocked list. Can we figure out who those users are and remove from the blocked list? No, we can’t. But Windows PowerShell can:

Get-Mailbox | Get-MailboxJunkEmailConfiguration | Where-Object {$_.BlockedSendersAndDomains -match ""} | Set-MailboxJunkEmailConfiguration -BlockedSendersAndDomains @{Remove=""}

So wouldn’t it be easier to do all this work using the Exchange Admin center instead? Maybe. But, to tell you the truth, we couldn’t find a way to manage junk email by using the Admin center. As near as we can tell, you need to use Windows PowerShell to configure junk email handling. Or calendar setup. Or spell-check configuration. Or autosignature and mailbox operations. Or – well, again, you get the idea.

Next: Working with Exchange Online Reports

See Also

Using Windows PowerShell to Manage Exchange Online