Removing Messages by Message Class (Updated)

powershellLast version: 1.4, July 8th, 2014.

Recently, I was asked if it is possible to remove stub items. The reason was they were going to transition to a newer version of Exchange and they wouldn’t be using the archiving solution in the new environment. When required, vendor tooling would be used to search through the existing archives.

In such cases it makes sense to remove the stubs from the mailbox, which are shortcut messages that points to a copy of the original message in the archive solution. The new environment won’t contain the required Outlook plugins or extensions to retrieve the original message from the archive using the stub, making the stub lead to a partial or empty message.

To identify stubs, one can filter on an attribute of each item, MessageClass. This attribute defines which kind of item it is (in fact, determines what form Outlook should use in order to present or process the information). Examples of MessageClass definitions are IPM.Note (regular e-mail messages), IPM.Note.EnterpriseVault.Shortcut (message archived by Enterprise Vault) or IPM.ixos-archive (message archived by Opentext/IXOS LiveLink E-Mail Archive).

To identify stubs from Outlook, add the Message Class field to your Outlook view, e.g.:

StubsOutlook

When you want to remove the stubs using Outlook, you can utilize the Advanced Find function of Outlook, but that is a very labor intensive, tedious and non-centralized per-mailbox procedure:

SearchFromOutlook

Now I wouldn’t have started this article if the same thing wasn’t possible with a little bit of scripting against Exchange Web Services and so the script Remove-MessagesClassItems.ps1 was born. Using this script requires Exchange 2007 or later and Exchange Web Services Managed API 1.2 (or later) which you can download here or you can copy the Microsoft.Exchange.WebServices.DLL locally and adjust the DLL path mentioned in the script when necessary. The script has been developed and tested against Exchange 2007, meaning it’s a PowerShell 1.0 script which should be compatible with later versions of PowerShell or Exchange.

Also take notice that since you’ll be processing user mailboxes, you’ll need to have full mailbox access or impersonation permissions; the latter is preferred. For details on how to configure impersonation for Exchange 2010 using RBAC, see this article or check here for details on how to configure impersonation for Exchange 2007.

The script Remove-MessagesClassItems.ps1 uses the following syntax:

Remove-MessageClassItems.ps1 [-Mailbox] <String> [-MessageClass] <String> [-Server <String>] [-Impersonation] [-Credentials <PSCredential>] [-PartialMatching] [-DeleteMode <String>] [-ScanAllFolders] [-Before <DateTime>] [-MailboxOnly] [-ArchiveOnly] 
 [-WhatIf] [-Confirm] [<CommonParameters>]  

A quick walk-through on the parameters and switches:

  • Mailbox is the name or e-mail address of the mailbox.
  • MessageClass specifies the Message Class to remove, for example IPM.Note.EnterpriseVault.Shortcut (EnterpriseVault).
  • Switch PartialMatch specifies if you want to use exact matching of MessageClass or partial matching. When enabled, specifying ‘EnterpriseVault’ will select all items containing ‘EnterpriseVault’ substring in message class.
  • Server is the name of the Client Access Server to access for Exchange Web Services. When omitted, the script will attempt to use Autodiscover.
  • Switch Impersonation specifies if impersonation will be used for mailbox access, otherwise the current user context will be used.
  • DeleteMode specifies how to remove messages. Possible values are HardDelete (permanently deleted), SoftDelete (use dumpster, default) or MoveToDeletedItems (move to Deleted Items folder). Note that the Deleted Items folder will be processed, unless MoveToDeletedItems is used.
  • Credentials specifies the user credentials to use.
  • Parameter Before can be used to only remove items received before specified date.
  • MailboxOnly specifies you only want to process the primary mailbox of specified users. You als need to use this parameter  when running against mailboxes on Exchange Server 2007.
  • ArchiveOnly specifies you only want to process personal archives of specified users.

So for example, suppose you want to remove  IPM.Note.EnterpriseVault.Shortcut items from the mailbox of user1 and personal archive when enabled, moving the items to the DeletedItems by Impersonation. In such case, you could use the following cmdlet:

