The += array problem is fixed by switching to a [System.Collections.Generic.List], which adds items in-place without rebuilding the array each time.

The problem:

$results = @()
foreach ($message in $newMessages) {
    $results += $result   # Destroys and rebuilds the entire array every iteration
}

The fix:

$results = [System.Collections.Generic.List[PSCustomObject]]::new()
foreach ($message in $newMessages) {
    $results.Add($result)   # Appends in-place, no rebuild
}

Apply the same change to $existingList:

# Before
$existingList = @()
$existingList += $indresult

# After
$existingList = [System.Collections.Generic.List[PSCustomObject]]::new()
$existingList.Add($indresult)

Why it matters in practice — every += on a plain @() array copies every existing element into a new array, then adds the new one. The cost grows with each iteration:

Messages += array List .Add()
100 ~5,000 copy operations 100 operations
500 ~125,000 copy operations 500 operations
1,000 ~500,000 copy operations 1,000 operations

An alternative that's equally valid is to just let PowerShell collect the output of the foreach directly into a variable, which avoids the issue entirely without needing a List:

$results = foreach ($message in $newMessages) {
    # No $results += needed — just output the object directly
    [PSCustomObject]@{
        MessageID = $message.Id
        # ... etc
    }
}

PowerShell handles the collection internally and this is arguably the most idiomatic approach for pure data transformation loops.