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 = '******@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 Exchange Server Development
Windows for business Windows Server User experience PowerShell
{count} votes

Accepted answer
  1. Rich Matheisen 47,901 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 47,901 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.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.