Remove-MessageClassItems.ps1 -Mailbox user1 -MessageClass IPM.Note.EnterpriseVault.Shortcut -DeleteMode MoveToDeletedItems -Impersonation –Verbose 

SampleOutput

Note: By default, Remove-MessageClassItems.ps1 will only process IPF.Note class folders (i.e. containing mail items), so you’ll only see those being processed. If you want all folders scanned (also class-less), use the ScanAllFolders switch.

The script also supports Office 365. For example, to remove all items with ‘Enterprise’ in their message class text, received before 1/1/2014, and only from the primary mailbox, you can use:

$Credentials= Get-Credential
Remove-MessageClassItems.ps1 -Mailbox olrik@office365tenant.com -DeleteMode MoveToDeletedItems -MessageClass EnterpriseVault -PartialMatching -Before 1/1/2014 -MailboxOnly -Credentials $Credentials

In case you want to process multiple mailboxes, you can use a CSV file which needs to contain the Mailbox field. An example of how the CSV could look:

Mailbox
francis
philip

The cmdlet could then be something like:

Import-CSV users.csv1 | Remove-MessageClassItems.ps1 -MessageClass IPM.Note.EnterpriseVault.Shortcut -DeleteMode HardDelete -Impersonation

You’re feedback is welcomed through the comments; if you got scripting suggestions, please use the contact form.

You can download the script from the Technet Gallery here.

Revision History
See TechNet Gallery page.

