Last active
February 16, 2024 19:59
-
-
Save bill-long/8a4f6eb44dd88db13c67a00c9903f27c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory = $false)] | |
[int]$MaxRetries = 20, | |
[Parameter(Mandatory = $false)] | |
[string]$LogFilePath = "$PSScriptRoot\GetAllPFStatistics.log" | |
) | |
function WriteHostAndLog($message) { | |
Write-Host $message | |
Add-Content -Path $LogFilePath -Value $message | |
} | |
function WriteLog($message) { | |
Add-Content -Path $LogFilePath -Value $message | |
} | |
function GetResidentFoldersWithRetry($PFMailboxResult) { | |
while ($true) { | |
try { | |
WriteHostAndLog "$(Get-Date) Getting hierarchy for $($PFMailboxResult.Mailbox.Name)" | |
$folders = @(Get-PublicFolder -Mailbox $PFMailboxResult.Mailbox.Name -ResidentFolders -Recurse -ResultSize Unlimited -ErrorAction Stop) | |
# Skip the root folder | |
if ($folders.Count -gt 1) { | |
$folders = $folders[1..$($folders.Count - 1)] | |
} else { | |
$folders = @() | |
} | |
WriteHostAndLog "$(Get-Date) Found $($folders.Count) public folders in mailbox $($PFMailboxResult.Mailbox.Name)" | |
$PFMailboxResult.Folders = $folders | |
return | |
} catch { | |
WriteHostAndLog "$(Get-Date) Error getting hierarchy: $($_.Exception.Message)" | |
$_ | Format-List * -Force | Out-String | ForEach-Object { WriteLog $_ } | |
[void]$PFMailboxResult.Errors.Add([PSCustomObject]@{ | |
Time = (Get-Date) | |
Stage = "Hierarchy" | |
Folder = $null | |
Error = $_ | |
}) | |
if ($errors.Count -ge $MaxRetries) { | |
WriteHostAndLog "$(Get-Date) Max retries reached, skipping mailbox $($PFMailboxResult.Mailbox.Name)" | |
break | |
} else { | |
WriteHostAndLog "$(Get-Date) Retrying in 5 seconds..." | |
Start-Sleep -Seconds 5 | |
continue | |
} | |
} | |
} | |
} | |
function GetPFMailboxStatisticsWithRetry($PFMailboxResult) { | |
WriteHostAndLog "$(Get-Date) Getting statistics for folders in mailbox $($PFMailboxResult.Mailbox.Name)" | |
$mailboxRetryCount = 0 | |
while ($PFMailboxResult.StatisticsProgressIndex -lt $PFMailboxResult.Folders.Count) { | |
if ($mailboxRetryCount -ge $MaxRetries) { | |
WriteHostAndLog "$(Get-Date) Max retries reached. Moving on to the next mailbox." | |
break | |
} | |
$folder = $PFMailboxResult.Folders[$PFMailboxResult.StatisticsProgressIndex] | |
if ($folder.Identity.ToString() -eq "\") { | |
$PFMailboxResult.StatisticsProgressIndex++ | |
continue | |
} | |
Write-Progress -Id 2 -ParentId 1 -Activity "Getting statistics" -Status "$($folder.Identity)" -PercentComplete ($PFMailboxResult.StatisticsProgressIndex / $PFMailboxResult.Folders.Count * 100) | |
$folderRetryCount = 0 | |
while ($true) { | |
try { | |
$stats = $folder | Get-PublicFolderStatistics -ErrorAction Stop | |
[void]$PFMailboxResult.Statistics.Add($stats) | |
$PFMailboxResult.StatisticsProgressIndex++ | |
break | |
} catch { | |
WriteHostAndLog "$(Get-Date) Error getting statistics on folder $($folder.Identity): $($_.Exception.Message)" | |
if ($_.ToString().Contains("ManagementObjectNotFoundException")) { | |
WriteHostAndLog "$(Get-Date) Folder appears to be deleted. Skipping..." | |
$PFMailboxResult.StatisticsProgressIndex++ | |
break | |
} | |
$_ | Format-List * -Force | Out-String | ForEach-Object { WriteLog $_ } | |
$folderRetryCount++ | |
[void]$PFMailboxResult.Errors.Add([PSCustomObject]@{ | |
Time = (Get-Date) | |
Stage = "Statistics" | |
Folder = $folder.Identity | |
Error = $_ | |
}) | |
if ($folderRetryCount -ge $MaxRetries) { | |
$mailboxRetryCount = $folderRetryCount | |
break | |
} else { | |
WriteHostAndLog "$(Get-Date) Retrying in 5 seconds..." | |
Start-Sleep -Seconds 5 | |
} | |
} | |
} | |
} | |
Write-Progress -Id 2 -ParentId 1 -Activity "Getting statistics" -Completed | |
} | |
function GetAndSaveResults($PassName, $ExistingResults) { | |
for ($i = 0; $i -lt $ExistingResults.Count; $i++) { | |
$pfMailboxResult = $ExistingResults[$i] | |
if ($null -ne $pfMailboxResult.Folders) { | |
continue | |
} | |
Write-Progress -Id 1 -Activity "Getting hierarchy" -Status "Mailbox: $($pfMailboxResult.Mailbox.Name)" -PercentComplete ($i / $ExistingResults.Count * 100) | |
$newResult = GetResidentFoldersWithRetry -PFMailboxResult $pfMailboxResult | |
if ($null -ne $newResult.Folders) { | |
$pfMailboxResult.Folders = $newResult.Folders | |
} | |
} | |
Write-Progress -Id 1 -Activity "Getting hierarchy" -Completed | |
for ($i = 0; $i -lt $ExistingResults.Count; $i++) { | |
$pfMailboxResult = $ExistingResults[$i] | |
if ($null -eq $pfMailboxResult.Folders -or $pfMailboxResult.StatisticsProgressIndex -ge $pfMailboxResult.Folders.Count) { | |
continue | |
} | |
Write-Progress -Id 1 -Activity "Getting statistics" -Status "Mailbox: $($pfMailboxResult.Mailbox.Name)" -PercentComplete ($i / $ExistingResults.Count * 100) | |
# This is null if we had to skip it due to too many retries on the hierarchy | |
if ($null -ne $pfMailboxResult.Folders) { | |
GetPFMailboxStatisticsWithRetry -pfMailboxResult $pfMailboxResult | |
} | |
} | |
Write-Progress -Id 1 -Activity "Getting statistics" -Completed | |
WriteHostAndLog "$(Get-Date) Results after $PassName pass:" | |
$pfMailboxResults | ForEach-Object { | |
[PSCustomObject]@{ | |
Mailbox = $($_.Mailbox.Name) | |
ErrorCount = $($_.Errors.Count) | |
HierarchyCount = $(if ($null -ne $_.Folders) { $_.Folders.Count } else { $null }) | |
StatisticsCount = $($_.Statistics.Count) | |
} | |
} | Format-Table -AutoSize | Out-String | ForEach-Object { WriteHostAndLog $_ } | |
WriteHostAndLog "$(Get-Date) Writing $PassName pass results to CSV..." | |
$pfMailboxResults.Statistics | Select-Object @{Name = "FolderPath"; Expression = { $_.FolderPath -join "\" } }, ItemCount, @{Name = "TotalItemSizeMB"; Expression = { [math]::Round(($_.TotalItemSize.ToString().Split("(")[1].Split(" ")[0].Replace(",", "") / 1MB), 2) } } | Export-Csv $PSScriptRoot\$($PassName)PassResults.csv -NoTypeInformation -Encoding utf8 | |
} | |
WriteHostAndLog "$(Get-Date) Getting public folder mailboxes..." | |
$pfMailboxes = Get-Mailbox -PublicFolder | |
WriteHostAndLog "$(Get-Date) Found $($pfMailboxes.Count) public folder mailboxes." | |
$pfMailboxResults = [System.Collections.ArrayList]::new() | |
foreach ($mailbox in $pfMailboxes) { | |
[void]$pfMailboxResults.Add([PSCustomObject]@{ | |
Mailbox = $mailbox | |
Folders = $null | |
Statistics = [System.Collections.ArrayList]::new() | |
StatisticsProgressIndex = 0 | |
Errors = [System.Collections.ArrayList]::new() | |
}) | |
} | |
GetAndSaveResults "First" $pfMailboxResults | |
$skippedHiearchy = $pfMailboxResults | Where-Object { $null -eq $_.Folders } | |
$skippedStatistics = $pfMailboxResults | Where-Object { $_.Statistics.Count -lt $_.Folders.Count } | |
if ($skippedHiearchy.Count -eq 0 -and $skippedStatistics.Count -eq 0) { | |
WriteHostAndLog "$(Get-Date) No skipped items. Done." | |
return | |
} | |
WriteHostAndLog "$(Get-Date) Skipped mailboxes due to too many retries on hierarchy: $($skippedHiearchy.Count)" | |
WriteHostAndLog "$(Get-Date) Skipped mailboxes due to too many retries on statistics: $($skippedStatistics.Count)" | |
WriteHostAndLog "$(Get-Date) Retrying skipped items..." | |
GetAndSaveResults "Second" $pfMailboxResults |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment