Tip

Locating unused Exchange Server mailboxes with PowerShell code

Exchange Server is licensed by the number of mailboxes within an organization. Not only do unused Exchange mailboxes consume licenses that could be better allocated elsewhere, but unused or dormant Active Directory accounts also weaken an Exchange organization's security. There is no native option within Exchange that retrieves a list of unused mailboxes, but PowerShell is up to the task.

Retrieving Exchange mailbox size via PowerShell

To begin searching for unused Exchange mailboxes, use

    Requires Free Membership to View

PowerShell to examine mailbox size. There are a number of different ways to accomplish this, but I prefer the following command:

 Get-Mailbox | Get-MailboxStatistics | where {$_.ObjectClass –eq “Mailbox”} | Sort-Object ItemCount –Descending | ft DisplayName, TotalItemSize, ItemCount

This command creates a report that lists the Exchange mailbox's display name, total mailbox size (in KB) and number of items in the mailbox. This report sorts the list by the item count in descending order. I did this because the total mailbox list often does not fit on the screen. Mailboxes with the fewest items are displayed at the end of the list.

Unfortunately, empty mailboxes don't always end up at the bottom. If a user has never used his mailbox, the unused Exchange mailbox is not listed. But that's not to say that the mailbox will not appear in the report. The command's output explains if a mailbox has never been used before. You can see this message and the command's full output in Figure 1.

Figure 1. The PowerShell code's output displays if an Exchange mailbox has never been used.

In my example, the full output fits on the screen because I only have a few mailboxes. In most organizations, the output is too long to completely fit on the screen.

If this happens to you, dump the output to a text file using PowerShell's Out-File cmdlet. Append a pipe to the command above, then enter Out-File, followed by the path and filename of your choosing. The full command looks like this:

 Get-Mailbox | Get-MailboxStatistics | where {$_.ObjectClass –eq “Mailbox”} | Sort-Object ItemCount –Descending | ft DisplayName, TotalItemSize, ItemCount | Out-File C:\report.txt

You may receive warnings about unused mailboxes. These warnings will be easier to read because the full report is not listed; only the warning is listed.

Open the report in Notepad or enter the Type command, followed by the filename. In Figure 2, you can see the full command, the on-screen warning and the contents of the report file.

Figure 2. The Exchange mailbox report gets written to a text file.

Determine last login time to view inactive Exchange mailboxes

The method I just described displays Exchange mailboxes that are empty or have never been used. But what if you want to find mailboxes that contain data, but are no longer active? The key here is determining when the mailbox's owner last logged in.

Note: This technique works for user mailboxes, but not Exchange resource mailboxes.

Unfortunately, there isn't a single PowerShell cmdlet that retrieves each user's most recent login information; you must assemble a PowerShell script. Here is a simple block of code from Automon.com that determines the most recent login for each user:

 $SearchAD = New-Object DirectoryServices.DirectorySearcher([adsi]"") $SearchAD.filter = "(objectclass=user)" $users = $SearchAD.findall() Foreach($user in $users) { if($user.properties.item("lastLogon") -ne 0) { $a = [datetime]::FromFileTime([int64]::Parse($user.properties.item("lastLogon"))) "$($user.properties.item(`"name`")) $a" } }

View this script's output in Figure 3.

Figure 3. The code's output displays last login time for each Exchange mailbox.

The block of code isn't perfect, but it effectively reports both user accounts and computer accounts. More importantly, user logon times are not replicated between domain controllers.

If you have multiple domain controllers, you need a more elaborate script capable of parsing each domain controller in the domain.

ABOUT THE AUTHOR:

Brien Posey is an eight-time Microsoft MVP with two decades of IT experience. Before becoming a freelance technical writer, Brien worked as a chief information officer at a national chain of hospitals and health care facilities. He has also served as a network administrator for some of the nation's largest insurance companies and for the Department of Defense at Fort Knox.

This was first published in August 2012

There are Comments. Add yours.

 
TIP: Want to include a code block in your comment? Use <pre> or <code> tags around the desired text. Ex: <code>insert code</code>

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
Sort by: OldestNewest

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

Disclaimer: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.