69 thoughts on “Removing Messages by Message Class (Updated)

  1. Pingback: Removing Messages by Message Class (Updated) | EighTwOne (821) | JC's Blog-O-Gibberish

  2. Michel, I would appreciate to learn more about the migration from EV to Exchange archiving. We are planning on moving from an Exchange 2007/EV 9.0.2 implementation to Exchange 2013 and the road block is the 34TB of data in EV and how best to get it back to exchange. On the plus side, we are not stubbing our emails.

    • Transvault :)
      Nb : when you say 34TB is y compressed and duplicated DATA (singleinstanceless) ? Or just the DATA in disk ?
      Regards,
      Ben

    • Depends on scenario and setup. This customer cut off their archived data (ie isolated, available when required using vendor tools) and will move not (yet) archived mailbox data to the new e-mail environment, facilitating large mailboxes. Otherwise, they’d have to inject the original mail items using the stubs from the archive, but as that data is rarely consulted but has a significant storage footprint, they chose to cut it off.

  3. Fantastic script! This is extremely useful in removing third-party voice mail messages from the Exchange environment. Not being very adept at EWS scripitng(but learning); I’d like to know how would the script be modified to find messages of a specific class older than, let’s say, 45-days?
    (define in base property set and then filter?)

    • The line with “[Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, $MessageClass)” defines the item filter. It’s a single condition; if you want to combine multiple conditions, you need to utilize a SearchFilterCollection where you add all the individual conditions. Then, pass that collection instead of the single condition to FindItems, e.g.

      ..
      $ItemSearchFilter1= New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo( [Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, $MessageClass)
      $ItemSearchFilter2= New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThanOrEqualTo( [Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, (Get-Date).AddDays(-45))
      $SearchFilterCollection= New Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And);
      $SearchFilterCollection.add( $ItemSearchFilter1)
      $SearchFilterCollection.add( $ItemSearchFilter2)

      Do {
      $ItemSearchResults= $SubFolder.FindItems( $ItemSearchFilterCollection, $ItemView)
      ..

      Let me know if there’s more animo for this; I could make item age a parameter of course :)

      • Thank you for the prompt reply. When I replace the code to create the SearchFilterCollection..I get an error regarding “New”…seems to run, then remove all messages, not just message class specified. (Of course, working in a test environment)
        [PS] E:\hold\msgclass>.\Remove-MessageClassItems45days.ps1 -Mailbox mbxrestore -MessageClass IPM.Note.Adomo.VM -DeleteMode MoveToDeletedItems -Impersonation -Verbose
        Processing mailbox mbxrestore
        VERBOSE: Loading Microsoft.Exchange.WebServices.dll
        VERBOSE: Set to trust all certificates
        VERBOSE: Using MBX.Restore@xxxxxx.xxxfor impersonation
        VERBOSE: Looking up EWS URL using Autodiscover for MBX.Restore@xxxxxx.xxx
        VERBOSE: Using EWS on CAS https://owa.xxxxxx.xxx/EWS/Exchange.asmx
        VERBOSE: DeleteMode is MoveToDeletedItems
        VERBOSE: Removing messages of class IPM.Note.Adomo.VM
        VERBOSE: Processing folder Drafts
        The term ‘New’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spellin
        g of the name, or if a path was included, verify that the path is correct and try again.
        At E:\hold\msgclass\Remove-MessageClassItems45days.ps1:166 char:38
        + $SearchFilterCollection= New <<<< Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollec
        tion([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And);
        + CategoryInfo : ObjectNotFound: (New:String) [], CommandNotFoundException
        + FullyQualifiedErrorId : CommandNotFoundException

        You cannot call a method on a null-valued expression.
        At E:\hold\msgclass\Remove-MessageClassItems45days.ps1:167 char:35
        + $SearchFilterCollection.add <<<< ( $ItemSearchFilter1)
        + CategoryInfo : InvalidOperation: (add:String) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull

        • Change:

          $ItemSearchFilter= New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo( [Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, $MessageClass)

          Do {
          $ItemSearchResults= $SubFolder.FindItems( $ItemSearchFilter, $ItemView)

          to:

          $ItemSearchFilter1= New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo( [Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, $MessageClass)
          $ItemSearchFilter2= New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThanOrEqualTo( [Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, (Get-Date).AddDays(-45))
          $ItemSearchFilterCollection= New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And);
          $ItemSearchFilterCollection.add( $ItemSearchFilter1)
          $ItemSearchFilterCollection.add( $ItemSearchFilter2)

          Do {
          $ItemSearchResults= $SubFolder.FindItems( $ItemSearchFilterCollection, $ItemView)

          • Fantastic! Works perfectly! Thanks so much for your effort. I enjoy your blog and the UC Podcasts.
            Regards.

  4. Pingback: The UC Architects » Episode 22: A Game of Clouds

  5. Fantastic !! Can’t thank you enough. Is it possible to make age as one of the parameters and also parameter to include a specific folder.

    Regards.

      • Can you give me some pointer as how to exclude messages in “Managed Folder” and its subfolders. We use Exchange Managed Folders for classifying important emails.

        Regards

  6. Thanks for the script. I am going to try to use it to see if my novice PS skills can change it from deleting items with a specified message class to changing them to a similiar but different message class. If you happen to catch this and have suggestions they would be appreciated.

    Thanks again for your contributions to date.

    J

  7. I found a similar solution using the search-mailbox command. I chose this meathod because I’m not using Exchange Web Services.

    Search-Mailbox -Identity $UserName -SearchQuery “IPM.NOTE.EnterpriseVault.Shortcut” -DeleteContent

    You can test with the following commands.

    This produces a report with the number of hits
    Search-Mailbox -Identity $UserName -SearchQuery “IPM.NOTE.EnterpriseVault.Shortcut” –EstimateResultOnly

    This will search a mailbox, and all hits will be copied to another mailbox. You can look at that mailbox and see exactly what would be deleted if you used the -DeleteContent command.

    Search-Mailbox -Identity $UserName -SearchQuery “IPM.NOTE.EnterpriseVault.Shortcut” -TargetMailbox “TestMB” -TargetFolder “$UserName”

    • Mike,

      sorry to latch on so late, but i’ve tried doing the search way (because i thought it would be faster), but the content detected doesn’t seem to catch everything. I’d like to use search because it’s faster.

      Thoughts?

  8. Just tried this script today but unfortunately it’s not working for me. In verbose mode I can see it’s processing all the folders, but it didn’t find any e-mails with the class “IPM.Note.EnterpriseVault.Shortcut”.

      • After reading the comment below, I know why it’s not working for me. The stub mail items are all in the archive mailbox. Because the script did show all folders including the ones in the archive mailbox I thought it was also working for the archive. I will use the search-mailbox cmdlet for now. If you include the option to process the archive it will be a great script. Keep up the good work!

  9. This is an awesome script. Thank you so much for taking the time to publish it.

    What if the stub is already in the user’s Personal Archive? Can we use the script to remove stubs that have already been moved to the user’s archive?

  10. Hello Michel,

    when I run the script I get the following. I’m running the script as a Exchange Administrator and I have full mailbox rights on this test account. I doesn’t remove any of the EAS messageClass items.

    [PS] C:\>.\Remove-MessageClassItems.ps1 -Mailbox Training6 -DeleteMode SoftDelete -MessageClass IPM.Note.EAS -ScanAllFolders -verbose
    Processing mailbox Training6
    VERBOSE: Loading Microsoft.Exchange.WebServices.dll
    VERBOSE: Set to trust all certificates
    VERBOSE: Looking up EWS URL using Autodiscover for Training6@****.com
    VERBOSE: Using EWS on CAS https://mail.****.com/EWS/Exchange.asmx
    VERBOSE: DeleteMode is SoftDelete
    VERBOSE: Removing messages of class IPM.Note.EAS
    VERBOSE: Scanning all folders
    VERBOSE: Processing folder Calendar
    VERBOSE: Processing folder Contacts
    VERBOSE: Processing folder Conversation Action Settings
    VERBOSE: Processing folder Drafts
    VERBOSE: Processing folder Inbox
    VERBOSE: Processing folder Journal
    VERBOSE: Processing folder Junk E-Mail
    VERBOSE: Processing folder Notes
    VERBOSE: Processing folder Outbox
    VERBOSE: Processing folder Quick Step Settings
    VERBOSE: Processing folder RSS Feeds
    VERBOSE: Processing folder Sent Items
    VERBOSE: Processing folder Suggested Contacts
    VERBOSE: Processing folder Sync Issues
    VERBOSE: Processing folder Conflicts
    VERBOSE: Processing folder Local Failures
    VERBOSE: Processing folder Server Failures
    VERBOSE: Processing folder Tasks

  11. Great script. Thanks for it. I have a few suggestions that you can take or leave.

    Enhancement Suggestions:
    – Include a parameter to specify the EWS API location of not installed to the default location
    – Include a parameter to run as a desired account to impersonate.
    -Include a parameter to change the default EWS Exchange2007_SP1 config to other versions of Exchange
    + I did this as part of Troubleshooting my issues and it appeared to not be the root cause of the issue. Perhaps this is not required because of it.
    – Provide a parameter to output verbose output to a log file (I know we can pipe it… but it would be nice to have on screen and off screen output)

    Thanks again for the hard work and responsive assistance

  12. Hi,

    I’ve managed to get the script to run without error now (had various syntax issues), but it doesn’t seem to be doing anything. After hitting enter, I just get a line showing ‘>>’ and no further action happens.

    I am trying to permanently remove EV stubs in Exchange 2010:

    .\Remove-MessageClassItems.ps1″ -Mailbox TomU -MessageClass IPM.Note.EnterpriseVault.Shortcut -DeleteMode HardDelete -Impersonation –Verbose

    Any ideas please?
    Thanks

    • You shouldn’t have to edit the script. If you copied/pasted the exact cmdlet, there’s a quote mismatch (the >> means its waiting for more input since you didn’t enter a closing quote). Try this:
      .\Remove-MessageClassItems.ps1 -Mailbox TomU -MessageClass IPM.Note.EnterpriseVault.Shortcut -DeleteMode HardDelete -Impersonation –Verbose

      • My bad, I didn’t edit the script, just the cmdlet. Your amendment now generates an error telling me it is not digitally signed? Appreciate your help.

        File C:\2010\Remove-MessageClassItems.ps1 cannot be loaded. The file C:\2010\Remove-MessageClassItems.ps1 is not digitally signed. The script will not execute on the system. Please see “get-help about_signing” for more details..
        At line:1 char:31
        + .\Remove-MessageClassItems.ps1 <<<< -Mailbox TomU -MessageClass IPM.Note.EnterpriseVault.Shortcut -DeleteMode HardDe
        lete -Impersonation -Verbose
        + CategoryInfo : NotSpecified: (:) [], PSSecurityException
        + FullyQualifiedErrorId : RuntimeException

          • Thanks, getting there…. A whole host of errors now though. Appreciate your time but understand if you have better things to be doing!

            Processing mailbox TomU
            VERBOSE: Loading Microsoft.Exchange.WebServices.dll
            Exception calling “LoadFile” with “1” argument(s): “The system cannot find the file specified. (Exception from HRESULT:
            0x80070002)”
            At C:\2010\Remove-MessageClassItems.ps1:253 char:46
            + [void][Reflection.Assembly]::LoadFile <<<< ( $EwsDll)
            + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
            + FullyQualifiedErrorId : DotNetMethodException

            Unable to find type [Microsoft.Exchange.WebServices.Data.ExchangeVersion]: make sure that the assembly containing this
            type is loaded.
            At C:\2010\Remove-MessageClassItems.ps1:257 char:80
            + $ExchangeVersion= [Microsoft.Exchange.WebServices.Data.ExchangeVersion] <<<< ::Exchange2007_SP1
            + CategoryInfo : InvalidOperation: (Microsoft.Excha…ExchangeVersion:String) [], RuntimeException
            + FullyQualifiedErrorId : TypeNotFound

            New-Object : Cannot find type [Microsoft.Exchange.WebServices.Data.ExchangeService]: make sure the assembly containing
            this type is loaded.
            At C:\2010\Remove-MessageClassItems.ps1:258 char:32
            + $EwsService= New-Object <<<< Microsoft.Exchange.WebServices.Data.ExchangeService( $ExchangeVersion)
            + CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException
            + FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand

            Property 'UseDefaultCredentials' cannot be found on this object; make sure it exists and is settable.
            At C:\2010\Remove-MessageClassItems.ps1:259 char:21
            + $EwsService. <<<< UseDefaultCredentials= $true
            + CategoryInfo : InvalidOperation: (UseDefaultCredentials:String) [], RuntimeException
            + FullyQualifiedErrorId : PropertyNotFound

            VERBOSE: Set to trust all certificates
            VERBOSE: Using TomU@contoso.com for impersonation
            Unable to find type [Microsoft.Exchange.WebServices.Data.ConnectingIdType]: make sure that the assembly containing this
            type is loaded.
            At C:\2010\Remove-MessageClassItems.ps1:270 char:165
            + $EwsService.ImpersonatedUserId= New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Micros
            oft.Exchange.WebServices.Data.ConnectingIdType] <<<< ::SmtpAddress, $EmailAddress)
            + CategoryInfo : InvalidOperation: (Microsoft.Excha…onnectingIdType:String) [], RuntimeException
            + FullyQualifiedErrorId : TypeNotFound

            VERBOSE: Looking up EWS URL using Autodiscover for TomU@contoso.com
            Write-Error : A positional parameter cannot be found that accepts argument 'You cannot call a method on a null-valued e
            xpression.'.
            At C:\2010\Remove-MessageClassItems.ps1:286 char:28
            + Write-Error <<<< "Autodiscover failed: " $error[0]
            + CategoryInfo : InvalidArgument: (:) [Write-Error], ParentContainsErrorRecordException
            + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.WriteErrorCommand

          • @Tom: “Using this script requires Exchange 2007 or later and Exchange Web Services Managed API 1.2 (or later) which you can download here or you can copy the Microsoft.Exchange.WebServices.DLL locally and adjust the DLL path mentioned in the script when necessary. “

          • @No need to install; you can install it elsewhere, copy the Microsoft.Exchange.WebServices.DLL in the same location as the script and change the location (in the script) accordingly. Updated version of script will have additional logic to look for that DLL by the way.

          • Me again…. Now I’ve got this far… “Can’t access mailbox information store” ?

            Cheers

            Processing mailbox TomU
            VERBOSE: Loading Microsoft.Exchange.WebServices.dll
            VERBOSE: Set to trust all certificates
            VERBOSE: Using TomU@square-enix.com for impersonation
            VERBOSE: Looking up EWS URL using Autodiscover for TomU@xxx
            VERBOSE: Using EWS on CAS https://xxx/EWS/Exchange.asmx
            C:\2010\Remove-MessageClassItems.ps1 : Can’t access mailbox information store
            At line:1 char:31
            + .\Remove-MessageClassItems.ps1 <<<< -Mailbox TomU -MessageClass IPM.Note.EnterpriseVault.Shortcut -DeleteMode HardDe
            lete -Impersonation -Verbose
            + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
            + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Remove-MessageClassItems.ps1

  13. Is it possible to target only one folder? For instance I want to delete the
    IPM.Note.Microsoft.Conversation files from the ConversationHistory folder on 139 mailboxes. I have my csv file ready but I was hoping to avoid running the script against all of the folders in each mailbox.

    Thanks!

  14. Hi,

    I wanted to know whether this script will work on a 2013 exchange evironment? i have followed the directions posted in reference to impersonation, but still running into errors whether i excute the script from a CAS or MBX server. I am trying to delete stubs from a legacy email archive solution.

    Thanks!

  15. Thanks for this script.. I’m trying to purge EV Shortcuts from a broken EV environment before a mail migration to O365. Script works fine for the most part but for a few users I get the “Can’t access mailbox information store” at line 1 char:31. These are users that are on the exact same mailbox database that users that the script works fine for. Impersonation is set on the account I’m using to run the script and again seems to work for the other users. Size issue? (these are fairly large Exchange 2010 mailboxes) I went so far as to specifically add Full right and send as to these problem mailboxes with no luck

      • Figured it out.. I did a

        get-mailbox -identity “username” | export-csv user.csv -notype

        On the users that were not working and discovered that despite showing as a regular User Mailbox in Exchange 2010 Management Console these mailboxes were apparently Linked Mailboxes. I discovered this by comparing all the properties of the mailboxes that did not work vs the ones that did and discovered that the failing mailboxes had a Linked Maser Account value (I have a very old Exchange environment that originally started as Exchange 5.5 so somewhere along the way during the migrations some mailboxes came across as Linked)

        So I ran

        Set-User -Identity user@fabrikam.com -LinkedMasterAccount $null

        against the failing mailboxes and now the script is working.

  16. Will this work against office 365. I have tried several times without luck. Getting the following error.

    C:\Scripts\Remove-MessageClassItems.ps1 : Can’t access mailbox information store

  17. Pingback: Script Updates | EighTwOne (821)

  18. Hi,

    I’m running the script and it seems to be working great, (both against on prem and cloud users), however on certain users it just stalls out on various folders. They don’t seem to be that large but they just can’t process past them. I’ve run it in verbose but i don’t see anything specific being reported.

  19. I dont think the “before” switch is working, or I am using the wrong format. What format does the -before switch need. Does it need the date that you want all items older than that to be deleted, or is it the number of days before. If it is date, what format do you need date? I tried MM/DD/YYYY and YYYY/MM/DD and it does not work properly with any of those. Or at least it’s not parsing it correctly. See the results below. Using the -before, it is still trying to remove ALL my stubs, not just the ones before the date I have specified. I am running it against an Exchange 2007 SP3 environment in preparation for moving to Exchange 2013 SP1

    [PS] C:\Download>.\Remove-MessageClassItems.ps1 -Mailbox %USERNAME% -MessageClass IPM.Note.MimosaStubmimosa1 -Server cas2.MYDOMAIN.COM -DeleteMode har
    ddelete -Before 2013/06/01 -Verbose
    VERBOSE: Loading C:\Program Files\Microsoft\Exchange\Web Services\2.0\\Microsoft.Exchange.WebServices.dll
    Processing mailbox USERNAME (%USERNAME%@MYDOMAIN.COM)
    VERBOSE: Set to trust all certificates
    VERBOSE: Using Exchange Web Services URL https://cas2.MYDOMAIN.COM/EWS/Exchange.asmx
    VERBOSE: DeleteMode is harddelete
    VERBOSE: PartialMatching is False
    VERBOSE: Removing messages of class IPM.Note.MimosaStubmimosa1
    VERBOSE: Removing messages older than 06/01/2013 00:00:00
    VERBOSE: Scanning all IPF.Note (E-mail) folders
    VERBOSE: Processing folder Deleted Items
    VERBOSE: Processing folder Drafts
    VERBOSE: Processing folder Inbox

    Confirm
    Are you sure you want to perform this action?
    Performing operation “Remove-MessageClassItems.ps1″ on Target “Remove 431 items from Inbox”.
    [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is “Y”):

    • The format provided should be in the current locale, e.g. mm/dd/yyyy (it’s of type datetime so you could fit in a time as well). This is evaluated against the item’s Received attribute. To see the expected format, use:
      (Get-Culture).dateTimeFormat | Select *Pattern
      (don’t have Ex2007 at hand, should this be a PoSH 1 quirk, you can run it from system running a more recent version of PoSH – it will run against your mailbox on Ex2007SP1+).

      • I ended up finding out it was an issue with impersonation. When I use impersonation it works fine. I also ran it from a 2012 server running Powershell 3 and the Exchange 2013 tools on it. One additional thing, when it goes to delete the items, it always prompts you to confirm. This is a good thing by and large. But it seems for whatever reason when it calculates the number of items in the inbox, it is more than double what the actual stubbed email count is. Every other folder it seems to be 100% accurate. Can you think of a reason for this, or perhaps it might be a quirk?
        At any rate, I have to compliment you on this and a couple other powershell scripts I have found on your site (the delete duplicate items one), they have saved me a ton of hassle. I was planning on just using managed default folder policy to just delete all emails older than a certain thresshold just to purge the stubs, but this is much more palatable to the end user…

      • Michael, I found another thing I cannot explain. When running the script, it appears to not parse certain mail folders inside certain users mailboxes at all. Nothing special about these folders. I thought it might be a permissions thing, but looking at folder permissions, it seems that there would be nothing inhibiting it. Plus I thought with Impersonation, folder permission should be irrelavent. I could look at something in MFCMapi or PFDavAdmin if you want, but I am not sure what to look for. I did verify the messageclass is identical across all instances, (IPM.Note.MimosaStubMimosa1), so it’s not like some stubs have different message class than others. Every test user I have run this against has similar results. It’s just not hitting all folders.

      • Michael, I think I may have found my problem, let me know if you think. When looking at the script run, I found this text when running in verbose mode: “VERBOSE: Scanning all IPF.Note (E-mail) folders”. This led me to go into MFCMapi and look at the folders not being parsed. It appears none of these folders have the “PR_CONTAINER_CLASS” of IPF.Note. In fact, the folders do not have even have the “PR_CONTAINER_CLASS” field at all. Not just not poplulated, they do not have that attribute at all. For your information, about 80% of my users were migrated to Exchange from Groupwise many years ago, and it’s possible that when these folders were created in Exchange at that time by the (Quest) Migration tool, it created the folders as some odd type? Just throwing this out there. You may or may not have a way to fix this… thanks again.

    • All roads lead to Rome. Yet, that requires Ex2010 or up, EMS or being member of the Discovery Management role group to name a few. There are lots of pre-Ex2010 customers that want to get rid of the stubs before moving data over (On-Prem or ExO). The script is not meant to be a replacement for Search-Mailbox (as indicated in another comment).

    • The search-mailbox command does not exist in Exchange 2007. Just a heads up that there are thousands of customers out there still using Exchange older than 2010. Sometimes Microsoft forgets that. We cant all be bleeding edge.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s