diff --git a/M365/Get-LargeMailboxFolderStatistics.ps1 b/M365/Get-LargeMailboxFolderStatistics.ps1 new file mode 100644 index 000000000..02a8cc014 --- /dev/null +++ b/M365/Get-LargeMailboxFolderStatistics.ps1 @@ -0,0 +1,72 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +#Requires -Modules @{ ModuleName="ExchangeOnlineManagement"; RequiredVersion="3.4.0" } + +<# +.SYNOPSIS + Retrieves folder statistics for mailboxes with large numbers of folders. + +.DESCRIPTION + This script retrieves folder statistics for large mailboxes or a specified user identity. + It can target either primary or archive mailboxes and processes the data in batches. + +.PARAMETER Identity + The identity of the user whose mailbox folder statistics are to be retrieved. + +.PARAMETER MailboxType + Specifies the type of mailbox to target. Valid values are "Primary" and "Archive". + Default is "Archive". + +.PARAMETER BatchSize + Specifies the number of items to process in each batch. Default is 5000. + +.PARAMETER Properties + Specifies the properties to include in the output. Default is "Name, FolderPath, ItemsInFolder, FolderSize, FolderAndSubfolderSize". + +.EXAMPLE + $folderStats = .\Get-LargeMailboxFolderStatistics.ps1 -Identity fred@contoso.com + $folderStats = .\Get-LargeMailboxFolderStatistics.ps1 -Identity fred@contoso.com -MailboxType Primary + $folderStats = .\Get-LargeMailboxFolderStatistics.ps1 -Identity fred@contoso.com -MailboxType Archive -BatchSize 5000 -Properties @("Name", "FolderPath") +#> +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 +} diff --git a/docs/M365/Get-LargeMailboxFolderStatistics.md b/docs/M365/Get-LargeMailboxFolderStatistics.md new file mode 100644 index 000000000..b10c9191c --- /dev/null +++ b/docs/M365/Get-LargeMailboxFolderStatistics.md @@ -0,0 +1,36 @@ +# Get-LargeMailboxFolderStatistics + +Download the latest release: [Get-LargeMailboxFolderStatistics.ps1](https://github.com/microsoft/CSS-Exchange/releases/latest/download/Get-LargeMailboxFolderStatistics.ps1) + + +This script runs the Get-MailboxFolderStatistics cmdlet and works around the problem of cmdlet timeouts where there are a large number of folders in the mailbox. This is particularly useful with mailboxes with more than 10k folders, especially Archive mailboxes. +Although it can work with both Primary and Archive mailboxes. + +By default the script will try and retrieve the folder statistics for a user's Archive mailbox. It will retrieve the folders in batches of 5000 and just retrieve the commonly required properties Name, FolderPath, ItemsInFolder, FolderSize, FolderAndSubfolderSize. + + +#### Syntax: + +Example to get the mailbox folder statistics for an Archive mailbox. +```PowerShell +$folderStats = .\Get-LargeMailboxFolderStatistics.ps1 -Identity fred@contoso.com +``` + +Example to get the mailbox folder statistics for a Primary mailbox. +```PowerShell +$folderStats = .\Get-LargeMailboxFolderStatistics.ps1 -Identity fred@contoso.com -MailboxType Primary +``` + +Example to get the mailbox folder statistics for a Archive mailbox, in batches of 5000 and just the folder properties Name and FolderPath +```PowerShell +$folderStats = .\Get-LargeMailboxFolderStatistics.ps1 -Identity fred@contoso.com -MailboxType Archive -BatchSize 5000 -Properties @("Name", "FolderPath") +``` + + + +##### Further information
+ +The sweet spot seems to be retrieving folders in batches of about 5000 at a time. This prevents cmdlet timeouts but also achieves a good overall run time. + +The script has been used successfully against archives mailboxes with up to 60K folders. + diff --git a/mkdocs.yml b/mkdocs.yml index 6f2e83b82..f47ea6f9e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -79,6 +79,7 @@ nav: - MDO: - MDOThreatPolicyChecker: M365/MDO/MDOThreatPolicyChecker.md - DLT365Groupsupgrade: M365/DLT365Groupsupgrade.md + - Get-LargeMailboxFolderStatistics: M365/Get-LargeMailboxFolderStatistics.md - Performance: - ExPerfWiz: Performance/ExPerfWiz.md - ExPerfAnalyzer: Performance/ExPerfAnalyzer.md