Powershell script on Exchange server returns 800+ records out of 62000. Why?

Alexander Korchagin 21 Reputation points
2021-02-21T18:35:17.797+00:00

Hi,
I've used script below to extract all attachments from mailbox (needed to perform only once). It's a mailbox where reports was sent, so it contains only messages with specific name and attachment.
And it returns only 800+ records out of 60+ thousands. Any advice how to modify it? I've tried to change ItemView from 1000 to 63000, nothing changed.

# Name of the mailbox to pull attachments from
$MailboxName = 'maibox@domain.com'

# Location to move attachments
$downloadDirectory = 'E:\ToExport'

# Path to the Web Services dll
$dllpath = "E:\Exchange\V15\Bin\Microsoft.Exchange.WebServices.dll"
[VOID][Reflection.Assembly]::LoadFile($dllpath)

# Create the new web services object
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2019)

# Create the LDAP security string in order to log into the mailbox
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
$aceuser = [ADSI]$sidbind

# Auto discover the URL used to pull the attachments
$service.AutodiscoverUrl($aceuser.mail.ToString())

# Get the folder id of the Inbox
$folderid = new-object  Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$MailboxName)
$InboxFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)

# Find mail in the Inbox with attachments
$Sfha = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::HasAttachments, $true)
$sfCollection = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And);
$sfCollection.add($Sfha)

# Grab all the mail that meets the prerequisites
$view = new-object Microsoft.Exchange.WebServices.Data.ItemView(63000)
$frFolderResult = $InboxFolder.FindItems($sfCollection,$view)

# Loop through the emails
foreach ($miMailItems in $frFolderResult.Items){

    # Load the message
    $miMailItems.Load()

    # Loop through the attachments
    foreach($attach in $miMailItems.Attachments){

        # Load the attachment
        $attach.Load()

        # Save the attachment to the predefined location
        $fiFile = new-object System.IO.FileStream(($downloadDirectory + “\” + $attach.Name.ToString()), [System.IO.FileMode]::Create)       
                $fiFile.Write($attach.Content, 0, $attach.Content.Length)
        $fiFile.Close()
    }
 }
Exchange Server Development
Exchange Server Development
Exchange Server: A family of Microsoft client/server messaging and collaboration software.Development: The process of researching, productizing, and refining new or existing technologies.
516 questions
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,389 questions
{count} votes

Accepted answer
  1. Rich Matheisen 45,096 Reputation points
    2021-02-22T03:39:24.7+00:00

    This is just the section of your code that I think needs modification. I've marked what I've added with "#ADDED" at the end of each line. It follows the code example in the link I posted earlier. I have not tested this:

    # Grab all the mail that meets the prerequisites
    $view = New-Object Microsoft.Exchange.WebServices.Data.ItemView(63000)
    
    $more = $true   # ADDED
    Do {    # ADDED
        $frFolderResult = $InboxFolder.FindItems($sfCollection, $view)
    
        # Loop through the emails
        foreach ($miMailItems in $frFolderResult.Items) {
    
            # Load the message
            $miMailItems.Load()
    
            # Loop through the attachments
            foreach ($attach in $miMailItems.Attachments) {
    
                # Load the attachment
                $attach.Load()
    
                # Save the attachment to the predefined location
                $fiFile = New-Object System.IO.FileStream(($downloadDirectory + “\” + $attach.Name.ToString()), [System.IO.FileMode]::Create)       
                $fiFile.Write($attach.Content, 0, $attach.Content.Length)
                $fiFile.Close()
            }
        }
        $more = $frFolderResult.MoreAvailable   # ADDED
        if ($more){ # ADDED
            $view.Offset += 1000    # ADDED
        }   # ADDED
    } while ($more) # ADDED
    

1 additional answer

Sort by: Most helpful
  1. Rich Matheisen 45,096 Reputation points
    2021-02-21T22:18:23.47+00:00

    Have a look here: what-is-the-maximal-size-of-an-itemview-in-ews

    You'll have to loop over the FindItems using $frFolderResult.MoreAvailable until no more results are returned.