Exchange Server Large MailItem Script

UPDATE :  

1. Please take note we have increased the size limit to 150MB during on boarding the previous 25MB should no longer be an issue - see the announcement here: https://blogs.office.com/2015/01/12/whats-new-december-2014/

2 . I've handed this script over to someone else for maintenance and support. Please use the following link to get the latest version: https://gallery.technet.microsoft.com/PowerShell-Script-Office-54d367e

There has been a lot of requests from my customers for an easy way to find large mail items in mailboxes that are planned to be moved to Exchange Online.

As you are probably aware, items larger than 25MB are not moved to Exchange Online and this causes the move request to fail if LargeItemLimit is not specified and/or the items larger than 25MB isn’t removed from the mailbox (backed up to a PST).

You can read more about it here: https://support.microsoft.com/kb/2584294

It’s obviously not very feasible to start your move requests without knowing that you are going to hit these kind of problems, because you want those moves to be as smooth as possible. I’ll show you some tricks that I use to avoid starting the move request from scratch when this occurs, but that will be another article.

Initially, I wanted to start from scratch and write a PowerShell script based on Exchange Web Services, but luckily one of my colleagues (Dmitry Kazantsev) already had a great bunch of scripts based on EWS that he created. I have however made some extensive changes by consolidating all the scripts to functions in one single script and adding some additional horsepower to the script. It’s been working great for me.

The script uses Exchange Web Services to impersonate a user account and essentially gaining access to the mailbox to scan the items in each folder for the large item limit you specify. All the results are then dumped to a CSV file.

So how does this work?

First, download and install the Exchange Web Services 2.0 API here

Make sure you have Exchange Management Tools installed on the machine you will be running the script. If you are running the script on an Exchange Server you need to install the API on the server.

Now we need an account with impersonation rights to be able to read the mailboxes.

  • Create a service account in Active Directory - for this example I’ll use svc_ews@contoso.com

Now we need to assign impersonation permissions for this account.

For Exchange Server 2007 mailboxes:

  • Open Exchange 2007 Management Shell.
  • Assign impersonation permissions on the Exchange 2007 Client Access Servers (replace svc_ews@contoso.com with your service account created earlier):
 Get-ExchangeServer|where {$_.Admindisplayversion.Major -lt 14 -and $_.IsClientAccessserver}| ForEach-Object {Add-ADPermission -Identity $_.distinguishedname -User svc_ews@contoso.com -extendedRight ms-Exch-EPI-Impersonation}
  • Assign impersonation permissions on the Exchange Server 2007 databases.
 Get-MailboxDatabase | ForEach-Object {Add-ADPermission -Identity $_.DistinguishedName -User svc_ews@contoso.com -ExtendedRights ms-Exch-EPI-May-Impersonate}

For Exchange Server 2010/2013 mailboxes:

  • Permissions for Exchange Server 2010/2013 mailboxes (replace svc_ews@contoso.com with your service account created earlier):
 New-ManagementRoleAssignment –Name:impersonationAssignmentName –Role:ApplicationImpersonation –User:svc_ews@contoso.com

Let’s cover the parameters that the script uses:

Mandatory parameters:

  • adminAccountName – Organization Management Administrator account
  • adminPassword - Administrator Password
  • serviceAccountDomain - EWS Service Account domain
  • serviceAccountName – EWS Service Account
  • servicePassword - Service Account Password
  • resultsFile – Results Export Filename
  • ItemSizeLimit - Item Size Limit

Parameters that are not mandatory:

  • ImportCSV  - List of mailboxes to import .
  • URI -  URI of EWS Endpoint.
  • archiveCheck - switch to only search archive folders.

If you want to target a subset of users you can use the ImportCSV parameter to specify a CSV file to read. The file needs a header called PrimarySMTPAddress and then the primary SMTP addresses of the mailboxes you want to target.

If you don’t specify the ImportCSV parameter the script will scan all mailboxes in the organization.

The URI parameter can also be specified if you want to use a specific EWS endpoint like https://webmail.contoso.com/ews/exchange.asmx.

If you do not specify the URI parameter the script will use Autodiscover for the correct Web Services URI for each mailbox.

And that’s it. Now you’re ready to rumble.

Copy the script to a folder of your choice and open Exchange Server 2010/2013 Management Shell.

To following is examples of the usage:

 .\LargeItemChecks.ps1 -serviceAccountName svc_ews -serviceAccountDomain contoso.com -servicePassword P@5sword2 -resultsFile .\exportResultSet.csv -ItemSizeLimit 25
 .\LargeItemChecks.ps1 -archiveCheck -serviceAccountName svc_ews -serviceAccountDomain contoso.com -servicePassword P@5sword2 -resultsFile .\exportResultSet.csv -ItemSizeLimit 25

It will run for a while depending on the size of your organization. The transcript log will also be created in the current directory.

The results file will look like this:

Until next time,

Michael Hall