none
EWS script to list all mailbox items - Exchange 2010 SP2 RRS feed

  • Question

  • Hello,

    A colleague and I have been working on a script to query and list all of the items within a mailbox, (including sub-folders), and output a list of items to a .csv file for use in a legal case currently being undertaken by our company.

    We need to ensure that all items within each mailbox we target are discovered, and subsequently listed in the output file.

    We have got so far, and the script we have is working to a degree, however when some mailbox folders are queried by the script errors are returned, and we cannot understand why. The error would seem to refer to the the fact that the folders are empty, but we know there are items within these folders.

    Below is a copy of the script, and below that is a sample of the script as it runs and enumerates the mailbox folders.

    Script:

     
    $MailBoxName = "email@mycompany.com"
     
     
    #Define Function to convert String to FolderPath  
    function ConvertToString($ipInputString){  
        $Val1Text = ""  
        for ($clInt=0;$clInt -lt $ipInputString.length;$clInt++){  
                $Val1Text = $Val1Text + [Convert]::ToString([Convert]::ToChar([Convert]::ToInt32($ipInputString.Substring($clInt,2),16)))  
                $clInt++  
        }  
        return $Val1Text  
    } 
     
     
     
      
    ## Load Managed API dll  
    Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"  
      
    ## Set Exchange Version  
    $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2  
      
    ## Create Exchange Service Object  
    $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion)  
      
    ## Set Credentials  
    $service.UseDefaultCredentials = $true  
      
    ## Choose to ignore any SSL Warning issues caused by Self Signed Certificates  
    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}  
      
    ## Set the URL of the CAS 
    #service.AutodiscoverUrl($MailBoxName,{$true})  
       
    $windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
    $aceuser = [ADSI]$sidbind 
     
    $service.AutodiscoverUrl($aceuser.mail.ToString())
     
     
     
    #Define Extended properties  
    $PR_FOLDER_TYPE = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(13825,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer)
    $rootFolderId = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)  
    #Define the FolderView & ItemView to retrieve 1000 at a time.  
    $folderView =  New-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)
    $itemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000) 
    #Deep Transval will ensure all folders in the search path are returned  
    $folderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
    $folderPropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)  
    $PR_MESSAGE_SIZE_EXTENDED = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(3592,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Long)
    $PR_DELETED_MESSAGE_SIZE_EXTENDED = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(26267,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Long)
    $PR_Folder_Path = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(26293, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
    #Add Properties to the folder Property Set  
    $folderPropertySet.Add($PR_MESSAGE_SIZE_EXTENDED)
    $folderPropertySet.Add($PR_Folder_Path)
    $folderView.PropertySet = $folderPropertySet
    #Define the item Property Set 
    $itemPropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)  
    #The Search filter will exclude any Search Folders  
    $folderSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo($PR_FOLDER_TYPE,"1")  
    $foldersResult = $null  
     
     
     
    $allEmails = @()
     
     
    #The Do loop will handle any paging that is required if there are more the 1000 folders in a mailbox  
    do {  
        $foldersResult = $Service.FindFolders($rootFolderId,$folderSearchFilter,$folderView) 
        foreach($folder in $foldersResult.Folders){  
            
            #Only use EmailMessage folders
            if ($folder.FolderClass -eq "IPF.Note" -and $folder.DisplayName -ne "Drafts") {
                
                #Try to get the FolderPath Value and then convert it to a usable String   
                $foldpathval = $null
                if ($folder.TryGetProperty($PR_Folder_Path,[ref] $foldpathval))  
                {  
                    $binarry = [Text.Encoding]::UTF8.GetBytes($foldpathval)  
                    $hexArr = $binarry | ForEach-Object { $_.ToString("X2") }  
                    $hexString = $hexArr -join ''  
                    $hexString = $hexString.Replace("FEFF", "5C00")  
                    $fpath = ConvertToString($hexString)  
                }    
                $fpath
                # Get the items within the current folder
                $itemsResult = $null  
                
                if ($folder.TotalCount -ne 0) {
                do{
                    
                    $itemsResult = $service.FindItems($folder.Id,$itemView)  
                    [Void]$service.LoadPropertiesForItems($itemsResult,$itemPropertySet) 
                    
                    foreach($Item in $itemsResult.Items){  
                    
                        #Create an object
                        $email = New-Object System.Object
                        
                        #Add the simple properties
                        $email | Add-Member -Type NoteProperty -Name FolderPath -Value $fpath
                        $email | Add-Member -Type NoteProperty -Name DateSent -Value $Item.DateTimeSent
                        $email | Add-Member -Type NoteProperty -Name DateReceived -Value $Item.DateTimeReceived
                        $email | Add-Member -Type NoteProperty -Name Sender -Value $Item.Sender.Address
                        $email | Add-Member -Type NoteProperty -Name Subject -Value $Item.Subject
                        $email | Add-Member -Type NoteProperty -Name Size -Value $Item.Size
                        
                        #Enumerate ToRecipients
                        $ToRecipientCount = $Item.ToRecipients.Count
                        if ($ToRecipientCount -gt 0) {
                            $to = ""
                            for ($i=0;$i -lt $ToRecipientCount;$i++) {
                                $to += $Item.ToRecipients.Item($i).Address + "; "
                            }
                            $email | Add-Member -Type NoteProperty -Name To -Value $to
                        }
                        
                        #Enumerate CcRecipients
                        $CcRecipientCount = $Item.CcRecipients.Count
                        if ($CcRecipientCount -gt 0) {
                            $cc = ""
                            for ($i=0;$i -lt $CcRecipientCount;$i++) {
                                $cc += $Item.CcRecipients.Item($i).Address + "; "
                            }
                            $email | Add-Member -Type NoteProperty -Name Cc -Value $cc
                        }
                        
                        #Enumerate BccRecipients
                        $BccRecipientCount = $Item.BccRecipients.Count
                        if ($BccRecipientCount -gt 0) {
                            $bcc = ""
                            for ($i=0;$i -lt $BccRecipientCount;$i++) {
                                $bcc += $Item.BccRecipients.Item($i).Address + "; "
                            }
                            $email | Add-Member -Type NoteProperty -Name Bcc -Value $bcc
                        }
                      
                        #Enumerate attachments
                        if ($Item.HasAttachments) {
                            $attachmentCount = $Item.Attachments.Count                        
                            if ($attachmentCount -gt 0) {
                                $attachments = ""
                                for ($i=0;$i -lt $attachmentCount;$i++) {
                                        $attachments += $Item.Attachments.Item($i).Name + "; "
                                }
                                $email | Add-Member -Type NoteProperty -Name Attachments -Value $attachments
                            }
                        }
                        
                        #Add this item to the collection
                        $allEmails += $email
                    }  
                    $itemView.Offset += $itemsResult.Items.Count  
                }while($itemsResult.MoreAvailable -eq $true) 
                }
            }
        } 
        $folderView.Offset += $foldersResult.Folders.Count
    }while($foldersResult.MoreAvailable -eq $true)  
     
     
    $allEmails | Select FolderPath,DateSent,DateReceived,Sender,Subject,Size,To,Cc,Bcc,Attachments | Export-Csv C:\Get-MailboxContent.csv
    #$allEmails
    
    

    Error:

    [PS] C:\Get-MailboxContent.ps1
    \Deleted Items
    \Inbox
    \Inbox\Test
    Exception calling "LoadPropertiesForItems" with "2" argument(s): "The collectio
    n is empty.
    Parameter name: items"
    At C:\Get-Mailbo
    xContent.ps1:97 char:54
    +                 [Void]$service.LoadPropertiesForItems <<<< ($itemsResult,$ite
    mPropertySet) 
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : DotNetMethodException
     
    \Junk E-Mail
    \Outbox
    \Sent Items
    Exception calling "LoadPropertiesForItems" with "2" argument(s): "The collectio
    n is empty.
    Parameter name: items"
    At C:\Get-Mailbo
    xContent.ps1:97 char:54
    +                 [Void]$service.LoadPropertiesForItems <<<< ($itemsResult,$ite
    mPropertySet) 
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : DotNetMethodException

    Can anyone assist with trying to resolve this issue please?

    Regards

    Matt


    Matt

    Wednesday, June 13, 2012 11:54 AM

All replies

  • I would suggest you make sure you set the ItemView offset back to 0 between folders (or re-create the object) 

    eg

        foreach($folder in $foldersResult.Folders){  
            $itemView.Offset = 0

    I'd would also put a check around

    if($itemsResult.Items.Count -gt 0){
    	[Void]$service.LoadPropertiesForItems($itemsResult,$itemPropertySet) 
    }

    You could get 0 Items returned if you where getting throttled etc

    Cheers
    Glen

    Thursday, June 14, 2012 6:55 AM
  • Thanks Glen.

    I will try your suggested modification and let you know if it works.

    Thanks


    Matt

    Friday, June 15, 2012 9:54 AM