Repository: microsoft/CSS-Exchange
File: M365/Get-LargeMailboxFolderStatistics.ps1 (PowerShell)

Code before:
param(
    [Parameter(Mandatory = $true, Position = 0)]
    $Identity,
    [Parameter(Mandatory = $false, Position = 1)]
    [ValidateSet("Primary", "Archive")]
    $MailboxType = "Archive",
    [Parameter(Mandatory = $false, Position = 2)]
    $BatchSize = 5000,
    [Parameter(Mandatory = $false, Position = 3)]
    [string[]]$Properties = @("Name", "FolderPath", "ItemsInFolder", "FolderSize", "FolderAndSubfolderSize")
)

process {
    $allContentFolders = New-Object System.Collections.Generic.List[System.Management.Automation.PSCustomObject]
    $start = Get-Date
    Write-Host "$start Running Get-MailboxFolderStatistics for $Identity $MailboxType locations, in batches of $BatchSize"

    $mailboxLocations = Get-MailboxLocation -User $Identity

    foreach ($location in $mailboxLocations) {
        if (($location.MailboxLocationType -like '*Archive' -and $MailboxType -like 'Archive') -or ($location.MailboxLocationType -like '*Primary' -and $MailboxType -like 'Primary')) {
            $loopCount = 0
            do {
                $skipCount = $BatchSize * $loopCount
                $batch = Get-MailboxFolderStatistics -Identity $($location.Identity) -ResultSize $batchSize -SkipCount $skipCount
                $allContentFolders += $batch | Where-Object { $_.ContentFolder -eq "TRUE" } | Select-Object -Property $Properties
                Write-Host "$(Get-Date):$loopCount Found $($batch.Count) content folders from $($location.MailboxLocationType):$($location.MailboxGuid)"
                $loopCount += 1
            }
            while ($($batch.Count) -eq $BatchSize)
        }
    }

    $end = Get-Date
    Write-Host "$end Found $($allContentFolders.Count) total content folders in $(($end-$start).ToString()) duration"

    $allContentFolders
}


Review comment (performance):
Because of the way PowerShell works, this is going to change the type of `$allContentFolders` back to a generic array type. You should do something like this: 

```suggestion
                $batch = Get-MailboxFolderStatistics -Identity $($location.Identity) -ResultSize $batchSize -SkipCount $skipCount | 
                Where-Object { $_.ContentFolder -eq "TRUE" } | 
                Select-Object -Property $Properties
                $allContentFolders.AddRange($batch)
```

https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.addrange?view=net-8.0

Code after:
param(
    [Parameter(Mandatory = $true, Position = 0)]
    $Identity,
    [Parameter(Mandatory = $false, Position = 1)]
    [ValidateSet("Primary", "Archive")]
    $MailboxType = "Archive",
    [Parameter(Mandatory = $false, Position = 2)]
    $BatchSize = 5000,
    [Parameter(Mandatory = $false, Position = 3)]
    [string[]]$Properties = @("Name", "FolderPath", "ItemsInFolder", "FolderSize", "FolderAndSubfolderSize")
)

process {
    $allContentFolders = New-Object System.Collections.Generic.List[object]
    $start = Get-Date
    Write-Host "$start Running Get-MailboxFolderStatistics for $Identity $MailboxType locations, in batches of $BatchSize"

    $mailboxLocations = Get-MailboxLocation -User $Identity

    foreach ($location in $mailboxLocations) {
        if (($location.MailboxLocationType -like '*Archive' -and $MailboxType -like 'Archive') -or ($location.MailboxLocationType -like '*Primary' -and $MailboxType -like 'Primary')) {
            $loopCount = 0
            do {
                $skipCount = $BatchSize * $loopCount
                $batch = Get-MailboxFolderStatistics -Identity $($location.Identity) -ResultSize $batchSize -SkipCount $skipCount
                [System.Array]$contentFolders = $batch | Where-Object { $_.ContentFolder -eq "TRUE" } | Select-Object -Property $Properties
                if ($contentFolders.Count -gt 0) {
                    $allContentFolders.AddRange($contentFolders)
                }
                Write-Host "$(Get-Date):$loopCount Found $($batch.Count) content folders from $($location.MailboxLocationType):$($location.MailboxGuid)"
                $loopCount += 1
            }
            while ($($batch.Count) -eq $BatchSize)
        }
    }

    $end = Get-Date
    Write-Host "$end Found $($allContentFolders.Count) total content folders in $(($end-$start).ToString()) duration"

    $allContentFolders
}