A scan of the Internet results in many interesting EMS code
snippets that can be usefully employed by an Exchange administrator.
This section discusses some good examples. The idea is not to present
complete solutions. Rather, I hope to inspire you to experiment with
EMS to see just how much value you can get from a few lines of
reasonably straightforward code. After all, if you can do a lot of work
in a couple of lines that take just a few minutes to type in and get
running, think of how much you can do if you really set your mind to
exploiting EMS!
Many
of the Exchange MVPs provide an extremely valuable service to the
Exchange community by publishing what become de facto standards for how
to write a script to solve certain problems. You should download these
scripts and use them as a starting point for understanding just how to
approach writing industrial-strength EMS code. At the risk of offending others,
among my favorite sites are:
Pat Richard (http://www.ehloworld.com/). Features
a great script (Send-NewUserWelcome.ps1) that shows how to build a
welcome message to new Exchange users on a scheduled basis.
Andy Grogan (http://www.telnetport25.com). Look at his script for automating the setup of an Exchange lab environment.
Mike Crowley (http://mikecrowley.wordpress.com/). Contains a nice script to report on the proxy addresses assigned to email users.
Steve Goodman (http://www.stevieg.org/). Shows
an extremely useful Exchange environment report, a comprehensive
overview of lots of information about your Exchange organization;
output in HTML format.
Paul Cunningham (http://exchangeserverpro.com/). Offers
the best mailbox report script around (Get-MailboxReport.ps1). Paul
also maintains a nice server health monitoring script that generates
and sends an HTML format message to administrators on a regular basis.
These
scripts can be downloaded from these sites; the code is fully revealed
and is easily adapted to meet any particular needs that exist in your
environment. New sites that feature great tips appear all the time, and
I’m sure you will accumulate your own list of go-to people you consult
when you meet a problem. In the meantime, look at some examples to get
started with EMS.
1. Looking for large folders
The first example shows how to discover users who might be
suffering from performance problems because they have very large
folders in their mailboxes. The number of items that is considered bad
has grown over time in line with the updates Microsoft has made to tune
the database schema. With Exchange 2000 or Exchange 2003, the danger
mark is around 5,000 items. The threshold increases to 20,000 with
Exchange 2007 and leaps to 100,000 for Exchange 2010 onward. The client
used is also important because Outlook 2010 and Outlook 2013 are better
at dealing with large folders than Outlook 2007 is. Having more than
20,000 items in a folder is evidence of solid pack-rat behavior by
anyone, and it marks a folder that probably will never be cleaned out
simply because it takes too much effort to explore the contents and
decide what should be kept and what should be deleted. Assume that you
want to flag potential issues to users who have more than 5,000 items
in a folder. You can use code like this:
Get-Mailbox –Server ExServer2 | Get-MailboxFolderStatistics | Where {$_.ItemsInFolder –GT 5000} | Sort ItemsInFolder
–Descending | Format-Table Identity, ItemsInFolder
–AutoSize
Identity ItemsInFolder
--------- -----------------
contoso.com/Exchange Users/Redmond, Eoin\I 5271
contoso.com/Exchange Users/Ruth, Andy\Inbox 5265
contoso.com/Exchange Users/Andrews, Ben\Inbox 5263
contoso.com/Exchange Users/Pelton, David\Inbox 5230
contoso.com/Exchange Users/Simpson, David\Inbox 5218
contoso.com/Exchange Users/Redmond, Tony\Sent Items 5215
Of
course, it would be impolite to send a note to these users to remind
them that good filing practices lead to clean mailboxes, but you can
still think about it!
This code does the following:
Calls
Get-Mailbox to generate a list of all mailboxes located on databases
hosted by a server. It is possible to process all mailboxes in an
organization by changing the code to Get-Mailbox –ResultSize Unlimited,
but such a command will take a long time to process in any organization
with more than a couple of thousand mailboxes (though you could use a
server-side filter when appropriate).
Calls Get-MailboxFolderStatistics to extract a count of items in each folder.
Filters any folder with more than 5,000 items.
Sorts the filtered folders by descending order.
Outputs the information.
If
you run this command against an Exchange 2010 or Exchange 2013 server,
even details of the folders in the dumpster (for example, Deletions)
will be shown that are not reported by an Exchange 2007 server.
Many examples of outputting CSV files from Exchange
data use the Export-CSV cmdlet. For instance, here’s a two-line script
that looks for any mailbox that has an ActiveSync partnership created,
which indicates that the user has connected a mobile device to the
mailbox by using ActiveSync. An expression is included to force a call
to the Get-ActiveSyncDevice cmdlet to retrieve the count of devices
associated with each user. This kind of information is useful when
understanding how many people actually connect mobile devices to
Exchange!
$Mbx = Get-CASMailbox –Filter {HasActiveSyncDevicePartnership –eq $True} | Get-Mailbox
$Mbx | Select DisplayName, UserPrincipalName, @{Name="Devices";Expression={(Get-ActiveSyncDevice –Mailbox $_.Identity).Count)} | Export-CSV "c:\temp\ActiveSync.csv" –NoTypeInformation
Export-CSV
is great because it takes care of all the formatting issues required to
create a valid CSV file that will be recognized by applications such as
Excel. However, there are other ways to generate CSV data. This script
creates a CSV file you can use to analyze mailbox usage (Figure 1).
A check in the code limits processing to the mailboxes found in a
specific database and ignores anything but user mailboxes. (Objects
such as room or arbitration mailboxes are ignored.) This script could
take quite a while to finish if there are more than a few hundred
mailboxes in the selected database, so be sure to test it on perhaps a
smaller group before you launch it to process larger collections.
$Outputfile = "C:\temp\Mailboxes.csv"
Out-File -FilePath $OutputFile -InputObject "UserPrincipalName, Items, Mailbox Size" -Encoding UTF8
$mbx = Get-Mailbox –Database DB2
Foreach ($M in $Mbx)
{
if ($M.RecipientTypeDetails -eq "UserMailbox")
{
# Fetch information about the mailbox
$UserMailbox = Get-Mailboxstatistics -Identity $($M.Identity)
$UserPrincipalName = $M.UserPrincipalName
$ItemSizeString = $UserMailbox.TotalItemSize.ToString()
$MailboxSize = "{0:N2}" -f ($ItemSizeString.SubString(($ItemSizeString.
IndexOf("(") + 1),($itemSizeString.IndexOf(" bytes") - ($ItemSizeString.IndexOf("(") + 1))).Replace(",","")/1024/1024)
$ItemCount = $UserMailbox.ItemCount
#Prepare the user details in CSV format for writing to file and append line
$UserDetails = $UserPrincipalName + "," + $ItemCount + "," + $MailboxSize
Out-File -FilePath $OutputFile -InputObject $UserDetails -Encoding UTF8 -append
}
}
This
script generates fairly basic data about mailboxes, and if you scan the
Internet, you can find many other approaches to the problem of mailbox
reporting, some of which are much better than others. With anything to
do with mailboxes, the key is speed because code that is quite good at
processing one or two mailboxes might not be smart when confronted with
a few thousand. It’s also a good idea to consider what information
needs to be output and make sure that the data reported is formatted in
a way that is most useful to the reader.