Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
5a1f736
Refactor SourceSideValidations
bill-long May 17, 2021
3143a68
Resume after failure in SlowTraversal mode
bill-long May 20, 2021
1a4ec55
Use New-Object rather than ::new()
bill-long Jun 1, 2021
270e322
Report errors during Get-ItemCount and retry
bill-long Jun 1, 2021
5c67cc8
Report the hierarchy limits with the other results
bill-long Jun 1, 2021
0a60eae
Recreate the session on retry and report empty folders
bill-long Jun 4, 2021
8c30e9b
Tie up some loose ends
bill-long Jun 29, 2021
7f32847
Fix path depth calculation
bill-long Jul 26, 2021
f80773d
Adjust BadPermission result summary
bill-long Jul 26, 2021
be59270
Send completed jobs to the pipeline
bill-long Jul 26, 2021
59aa05a
Multithreaded slow traversal item count
bill-long Jul 26, 2021
1e910be
Preserve previous validation results
bill-long Jul 27, 2021
9b618f5
Merge branch 'main' into bilong-ssvrefactor2
bill-long Jul 27, 2021
32d2f4f
CodeFormatter fixes
bill-long Jul 27, 2021
b9463d1
Merge branch 'main' into bilong-ssvrefactor2
bill-long Jul 29, 2021
cef43be
Prevent unwanted output to pipeline
bill-long Jul 29, 2021
60d1c7d
Set debug config to interactive console for local debug
bill-long Jul 29, 2021
8262cfd
Take pipeline input to New-TestResult
bill-long Jul 30, 2021
860f6db
Merge branch 'main' into bilong-ssvrefactor2
bill-long Sep 3, 2021
a29a7f7
PSScriptAnalyzer fixes
bill-long Sep 3, 2021
ec37d43
Remove the item count progress file
bill-long Sep 3, 2021
23fb742
Add a little whitespace
bill-long Sep 3, 2021
a16ca56
Add folder name check
bill-long Sep 3, 2021
ee2ebf4
Allow specifying which tests to run
bill-long Sep 3, 2021
0a7c57e
Fix dumpster result bug
bill-long Sep 3, 2021
e36366e
Fix name result bug
bill-long Sep 3, 2021
d68f65a
Accurately calculate folder path depth
bill-long Sep 3, 2021
0b5ac77
Fix path depth calculation off by one
bill-long Sep 3, 2021
8e63842
Report folders that are completely empty including their subfolders
bill-long Sep 3, 2021
851cccd
Replace problem characters with spaces
bill-long Sep 3, 2021
6b333e5
gitignore launch.json
bill-long Sep 3, 2021
62c409f
Remove unintended console output
bill-long Sep 3, 2021
87281e4
Move the export operations so they are only called when we actually g…
bill-long Sep 3, 2021
abeff17
Faster approach to suppressing output
bill-long Sep 3, 2021
c4a22c3
Consistently use -AllowClobber
bill-long Sep 3, 2021
0c9788e
Add missing import
bill-long Sep 3, 2021
e0ad302
Update docs for SSV
bill-long Sep 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
launch.json

This file was deleted.

102 changes: 70 additions & 32 deletions PublicFolders/src/SourceSideValidations/Get-FolderData.ps1
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

. $PSScriptRoot\Get-IpmSubtree.ps1
. $PSScriptRoot\Get-NonIpmSubtree.ps1
. $PSScriptRoot\Get-ItemCount.ps1

