From 4ebf4d4e30ced1eabf5a81bf39436cc4d5463072 Mon Sep 17 00:00:00 2001 From: Bill Long Date: Thu, 8 Sep 2022 16:22:19 -0500 Subject: [PATCH 1/2] Prevent erroneous empty folder results Aggregate child items must be reported to the parent at each level to produce correct results. --- .../SourceSideValidations/Tests/Limit/Test-FolderLimit.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PublicFolders/SourceSideValidations/Tests/Limit/Test-FolderLimit.ps1 b/PublicFolders/SourceSideValidations/Tests/Limit/Test-FolderLimit.ps1 index 992210393d..c911cbafaf 100644 --- a/PublicFolders/SourceSideValidations/Tests/Limit/Test-FolderLimit.ps1 +++ b/PublicFolders/SourceSideValidations/Tests/Limit/Test-FolderLimit.ps1 @@ -47,10 +47,14 @@ function Test-FolderLimit { $stats = $FolderData.StatisticsDictionary[$folder.EntryId] [int]$itemCount = $stats.ItemCount [Int64]$totalItemSize = $stats.TotalItemSize + $aggregateChildItemCount = $aggregateChildItemCounts[$folder.EntryId] $parent = $FolderData.EntryIdDictionary[$folder.ParentEntryId] if ($null -ne $parent) { $aggregateChildItemCounts[$parent.EntryId] += $itemCount + if ($null -ne $aggregateChildItemCount) { + $aggregateChildItemCounts[$parent.EntryId] += $aggregateChildItemCount + } } if ($itemCount -lt 1 -and $aggregateChildItemCounts[$folder.EntryId] -lt 1 -and $folder.FolderPathDepth -gt 0) { From 619d232d54676dbe23dec18255ca373bb24beff7 Mon Sep 17 00:00:00 2001 From: Bill Long Date: Thu, 8 Sep 2022 16:38:30 -0500 Subject: [PATCH 2/2] Better handling for no statistics scenario When Get-PublicFolderStatistics fails to return statistics, we now handle this scenario better. * The folder is assumed to have content so we do not report it as empty. * We call out the fact that statistics are not available and tests were skipped in the validation results. --- .../Tests/Limit/Test-FolderLimit.ps1 | 21 ++++++++++++++++--- .../Limit/Write-TestFolderLimitResult.ps1 | 8 +++++++ docs/PublicFolders/SourceSideValidations.md | 1 + 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/PublicFolders/SourceSideValidations/Tests/Limit/Test-FolderLimit.ps1 b/PublicFolders/SourceSideValidations/Tests/Limit/Test-FolderLimit.ps1 index c911cbafaf..7501cc467e 100644 --- a/PublicFolders/SourceSideValidations/Tests/Limit/Test-FolderLimit.ps1 +++ b/PublicFolders/SourceSideValidations/Tests/Limit/Test-FolderLimit.ps1 @@ -44,11 +44,26 @@ function Test-FolderLimit { Write-Progress @progressParams -Status $progressCount -PercentComplete ($progressCount * 100 / $FolderData.IpmSubtree.Count) } - $stats = $FolderData.StatisticsDictionary[$folder.EntryId] - [int]$itemCount = $stats.ItemCount - [Int64]$totalItemSize = $stats.TotalItemSize + # If we failed to get statistics for some reason, assume we have content + [int]$itemCount = 1 + [Int64]$totalItemSize = 0 $aggregateChildItemCount = $aggregateChildItemCounts[$folder.EntryId] + $stats = $FolderData.StatisticsDictionary[$folder.EntryId] + if ($null -ne $stats) { + [int]$itemCount = $stats.ItemCount + [Int64]$totalItemSize = $stats.TotalItemSize + } else { + $noStatisticsResult = @{ + TestName = "Limit" + Severity = "Warning" + ResultType = "NoStatistics" + FolderIdentity = $folder.Identity.ToString() + FolderEntryId = $folder.EntryId.ToString() + } + New-TestResult @noStatisticsResult + } + $parent = $FolderData.EntryIdDictionary[$folder.ParentEntryId] if ($null -ne $parent) { $aggregateChildItemCounts[$parent.EntryId] += $itemCount diff --git a/PublicFolders/SourceSideValidations/Tests/Limit/Write-TestFolderLimitResult.ps1 b/PublicFolders/SourceSideValidations/Tests/Limit/Write-TestFolderLimitResult.ps1 index 294bc39324..d7cdf9070e 100644 --- a/PublicFolders/SourceSideValidations/Tests/Limit/Write-TestFolderLimitResult.ps1 +++ b/PublicFolders/SourceSideValidations/Tests/Limit/Write-TestFolderLimitResult.ps1 @@ -17,6 +17,7 @@ function Write-TestFolderLimitResult { $itemCountResults = New-Object System.Collections.ArrayList $totalItemSizeResults = New-Object System.Collections.ArrayList $emptyFolderResults = New-Object System.Collections.ArrayList + $noStatisticsResults = New-Object System.Collections.ArrayList $hierarchyCountResult = $null $hierarchyAndDumpsterCountResult = $null $folderCountMigrationLimit = 250000 @@ -32,6 +33,7 @@ function Write-TestFolderLimitResult { "TotalItemSize" { [void]$totalItemSizeResults.Add($TestResult) } "HierarchyCount" { $hierarchyCountResult = $TestResult } "HierarchyAndDumpsterCount" { $hierarchyAndDumpsterCountResult = $TestResult } + "NoStatistics" { [void]$noStatisticsResults.Add($TestResult) } } } } @@ -79,5 +81,11 @@ function Write-TestFolderLimitResult { "Folders contain no items and have only empty subfolders. " + "These will not cause a migration issue, but they may be pruned if desired.") } + + if ($noStatisticsResults.Count -gt 0) { + Get-ResultSummary -ResultType $noStatisticsResults[0].ResultType -Severity $noStatisticsResults[0].Severity -Count $noStatisticsResults.Count -Action ( + "Public folder statistics could not be retreived for these folders. " + + "ItemCount, TotalItemSize, and EmptyFolder tests were skipped for these folders.") + } } } diff --git a/docs/PublicFolders/SourceSideValidations.md b/docs/PublicFolders/SourceSideValidations.md index 73c2672ed7..b4b9a3b477 100644 --- a/docs/PublicFolders/SourceSideValidations.md +++ b/docs/PublicFolders/SourceSideValidations.md @@ -48,6 +48,7 @@ Limit|FolderPathDepth|The folder path is greater than 299 folders deep. Limit|HierarchyCount|There are more than 250,000 total folders in the hierarchy. Limit|HierarchyAndDumpsterCount|There are more than 250,000 total folders if you count both the folders and their dumpsters. Limit|ItemCount|The folder has more than 1,000,000 items. +Limit|NoStatistics|Get-PublicFolderStatistics did not return any statistics for these folders. ItemCount, TotalItemSize, and EmptyFolder tests were skipped. Limit|TotalItemSize|The items directly in this folder (not child folders) add up to more than 25 GB. MailEnabledFolder|MailDisabledWithProxyGuid|The folder is not mail-enabled, but it has the GUID of an Active Directory object in its MailRecipientGuid property. MailEnabledFolder|MailEnabledSystemFolder|The folder is a system folder, which should not be mail-enabled.