Share via


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

Comments

  • Anonymous
    January 01, 2003
    Hi Todd,Things have been somewhat hectic in my life as of late, so I haven't had time to look at the script. But thanks for providing me with the above feedback and fixes!! I will definitely update the script with the fixes. Will be working on it in my spare time, but will update this page once its done.Thanks,Michael

  • Anonymous
    January 01, 2003
    Hi Zoltan, It's your lucky day, I added archive support into the new version 1.2.7. If you specify the -archiveCheck switch it will search archive mailboxes only. This was only tested in my lab environment, so I hope it works in your environment. Michael

  • Anonymous
    January 01, 2003
    Lance, would you mind communicating with me on the TechnicalRamblings mail addy. I'm not able to repro this, but I might have an idea why its happening, it just need someone to test the change I made :-)
    Michael

  • Anonymous
    January 01, 2003
    Hi Won Keat, You are correct, I'm busy investigating how MRS determines the size of an item to make sure we don't get into a situation where we dont report on actuals that MRS would deem as large items. In the meantime if you are comfortable taking the chance I'd suggest changing the value to 1048576.

    Hi Maxime, Did you receive any exceptions that you can send me?

  • Anonymous
    January 01, 2003
    Hey Tony,
    You could potentially use the output from the script as contentfilter properties in new-mailboxexportrequest cmdlet. I haven't tried it myself yet, might be a good candidate for a follow up article.
    Michael

  • Anonymous
    January 01, 2003
    Good news !! The size large item limit has been increased to 150MB. http://blogs.office.com/2015/01/12/whats-new-december-2014/

  • Anonymous
    January 01, 2003
    Try forcing the EWS Endpoint by using the URI parameter. This way it wont utilize autodiscover to find the smtp address.

  • Anonymous
    January 01, 2003
    Please find the latest version here https://gallery.technet.microsoft.com/PowerShell-Script-Office-54d367ea
    I've given this to someone else to manage going forward since I don't have time to support the script going forward

  • Anonymous
    January 01, 2003
    Hey Steve, I've had some other complaints around 401 Unauthorized. Unfortunately, I cannot repro it on my side. I have however updated the script to use a new credential mechanism for the EWS cred instantiation. Give it a shot and let me know. Michael

  • Anonymous
    December 06, 2013
    Hi Michael, thanks for putting this together, will be much help once I get it going. When I run it I get "Exchange Server Management Tools not installed on this host". I have the management tools installed on the host I'm running the script from, I see the script does a check "$checkEMT12Installed = test-path -Path 'hklm:SOFTWAREMicrosoftExchangeServerv12AdminTools' " which is False, as that path does not exist in that registry location. Is there another location where I can check to confirm AdminTools are installed? I searched my registry and don't find this Key anywhere, but I have confirmed Exchange Admin Tools are installed. Thoughs? Exchange 2007 sp3 / Host is Windows 7. Thanks Kyle

  • Anonymous
    December 06, 2013
    I was able to over come this by running the script on the hybrid exchange server. But interested in getting it running on my host machine. Regardless, this script is a huge help! Thanks again, Mike! Kyle

  • Anonymous
    December 10, 2013
    Hello Michael.  Thanks a million for this script.  If I can get it to work, I would like to send you a donation. I am also getting the "Exchange Server Management Tools not installed on this host". I have the management tools installed on the host I'm running the script from, I see the script does a check "$checkEMT12Installed = test-path -Path 'hklm:SOFTWAREMicrosoftExchangeServerv12AdminTools' " which is False, as that path does not exist in that registry location. Is there another location where I can check to confirm AdminTools are installed? My Exchange is 2007 running on Server 2003 x64.  I get this error if I try to run the scripts on the host or on an XP workstation with the Management tools installed. Thanks, -Todd

  • Anonymous
    December 12, 2013
    The comment has been removed

  • Anonymous
    January 23, 2014
    Michael,I have a question how does this differ from exFolders. We have been migrating mailboxes into Office 365 and when I run the script it doesn't return the same information that exFolders does. I am able to find the folder location that has a large item using exFolders but the script does not find anything. Any information would be appreciated. thanks,

  • Anonymous
    January 30, 2014
    The comment has been removed

  • Anonymous
    February 13, 2014
    Does the script also search the archive mailbox, or the primary mailbox only?

  • Anonymous
    February 13, 2014
    To complement my previous post, I have a customer who has some 1000 archive mailboxes that he wants to move to O365 while keeping the primary mailbox on premise. Some moves fail due to large items. How do I find them without having to walk to the user and use their Outlook? Thanks.

  • Anonymous
    February 16, 2014
    Awesome news! Thanks Michael :-)

  • Anonymous
    February 24, 2014
    Michael, I ran the script and overall it did an excellent job. It however failed twice with errors similar to the following, on the Drafts and Calendar folders in the archive mailbox:

    ======================================================================
    2014-02-25_02-44-22_PM : EWS found item it cannot process
    WARNING:
    2014-02-25_02-44-22_PM : Processing of the folder Drafts is incomplete
    Get-Item :
    2014-02-25_02-44-22_PM : Inner Exception: Exception calling "FindItems" with "2" argument(s): "An internal server error occurred. The operation failed."
    At C:_ZELargeItemChecks_1_2_7.ps1:415 char:29
    + $largeItems = Get-Item <<<< -ItemSizeLimit $itemSizeLimit -Folders $folders -Service $service -Verbose;
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-Item
    ======================================================================

    The errors have been handled gracefully, they got logged in the output CSV file too, and they did not prevent the script from carrying on. That's a very good thing.

    Is it something you can address in the script or it's a missing/buggy feature of EWS?

    Thanks,
    Zoltan

  • Anonymous
    March 10, 2014
    I'm trying to run this in a Exchange 2013 CU3 Environment. I'm getting a error on all mailboxes;
    Exception calling "FindFolders" with "2" argument(s): "The SMTP address han no mailbox associated with it."[0]

    However if I enter the same SMTP address in OWA it resolves to a user.

    What should I look for to troubleshoot/solve this ?

    Regards,

    Rikard Strand

  • Anonymous
    March 12, 2014
    Hi Michael

    I have a question regarding the code
    [System.Int32] $size = $item.Size / 776192; #Investigate this number

    I remember $Item.Size return the value in bytes, hence shouldn't the formula is $item.Size / 1048576 in order to convert the bytes to MB?

    Besides that, if I wish to export the message class for those mail items, ex. IPM.Note, IPM.Appointment etc, what properties I should add in? Is it $Item.ItemClass ?

    Thanks for your guidance.


    Regards,
    Won Keat, Liew

  • Anonymous
    April 14, 2014
    Hi Michael,
    Thanks a lot for your script
    It run well on exchange 2010 servers, but for big mailbox, it only seems to parse the first 1000 folders of this mailbox, any idea?
    Best regards.

  • Anonymous
    April 16, 2014
    Hi Michael,
    thanks for your quick reply, unfortunatly i didn't get any exception but i found a work arround making a loop splitting each 1000 folder result :-)
    Best regards

  • Anonymous
    April 22, 2014
    Hi Michael,

    I'm running into an issue when I try to run the script. I'm getting "Exception calling "FindFolders" with "2" arguments: the SMTP address has no mailbox associated ..."

    I have set the URI entry, but that didn't help. Exchange 2007 with 2013 SP1 Hyrbid server.

    Any ideas?

  • Anonymous
    April 24, 2014
    Michael is there an easy way to incorporate this to give us a report and allow us to export the emails to PST.

  • Anonymous
    May 28, 2014
    The comment has been removed

  • Anonymous
    June 17, 2014
    This is Good , But I have got Trouble at output file. I am getting some symbols. I have added -encoding ASCII,, Now out put is proper

  • Anonymous
    June 17, 2014
    The comment has been removed

  • Anonymous
    July 22, 2014
    I had this error when I ran it on two servers 2007 and 2010 any idea why

    2014-07-22_01-52-24_PM : Enumerating folders

    2014-07-22_01-52-24_PM : Exception calling "FindFolders" with "2" argument(s): "The request failed. The remote server re
    turned an error: (401) Unauthorized."[0]

    2014-07-22_01-52-24_PM : Check service account credentials
    thanks

  • Anonymous
    August 05, 2014
    The tool doesn't seem to be able to view "Private" items. I've had several mailboxes show up as having no items over the large limit, but when I went to move them, the move failed with too many large items. The returned list of items detected as large could not be seen by me when I mounted the mailbox as a full-access user. Any setting change needed to enable the script to "see" large private items?

  • Anonymous
    August 05, 2014
    Now that I look at a completion report again, it might not be a "Private" items issue after all, though I think that might still be there. However, there is a problem with moving items in the "Recoverable Items/Deletions" folder. Can the tool also detect these? For some reason this folder gets moved with the mailbox.

  • Anonymous
    August 07, 2014
    Great script. It worked on my company cas server. But I tried to run it on a customer servers and I get "Transcription cannot be started" "Use the Start Transcript command"

  • Anonymous
    September 01, 2014
    If you haven’t seen my mailbox migration tool yet, go and have a look at it here . It’s been

  • Anonymous
    September 03, 2014
    I am randomly getting these errors in the middle of processing a folder
    I still get data but wonder if I am missing some

    Get-Item :
    2014-09-03_03-46-03_PM : Inner Exception: Exception calling "FindItems" with "2
    argument(s): "The request failed. The remote server returned an error: (401)
    unauthorized."
    t C:Documents and SettingsxxxxxxxDesktopLargeItemChecksLargeIte
    mChecks_1_4.ps1:452 char:29
    $largeItems = Get-Item <<<< -ItemSizeLimit $itemSizeLimit -Folde
    rs $folders -Service $service -Verbose;
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorExcep
    tion
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio
    n,Get-Item

  • Anonymous
    October 22, 2014
    Great Script, would it be possible to search for public folders as well?

  • Anonymous
    October 24, 2014
    The comment has been removed

  • Anonymous
    November 11, 2014
    Hope this helps someone, but I was having all kinds of issues until I installed powershell 3.0, things just didnt seem to work right under 2.0

  • Anonymous
    January 06, 2015
    Dears,
    from where can I download the script LargeItemChecks.ps1 , please help..

  • Anonymous
    March 10, 2015
    Running the script with the following options, and receiving the error below. I have specified the folder on the server I am running the script. I have also shared and given the service account full access to the folders. Can anyone help with this?

    .LargeItemChecks_2_2_0.ps1 -ServiceAccountDomain grsd.local -ServiceAccountName mailscript -ServicePassword Spassword1 -ItemSizeLimit 25 -ImportCSV .user.csv -MoveLargeItems -ExportLargeItems -LargeItemNotice

    Couldn't find the Enterprise Organization container.
    + CategoryInfo : NotSpecified: (0:Int32) [Get-MailboxExportRequest], OrgContainerNotFoundException
    + FullyQualifiedErrorId : 52B56334,Microsoft.Exchange.Management.RecipientTasks.GetMailboxExportRequest

    Couldn't find the Enterprise Organization container.
    + CategoryInfo : NotSpecified: (0:Int32) [New-MailboxExportRequest], OrgContainerNotFoundException
    + FullyQualifiedErrorId : 31182839,Microsoft.Exchange.Management.RecipientTasks.NewMailboxExportRequest