function Get-FolderData {
[CmdletBinding()]
param (
[Parameter()]
[bool]
$StartFresh = $true
$StartFresh = $true,

[Parameter()]
[bool]
$SlowTraversal = $false
)

begin {
Write-Verbose "$($MyInvocation.MyCommand) called."
$startTime = Get-Date
$serverName = (Get-Mailbox -PublicFolder (Get-OrganizationConfig).RootPublicFolderMailbox.HierarchyMailboxGuid.ToString()).ServerName
$folderData = [PSCustomObject]@{
Expand All @@ -21,66 +30,99 @@ function Get-FolderData {
NonIpmEntryIdDictionary = @{}
MailboxToServerMap = @{}
ItemCounts = @()
ItemCountDictionary = @{}
Errors = New-Object System.Collections.ArrayList
}
}

process {
if (-not $StartFresh -and (Test-Path $PSScriptRoot\IpmSubtree.csv)) {
$folderData.IpmSubtree = Import-Csv $PSScriptRoot\IpmSubtree.csv
$folderData.NonIpmSubtree = Import-Csv $PSScriptRoot\NonIpmSubtree.csv
$folderData.ItemCounts = Import-Csv $PSScriptRoot\ItemCounts.csv
} else {
Add-JobQueueJob @{
ArgumentList = $serverName
ArgumentList = $serverName, $SlowTraversal
Name = "Get-IpmSubtree"
ScriptBlock = ${Function:Get-IpmSubtree}
}
}

if (-not $StartFresh -and (Test-Path $PSScriptRoot\NonIpmSubtree.csv)) {
$folderData.NonIpmSubtree = Import-Csv $PSScriptRoot\NonIpmSubtree.csv
} else {
Add-JobQueueJob @{
ArgumentList = $serverName
ArgumentList = $serverName, $SlowTraversal
Name = "Get-NonIpmSubtree"
ScriptBlock = ${Function:Get-NonIpmSubtree}
}
}

Add-JobQueueJob @{
ArgumentList = $serverName
Name = "Get-ItemCount"
ScriptBlock = ${Function:Get-ItemCount}
# If we're not doing slow traversal, we can get the stats concurrently with the other jobs
if (-not $SlowTraversal) {
if (-not $StartFresh -and (Test-Path $PSScriptRoot\ItemCounts.csv)) {
$folderData.ItemCounts = Import-Csv $PSScriptRoot\ItemCounts.csv
} else {
Add-JobQueueJob @{
ArgumentList = $serverName
Name = "Get-ItemCount"
ScriptBlock = ${Function:Get-ItemCount}
}
}
}

$completedJobs = Wait-QueuedJob
$completedJobs = Wait-QueuedJob

foreach ($job in $completedJobs) {
if ($null -ne $job.IpmSubtree) {
$folderData.IpmSubtree = $job.IpmSubtree
$folderData.IpmSubtree | Export-Csv $PSScriptRoot\IpmSubtree.csv
}
foreach ($job in $completedJobs) {
if ($null -ne $job.IpmSubtree) {
$folderData.IpmSubtree = $job.IpmSubtree
$folderData.IpmSubtree | Export-Csv $PSScriptRoot\IpmSubtree.csv
}

if ($null -ne $job.NonIpmSubtree) {
$folderData.NonIpmSubtree = $job.NonIpmSubtree
$folderData.NonIpmSubtree | Export-Csv $PSScriptRoot\NonIpmSubtree.csv
}
if ($null -ne $job.NonIpmSubtree) {
$folderData.NonIpmSubtree = $job.NonIpmSubtree
$folderData.NonIpmSubtree | Export-Csv $PSScriptRoot\NonIpmSubtree.csv
}

if ($null -ne $job.ItemCounts) {
$folderData.ItemCounts = $job.ItemCounts
$folderData.ItemCounts | Export-Csv $PSScriptRoot\ItemCounts.csv
}
if ($null -ne $job.ItemCounts) {
$folderData.ItemCounts = $job.ItemCounts
$folderData.ItemCounts | Export-Csv $PSScriptRoot\ItemCounts.csv
}
}

$folderData.IpmSubtreeByMailbox = $folderData.IpmSubtree | Group-Object ContentMailbox
$folderData.IpmSubtree | ForEach-Object { $folderData.ParentEntryIdCounts[$_.ParentEntryId] += 1 }
$folderData.IpmSubtree | ForEach-Object { $folderData.EntryIdDictionary[$_.EntryId] = $_ }
# We can't count on $folder.Path.Depth being available in remote powershell,
# so we calculate the depth by walking the parent entry IDs.
$folderData.IpmSubtree | ForEach-Object {
$pathDepth = 0
$parent = $folderData.EntryIdDictionary[$_.ParentEntryId]
while ($null -ne $parent) {
$pathDepth++
$parent = $folderData.EntryIdDictionary[$parent.ParentEntryId]
}

Add-Member -InputObject $_ -MemberType NoteProperty -Name FolderPathDepth -Value $pathDepth
}
$folderData.NonIpmSubtree | ForEach-Object { $folderData.NonIpmEntryIdDictionary[$_.EntryId] = $_ }
$folderData.ItemCounts | ForEach-Object {
if ($_.ItemCount -gt 0) {
$folder = $folderData.EntryIdDictionary[$_.EntryId.ToString()]

if ($null -ne $folder) {
$folder.ItemCount = $_.ItemCount
# If we're doing slow traversal, we have to get the stats after we have the hierarchy
# grouped by mailbox.
if ($SlowTraversal) {
if (-not $StartFresh -and (Test-Path $PSScriptRoot\ItemCounts.csv)) {
$folderData.ItemCounts = Import-Csv $PSScriptRoot\ItemCounts.csv
} else {
Write-Verbose "Starting slow traversal item count."
$itemCountResult = Get-ItemCount $serverName $folderData
$folderData.ItemCounts = $itemCountResult.ItemCounts
$folderData.ItemCounts | Export-Csv $PSScriptRoot\ItemCounts.csv
foreach ($errorParam in $itemCountResult.Errors) {
$errorResult = New-TestResult @errorParam
$folderData.Errors.Add($errorResult)
}
}
}

$folderData.ItemCounts | ForEach-Object { $folderData.ItemCountDictionary[$_.EntryId] = $_.ItemCount }
}

end {
Expand All @@ -91,7 +133,3 @@ function Get-FolderData {
return $folderData
}
}

. $PSScriptRoot\Get-IpmSubtree.ps1
. $PSScriptRoot\Get-NonIpmSubtree.ps1
. $PSScriptRoot\Get-ItemCount.ps1
Loading