Exchange Get-MailboxStatistics observations

As an exchange Administrator, you should be expert in dealing with PowerShell cmdlets. There are couple of Get cmdlets that are so famous and fundamental when querying mailboxes in any exchange environment. Those commands are Get-Mailbox  and Get-MailboxStatistics.

Both commands will return mailboxes, but each one will behave differently, and most of the time, will return different results. Even the result output for the same mailbox returned will be different. I do not want to confuse you, instead I want to walk you through my observations when dealing with those two cmdlets.

Observation 1

I will start by creating an empty database called Test. I will run both Get-Mailbox and Get-MailboxStatistics.

Running Get-Mailbox , returns nothing, while running Get-MailboxStatistics  returns the System Mailbox

 

Get-MailboxStatistics

Observation 2

I will create user called SoloUser and a mailbox for him in the Test mailbox database. Running Get-Mailbox  will return the SoloUser mailbox, while running Get-MailboxStatistics  will not return the SoloUser mailbox.

The reason behind not returning SoloUser mailbox as a result when running Get-MailboxStatistics is simply because Get-MailboxStatistics  requires the user to log on to his mailbox for the first time, in order for Get-MailboxStatistics  to return his mailbox as a result.

Rule: Get-MailboxStatistics  retrieves mailboxes ONLY after the first logon

Get-MailboxStatistics

After the successful logon for SoloUser, running the Get-MailboxStatistics will return the system mailbox and the user mailbox.

Get-MailboxStatistics

Observation 3

Let us enable an archive mailbox for the user and run both commands.

Get-Mailbox  will only return the SoloUser, while Get-MailboxStatistics  will return the mailbox, the archive mailbox , and the system mailbox. As you can see Get-MailboxStatistics  tend to be more realistic by looking at all and every mailbox in the database. Since the archive mailbox is just another mailbox, it is returned by the Get-MailboxStatistics  as a mailbox. Get-Mailbox on the other hand, tend to deal with the logical representation of mailboxes as it will treat the archive mailbox as not worthy to be returned as a result, because it is linked to the user mailbox.

Get-MailboxStatistics

Get-MailboxStatistics

 

Observation 4

I will create another user called FiredUser. I will give him a mailbox and an archive mailbox. I will then disabled his archive mailbox.

Running the following cmdlet will return an error.

Get-MailboxStatistics "FiredUser" -Archive

Running the following cmdlet will show the archive mailbox for the FiredUser, with full properties and no indication that it is disabled mailbox.

Get-MailboxStatistics -database "Test"

Get-MailboxStatistics

The strange thing is that FiredUser has his archive deleted (disabled), and yet his archive is showing when running Get-MailboxStatistics  for the Test database. When viewing the full properties of that personal archive, nothing indicates it was deleted

Get-MailboxStatistics

Rule: Get-MailboxStatistics  will always return everything if the lastlogonstamp exist, even if the item is marked for deletion.

Observation 5

I will move the SoloUser mailbox and his archive to another database.

Get-Mailbox  will not return anything, while Get-MailboxStatistics  will return everything.

Get-MailboxStatistics

Observations results

Get-Mailbox  will only return the active live user mailboxes (not archive mailboxes). If the user is moved to another database or deleted, this command will not show deleted mailboxes or the soft deleted mailboxes in case of a local move request

Get-MailboxStatistics  will return the system mailbox + user mailbox + archive mailbox + deleted mailboxes (mark for deletion) + softly deleted mailboxes (in case of local move request)

Get-MailboxStatistics

I consider Get-Mailbox  as a cmdlet that will give you the logical view of a databases, while Get-MailboxStatistics will show you the actual items in the database. That is why in order to get the mailbox size, you have to go with Get-MailboxStatistics  as it reflects the physical structure of a database.

Query archive mailboxes

Let us assume we have one mailbox database called mydatabase, and five users [UserA – UserE]. Each users has a primary mailbox, so UserA has a mailbox called M1, while UserE has a mailbox called M5. Let us also assume that UserA and UserB have archive mailboxes [A1 and A2].

Now, let us run couple of cmdlets and see how each command will work with archive mailboxes.

 

Get-MailboxStatistics

Running Get-mailbox -database mydatabase  will return five objects [M1, M2, M3, M4, M5], while running Get-mailbox-database mydatabase -archive  will return two objects [M1,M2] and not [A1,A2].

What is so strange is that Get-Mailbox will always return primary mailboxes and not archive mailboxes. To validate this point, the following two cmdlets will return the same result

Get-Mailbox SoloUser
Get-Mailbox SoloUser -Archive

 

Get-MailboxStatistics

Get-MailboxStatistics  works differently as running the following cmdlets will return different results:

This command will return M1, which is the primary mailbox for UserA.

Get-MailboxStatistics UserA

This command will return A1, which is the archive mailbox for UserA

Get-MailboxStatistics UserA -Archive

Another important thing to notice is that Get-MailboxStatistics -Archive  cannot be used to retrieve more than one archive mailbox at a time. For example, you cannot say Get-MailboxStatistics -Archive  without any additional parameters, or Get-MailboxStatistics -database  “Test” -Archive . The only time you can use  the -Archive switch with the Get-MailboxStatistics  command is when you specifically type the identity of the mailbox in question.

How to get users with archive mailboxes?

Get-Mailbox -Archive   or Get-Mailbox | where {$_.archivedatabase -ne $null}

[Returns the mailboxes of users who have archives. This command will not return the archive mailboxes themselves, but the main primary mailboxes for users who have archives]

Get-Mailbox -Archive -Database "Test"

[Returns the mailboxes of users in Test DB who have archives. This command will not return the archive mailboxes themselves, but the main primary mailboxes for users who have archives]

Get-Mailbox -Archive -Server MBX1

[Returns the mailboxes of users in MBX1 who have archives. This command will not return the archive mailboxes themselves, but the main primary mailboxes for users who have archives]

Get-Recipient -RecipientType 'UserMailbox' -Filter  '((ArchiveState -eq ''1''))'

[Returns (Get-Recipient) object for mailboxes having archives]

 

Note:  To get mailboxes that are not attached to Archives, simply run your Get-Mailbox  with any filters like -Database or -Server, and then pipeline it with Where {$_.archivedatabase -eq $null}

Note: The beauty thing about Get-Mailbox  command is that it does not return disconnected, deleted or soft deleted mailboxes.

Note: Since Get-MailboxStatistics -Archive  returns one item at a time as discussed before, then you cannot use Get-MailboxStatistics -Archive to query archives.

Note: Why running

Get-MailboxStatistics |Where {$_.IsArchiveMailbox -eq $true}

is not a good thing ? Because this command will return deleted archives, soft deleted archives (in case of local move request), and so it does not distinguish between active archives or not.

Returning all archive mailbox objects?

Two Step job :

  1. Query those primary mailboxes who have active archives using Get-Mailbox   [Since Get-Mailbox -Archive  can query multiple mailboxes, but only returns the primary mailbox not its archive]
  2. Pipeline that to Get-MailboxStatistics -Archive  [Since this command takes one item at a time and returns the actual archive mailbox]

So you can type something like Get-Mailbox -Archive | Get-MailboxStatistics -Archive . This command will return all mailbox archive objects in the enterprise.

Rule : Use Get-Mailbox  to query and scope your result, append the archive filter to get only mailboxes with archives (either by -Archive parameter or pipeline the result with Where {$_.archivedatabase -nq $null} , and then use Get-MailboxStatistics -Archive  to get the archive mailbox objects themselves.

Get-MailboxStatistics

Get-MailboxStatistics