From bd4ffe5c16de324506e7f50df782f4d7e9a75c67 Mon Sep 17 00:00:00 2001 From: hazemembaby <71065889+hazemembaby@users.noreply.github.com> Date: Wed, 7 Jun 2023 17:31:30 +0300 Subject: [PATCH 1/6] update dumpster script --- PublicFolders/ValidateEXOPFDumpster.ps1 | 402 +++++++++++++----------- 1 file changed, 217 insertions(+), 185 deletions(-) diff --git a/PublicFolders/ValidateEXOPFDumpster.ps1 b/PublicFolders/ValidateEXOPFDumpster.ps1 index e12543901b..cf9aa1b766 100644 --- a/PublicFolders/ValidateEXOPFDumpster.ps1 +++ b/PublicFolders/ValidateEXOPFDumpster.ps1 @@ -4,12 +4,12 @@ param( [Parameter(Mandatory = $false)] [String]$ExportPath, [Parameter(Mandatory = $true)] - [String]$PFolder, + [String]$Pfolder, [Parameter(Mandatory = $false)] - [String]$AffectedUser) + [String]$Affecteduser) $Script:ReportName = "ValidatePFDumpsterREPORT.txt" -#Requires -Modules @{ModuleName="ExchangeOnlineManagement"; ModuleVersion="2.0.0" } -function LogError { +#Requires -Modules @{ModuleName="ExchangeOnlineManagement"; ModuleVersion="3.0.0" } +function logerror { param( [Parameter(Mandatory = $true)] [string]$CurrentStatus, @@ -25,9 +25,9 @@ function LogError { Function = $Function Description = $CurrentDescription Status = $CurrentStatus - } | Export-Csv $ExportPath\ValidatePFDumpsterChecksLogging.csv -NoTypeInformation -Append + } | Export-Csv $ExportPath\ValidatePFDumpsterCheckslogging.csv -NoTypeInformation -Append } -function WriteToScreenAndLog { +function WritetoScreenANDlog { param( [Parameter(Mandatory = $true)] [String]$Issue, @@ -45,113 +45,131 @@ function WriteToScreenAndLog { function Connect2EXO { try { - Write-Host "Connecting to EXO V2, please enter Global administrator credentials when prompted!" -ForegroundColor Yellow + Write-Host "Connecting to EXO, please enter Global administrator credentials when prompted!" -ForegroundColor Yellow Connect-ExchangeOnline -ErrorAction Stop - $CurrentDescription= "Connecting to EXO V2" + $CurrentDescription= "Connecting to EXO" $CurrentStatus = "Success" - LogError -CurrentStatus $CurrentStatus -Function "Connecting to EXO V2" -CurrentDescription $CurrentDescription - Write-Host "Connected to EXO V2 successfully" -ForegroundColor Cyan + logerror -CurrentStatus $CurrentStatus -Function "Connecting to EXO" -CurrentDescription $CurrentDescription + Write-Host "Connected to EXO successfully" -ForegroundColor Cyan } catch { - $ErrorEncountered=$Global:error[0].Exception - $CurrentDescription = "Connecting to EXO V2" + $Errorencountered=$Global:error[0].Exception + $CurrentDescription = "Connecting to EXO" $CurrentStatus = "Failure" - LogError -CurrentStatus $CurrentStatus -Function "Connecting to EXO V2" -CurrentDescription $CurrentDescription + logerror -CurrentStatus $CurrentStatus -Function "Connecting to EXO" -CurrentDescription $CurrentDescription Write-Host "Error encountered during executing the script!"-ForegroundColor Red - Write-Host $ErrorEncountered -ForegroundColor Red + Write-Host $Errorencountered -ForegroundColor Red Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 break } } +function ValidateDumpsterExistance { + param([PSCustomObject]$Publicfolder) + try { + $Publicfolderdumpster=Get-PublicFolder $Publicfolder.DumpsterEntryId -ErrorAction stop + $CurrentDescription = "Retrieving: $($Publicfolder.Identity) dumpster for diagnosing" + $CurrentStatus = "Success" + logerror -Function "Retrieve public folder $($Publicfolder.Identity) dumpster" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + return $Publicfolderdumpster + } catch { + $Issue="Public folder $($Publicfolder.Identity) Dumpster is not existing!" + $Fix="FIX --> Please raise a support request for microsoft including the report & logs folder" + WritetoScreenANDlog -Issue $Issue -Fix $Fix + $Errorencountered=$Global:error[0].Exception + $CurrentDescription = "Retrieving: $($Publicfolder.Identity) dumpster for diagnosing" + $CurrentStatus = "Failure with error: "+$Errorencountered + logerror -Function "Retrieve public folder $($Publicfolder.Identity) dumpster" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + AskForFeedback + QuitEXOSession + } +} function GetPublicFolderInfo { - param([String]$PFolder) - Write-Host "Retrieving PublicFolder information for diagnosing!,please wait as this might take awhile...." -ForegroundColor Yellow + param([String]$Pfolder) try { - $PublicFolder=Get-PublicFolder $PFolder -ErrorAction stop - $PublicFolderDumpster=Get-PublicFolder $PublicFolder.DumpsterEntryId -ErrorAction stop - $PublicFolderStats=Get-PublicFolderStatistics $PublicFolder.EntryId -ErrorAction stop - $PfMbx=Get-mailbox -PublicFolder $PublicFolder.ContentMailboxGuid.Guid - $PfMBXStats=Get-mailboxStatistics $PublicFolder.ContentMailboxGuid.Guid -ErrorAction stop + $Publicfolder=Get-PublicFolder $Pfolder -ErrorAction stop + Write-Host "Retrieving Publicfolder $($Publicfolder.Identity) information for diagnosing!,please wait as this might take awhile...." -ForegroundColor Yellow + $Publicfolderdumpster=ValidateDumpsterExistance($Publicfolder) + $Publicfolderstats=Get-PublicFolderStatistics $Publicfolder.EntryId -ErrorAction stop + $pfmbx=Get-mailbox -PublicFolder $Publicfolder.ContentMailboxGuid.Guid + $PfMBXstats=Get-mailboxStatistics $Publicfolder.ContentMailboxGuid.Guid -ErrorAction stop $IPM_SUBTREE=Get-PublicFolder \ -ErrorAction stop $NON_IPM_SUBTREE=Get-PublicFolder \NON_IPM_SUBTREE -ErrorAction stop $DUMPSTER_ROOT=Get-PublicFolder \NON_IPM_SUBTREE\DUMPSTER_ROOT -ErrorAction stop $OrganizationConfig =Get-OrganizationConfig -ErrorAction stop [Int64]$DefaultPublicFolderProhibitPostQuota=[Int64]$OrganizationConfig.DefaultPublicFolderProhibitPostQuota.Split("(")[1].split(" ")[0].Replace(",", "") [Int64]$DefaultPublicFolderIssueWarningQuota=[Int64]$OrganizationConfig.DefaultPublicFolderIssueWarningQuota.Split("(")[1].split(" ")[0].Replace(",", "") - [Int64]$PublicFolderSize=[Int64]$PublicFolderStats.TotalItemSize.Split("(")[1].split("")[0].replace(",", "")+[Int64]$PublicFolderStats.TotalDeletedItemSize.Split("(")[1].split("")[0].replace(",", "") + [Int64]$Publicfoldersize=[Int64]$Publicfolderstats.TotalItemSize.Split("(")[1].split(" ")[0].replace(",", "")+[Int64]$Publicfolderstats.TotaldeletedItemSize.Split("(")[1].split(" ")[0].replace(",", "") [PSCustomObject]$PublicFolderInfo=@{ - PublicFolder = $PublicFolder - PublicFolderDumpster = $PublicFolderDumpster - PfMbx = $PfMbx - PublicFolderStats = $PublicFolderStats - PfMBXStats = $PfMBXStats + Publicfolder = $Publicfolder + Publicfolderdumpster = $Publicfolderdumpster + pfmbx = $pfmbx + Publicfolderstats = $Publicfolderstats + PfMBXstats = $PfMBXstats IPM_SUBTREE = $IPM_SUBTREE NON_IPM_SUBTREE = $NON_IPM_SUBTREE DUMPSTER_ROOT = $DUMPSTER_ROOT - PublicFolderSize = $PublicFolderSize + Publicfoldersize = $Publicfoldersize DefaultPublicFolderProhibitPostQuota = $DefaultPublicFolderProhibitPostQuota DefaultPublicFolderIssueWarningQuota = $DefaultPublicFolderIssueWarningQuota } return $PublicFolderInfo - $CurrentDescription = "Retrieving: $($PublicFolder.identity) & its dumpster for diagnosing" + $CurrentDescription = "Retrieving: $($Publicfolder.identity) & its dumpster for diagnosing" $CurrentStatus = "Success" - LogError -Function "Retrieve public folder & its dumpster statistics" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + logerror -Function "Retrieve public folder & its dumpster statistics" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription } catch { - $ErrorEncountered=$Global:error[0].Exception - $CurrentDescription = "Retrieving: $($PFolder) & its dumpster for diagnosing" - $CurrentStatus = "Failure with error: "+$ErrorEncountered - LogError -Function "Retrieve public folder & its dumpster statistics" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + $Errorencountered=$Global:error[0].Exception + $CurrentDescription = "Retrieving: $($Publicfolder.Identity) & its dumpster for diagnosing" + $CurrentStatus = "Failure with error: "+$Errorencountered + logerror -Function "Retrieve public folder & its dumpster statistics" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription Write-Host "Error encountered during executing the script!"-ForegroundColor Red - Write-Host $ErrorEncountered -ForegroundColor Red - Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow - Start-Sleep -Seconds 3 - break + Write-Host $Errorencountered -ForegroundColor Red + QuitEXOSession #write log and exit function } } function ValidateContentMBXUniqueness { param([PSCustomObject]$PublicFolderInfo) - if ($PublicFolderInfo.PublicFolder.ContentMailboxGuid.Guid -ne $PublicFolderInfo.PublicFolderDumpster.ContentMailboxGuid.Guid) { + if ($PublicFolderInfo.Publicfolder.ContentMailboxGuid.Guid -ne $PublicFolderInfo.Publicfolderdumpster.ContentMailboxGuid.Guid) { ExtractLog($PublicFolderInfo) $Fix= "FIX --> Please raise a support request for microsoft including the report & logs folder" - $Issue="Public folder $($PublicFolder.Identity) & its dumpster doesn't have the same content public folder mailbox" - WriteToScreenAndLog -Issue $Issue -Fix $Fix + $Issue="Public folder $($Publicfolder.Identity) & its dumpster doesn't have the same content public folder mailbox" + WritetoScreenANDlog -Issue $Issue -Fix $Fix } } function ValidateEntryIDMapping { param([PSCustomObject]$PublicFolderInfo) - if ($PublicFolderInfo.PublicFolder.EntryId -ne $PublicFolderInfo.PublicFolderDumpster.DumpsterEntryID -or $PublicFolderInfo.PublicFolder.DumpsterEntryID -ne $PublicFolderInfo.PublicFolderDumpster.EntryId) { - if (!(Test-Path -Path "$ExportPath\logs_\PublicFolderInfo.xml")) { + if ($PublicFolderInfo.Publicfolder.EntryId -ne $PublicFolderInfo.Publicfolderdumpster.DumpsterEntryID -or $PublicFolderInfo.Publicfolder.DumpsterEntryID -ne $PublicFolderInfo.Publicfolderdumpster.EntryId) { + if (!(Test-Path -Path "$ExportPath\logs_$ts\PublicFolderInfo.xml")) { ExtractLog($PublicFolderInfo) } - $Issue="Public folder $($PublicFolder.Identity) EntryId & DumpsterEntryID values are not mapped properly" + $Issue="Public folder $($Publicfolder.Identity) EntryId & DumpsterEntryID values are not mapped properly" $Fix="FIX --> Please raise a support request for microsoft including the report & logs folder" - WriteToScreenAndLog -Issue $Issue -Fix $Fix + WritetoScreenANDlog -Issue $Issue -Fix $Fix } } function ValidateContentMBXQuota { param([PSCustomObject]$PublicFolderInfo) - [Int64]$PfMbxRecoverableItemsQuotaInB=[Int64]$PublicFolderInfo.PfMbx.RecoverableItemsQuota.Split("(")[1].split(" ")[0].Replace(",", "") - [Int64]$PfMBXStatsInB=[Int64]$PublicFolderInfo.PfMBXStats.TotalDeletedItemSize.Value.ToString().Split("(")[1].split(" ")[0].Replace(",", "") - if ($PfMBXStatsInB -ge $PfMbxRecoverableItemsQuotaInB ) { + [Int64]$pfmbxRecoverableItemsQuotainB=[Int64]$PublicFolderInfo.pfmbx.RecoverableItemsQuota.Split("(")[1].split(" ")[0].Replace(",", "") + [Int64]$PfMBXstatsinB=[Int64]$PublicFolderInfo.PfMBXstats.TotalDeletedItemSize.Value.tostring().Split("(")[1].split(" ")[0].Replace(",", "") + if ($PfMBXstatsinB -ge $pfmbxRecoverableItemsQuotainB ) { $article="https://aka.ms/PFrecovery" $RecoverDeletedItems="https://aka.ms/cannotdeleteitemsOWA" $Fix="FIX --> To resolve a scenario where content public folder mailbox TotalDeletedItemSize value has reached RecoverableItemsQuota value, users could manually clean up the dumpster using: ->Outlook $RecoverDeletedItems ->MFCMAPI please refer to the following $article to check steps related to get to public folder dumpster using MFCMAPI then select unrequired items to be purged permanently" - $Issue="Public folder mailbox $($PublicFolderInfo.PfMbx.name) TotalDeletedItemSize value has reached its RecoverableItemsQuota value" - WriteToScreenAndLog -Issue $Issue -Fix $Fix + $Issue="Public folder mailbox $($PublicFolderInfo.pfmbx.name) TotalDeletedItemSize value has reached its RecoverableItemsQuota value" + WritetoScreenANDlog -Issue $Issue -Fix $Fix } } function ValidateParentPublicFolder { param([PSCustomObject]$PublicFolderInfo) #Validate where is the removal taking place under IPM_Subtree or Non_IPM_Subtree depends on the pf identity e.g \pf1 - if ($PublicFolderInfo.PublicFolder.FolderPath.Contains("DUMPSTER_ROOT")) { + if ($PublicFolderInfo.Publicfolder.FolderPath.Contains("DUMPSTER_ROOT")) { #Validate till Non_Ipm_Subtree - if ($PublicFolderInfo.PublicFolder.ParentFolder -ne $PublicFolderInfo.NON_IPM_SUBTREE.EntryId) { - $ParentPublicFolderInfo=GetPublicFolderInfo($PublicFolderInfo.PublicFolder.ParentFolder) + if ($PublicFolderInfo.Publicfolder.ParentFolder -ne $PublicFolderInfo.NON_IPM_SUBTREE.EntryId) { + $ParentPublicFolderInfo=GetPublicFolderInfo($PublicFolderInfo.Publicfolder.ParentFolder) ValidateContentMBXUniqueness($ParentPublicFolderInfo) ValidateEntryIDMapping($ParentPublicFolderInfo) ValidateContentMBXQuota($ParentPublicFolderInfo) @@ -160,8 +178,8 @@ function ValidateParentPublicFolder { } #Validate on IPM_Subtree else { - if ($PublicFolderInfo.PublicFolder.ParentFolder -ne $PublicFolderInfo.IPM_SUBTREE.EntryId) { - $ParentPublicFolderInfo=GetPublicFolderInfo($PublicFolderInfo.PublicFolder.ParentFolder) + if (![string]::IsNullOrEmpty($PublicFolderInfo.Publicfolder.ParentFolder)) { + $ParentPublicFolderInfo=GetPublicFolderInfo($PublicFolderInfo.Publicfolder.ParentFolder) ValidateContentMBXUniqueness($ParentPublicFolderInfo) ValidateEntryIDMapping($ParentPublicFolderInfo) ValidateContentMBXQuota($ParentPublicFolderInfo) @@ -171,18 +189,20 @@ function ValidateParentPublicFolder { } function ValidateDumpsterFlag { param([PSCustomObject]$PublicFolderInfo) - if ($PublicFolderInfo.PublicFolder.AdminFolderFlags -eq "DumpsterFolder") { - $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) is a dumpster folder, content folder and its dumpster are linked to each other, that link cannot be undone, in other words admins cannot delete dumpster only" - $Fix="FIX --> Please move $($PublicFolderInfo.PublicFolder.Identity) public folder to be under NON_IPM_SUBTREE using Set-PublicFolder command, for more information please check https://aka.ms/setpf" - WriteToScreenAndLog -Issue $Issue -Fix $Fix + if ($PublicFolderInfo.Publicfolder.AdminFolderFlags -eq "DumpsterFolder") { + $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) is a dumpster folder, content folder and its dumpster are linked to each other, that link cannot be undone, in other words admins cannot delete dumpster only" + $Fix="FIX --> Please move $($PublicFolderInfo.Publicfolder.Identity) public folder to be under NON_IPM_SUBTREE using Set-PublicFolder command, for more information please check https://aka.ms/setpf" + WritetoScreenANDlog -Issue $Issue -Fix $Fix + AskForFeedback + QuitEXOSession } } function GetUserPermissions { param([PSCustomObject]$Perms) - $workingPermissions=@("Editor", "Owner", "PublishingEditor", "DeleteAllItems").ToLower() + $workingpermissions=@("editor", "owner", "publishingeditor", "deleteallitems") if ($null -ne $Perms) { foreach ($perm in $Perms.AccessRights) { - if ($workingPermissions.Contains($($perm.ToLower()))) { + if ($workingpermissions.Contains($($perm.ToLower()))) { return "user has permission" } } @@ -194,10 +214,10 @@ function GetUserPermissions { } } function ValidateUserPermissions { - param([PSCustomObject]$Perms, [PSCustomObject]$PermsUserPfMbx) - if ($Perms.AccessRights.count -eq $PermsUserPfMbx.AccessRights.count) { + param([PSCustomObject]$Perms, [PSCustomObject]$Permsuserpfmbx) + if ($Perms.AccessRights.count -eq $Permsuserpfmbx.AccessRights.count) { foreach ($Perm in $perms.AccessRights) { - if (!$PermsUserPfMbx.AccessRights.contains($Perm)) { + if (!$Permsuserpfmbx.AccessRights.contains($Perm)) { return "sync issue exist" } } @@ -209,80 +229,92 @@ function ValidatePublicFolderIssue { param([Parameter(Mandatory = $true)] [PSCustomObject]$PublicFolderInfo, [Parameter(Mandatory = $false)] - [string]$AffectedUser) - #validate explicit permission & default permission if item + [string]$Affecteduser) + #validate explict permission & default permission if item try { - $User=Get-Mailbox $AffectedUser -ErrorAction stop - $UserPfMbx=Get-mailbox -PublicFolder $($User.EffectivePublicFolderMailbox) -ErrorAction stop - $ExplicitPerms=Get-PublicFolderClientPermission $PublicFolderInfo.PublicFolder.EntryId -User $User.Guid.Guid.ToString() -ErrorAction SilentlyContinue - $DefaultPerms=Get-PublicFolderClientPermission $PublicFolderInfo.PublicFolder.EntryId -User Default -ErrorAction SilentlyContinue + $User=Get-Mailbox $Affecteduser -ErrorAction stop + $Userpfmbx=Get-mailbox -PublicFolder $($User.EffectivePublicFolderMailbox) -ErrorAction stop + $Explicitperms=Get-PublicFolderClientPermission $PublicFolderInfo.Publicfolder.EntryId -User $User.Guid.Guid.tostring() -ErrorAction SilentlyContinue + $Defaultperms=Get-PublicFolderClientPermission $PublicFolderInfo.Publicfolder.EntryId -User Default -ErrorAction SilentlyContinue #Validate if there's no perm sync issue - $ExplicitPermsUserPfMbx=Get-PublicFolderClientPermission $PublicFolderInfo.PublicFolder.Identity -User $User.Guid.Guid.ToString() -ErrorAction SilentlyContinue -Mailbox $userPfMbx.ExchangeGuid.Guid - $DefaultPermsUserPfMbx=Get-PublicFolderClientPermission $PublicFolderInfo.PublicFolder.Identity -User Default -ErrorAction SilentlyContinue -Mailbox $userPfMbx.ExchangeGuid.Guid - $UserPermSyncIssue=ValidateUserPermissions -PermsUserPfMbx $ExplicitPermsUserPfMbx -Perms $ExplicitPerms - $DefaultUserPermSyncIssue=ValidateUserPermissions -PermsUserPfMbx $DefaultPermsUserPfMbx -Perms $DefaultPerms - $ExplicitPermsResult=GetUserPermissions($ExplicitPerms) - $DefaultPermsResult=GetUserPermissions($DefaultPerms) - if ($UserPermSyncIssue -eq "sync issue exist") { - #explicitUser sync perm issue + $Explicitpermsuserpfmbx=Get-PublicFolderClientPermission $PublicFolderInfo.Publicfolder.Identity -User $User.Guid.Guid.tostring() -ErrorAction SilentlyContinue -Mailbox $userpfmbx.ExchangeGuid.Guid + $Defaultpermsuserpfmbx=Get-PublicFolderClientPermission $PublicFolderInfo.Publicfolder.Identity -User Default -ErrorAction SilentlyContinue -Mailbox $userpfmbx.ExchangeGuid.Guid + $Userpermsyncissue=ValidateUserPermissions -Permsuserpfmbx $Explicitpermsuserpfmbx -Perms $Explicitperms + $Defaultuserpermsyncissue=ValidateUserPermissions -Permsuserpfmbx $Defaultpermsuserpfmbx -Perms $Defaultperms + $Explicitpermsresult=GetUserPermissions($Explicitperms) + $Defaultpermsresult=GetUserPermissions($Defaultperms) + if ($Userpermsyncissue -eq "sync issue exist") { + #explicituser sync perm issue #validate that user has sufficient perms - if ($ExplicitPermsResult -match "user has no permission") { + if ($Explicitpermsresult -match "user has no permission") { #user has no sufficient perm $FIX="FIX --> Please ensure that user $($User.PrimarySmtpAddress) has sufficient permissions to delete, for more information please check the following article https://aka.ms/addPFperm" - $Issue="$($User.PrimarySmtpAddress) have no sufficient permissions to delete items inside $($PublicFolderInfo.PublicFolder.identity)" - WriteToScreenAndLog -Issue $Issue -Fix $fix + $Issue="$($User.PrimarySmtpAddress) have no sufficient permissions to delete items inside $($PublicFolderInfo.publicfolder.identity)" + WritetoScreenANDlog -Issue $Issue -Fix $fix } #user has sufficient perm $FIX="FIX --> Please ensure that user $($User.PrimarySmtpAddress) permissions are synced properly over his EffectivePublicFolderMailbox $($User.EffectivePublicFolderMailbox), for more information please check the following article https://aka.ms/Fixpfpermissue" $Issue="$($User.PrimarySmtpAddress) has permissions sync problems over EffectivePublicFolderMailbox $($User.EffectivePublicFolderMailbox)!" - WriteToScreenAndLog -Issue $Issue -Fix $fix + WritetoScreenANDlog -Issue $Issue -Fix $fix } - if ($DefaultUserPermSyncIssue -eq "sync issue exist" -and $ExplicitPermsResult -match "user has no permission") { - #DefaultUser sync perm issue + if ($Defaultuserpermsyncissue -eq "sync issue exist" ) { + #Defaultuser sync perm issue #validate that Default has sufficient perms - if ($DefaultPermsResult -match "user has no permission") { + if ($Defaultpermsresult -match "user has no permission" -and $Explicitpermsresult -match "user has no permission") { #Default user has no sufficient perm $FIX="FIX --> Please ensure that either $($User.PrimarySmtpAddress) or Default user has sufficient permissions to delete, for more information please check the following article https://aka.ms/addPFperm" - $Issue="Neither $($User.PrimarySmtpAddress) nor Default user have sufficient permissions to delete items inside $($PublicFolderInfo.PublicFolder.identity)" - WriteToScreenAndLog -Issue $Issue -Fix $fix + $Issue="Neither $($User.PrimarySmtpAddress) nor Default user have sufficient permissions to delete items inside $($PublicFolderInfo.publicfolder.identity)" + WritetoScreenANDlog -Issue $Issue -Fix $fix } #Default user has sufficient perm - $FIX="FIX --> Please ensure that Default user permissions are synced properly over user EffectivePublicFolderMailbox $($User.EffectivePublicFolderMailbox), for more information please check the following article https://aka.ms/Fixpfpermissue" - $Issue="Default user has permissions sync problems over user EffectivePublicFolderMailbox $($User.EffectivePublicFolderMailbox)!" - WriteToScreenAndLog -Issue $Issue -Fix $fix + if ($Defaultpermsresult -match "user has permission" -and $Explicitpermsresult -match "user has no permission") { + $FIX="FIX --> Please ensure that Default user permissions are synced properly over user EffectivePublicFolderMailbox $($User.EffectivePublicFolderMailbox), for more information please check the following article https://aka.ms/Fixpfpermissue" + $Issue="Default user has permissions sync problems over user EffectivePublicFolderMailbox $($User.EffectivePublicFolderMailbox)!" + WritetoScreenANDlog -Issue $Issue -Fix $fix + $FIX="FIX --> Please ensure that user $($User.PrimarySmtpAddress) has sufficient permissions to delete, for more information please check the following article https://aka.ms/addPFperm" + $Issue="$($User.PrimarySmtpAddress) have no sufficient permissions to delete items inside $($PublicFolderInfo.publicfolder.identity)" + WritetoScreenANDlog -Issue $Issue -Fix $fix + } + if ($Defaultpermsresult -match "user has permission" -and $Explicitpermsresult -match "user has permission") { + $FIX="FIX --> Please re-grant user $($User.PrimarySmtpAddress) permissions over the affected public folder, for more information please check the following articles https://aka.ms/removePFperm, https://aka.ms/addPFperm" + $Issue="$($User.PrimarySmtpAddress) user has corrupted permission over public folder $($PublicFolderInfo.publicfolder.identity)" + WritetoScreenANDlog -Issue $Issue -Fix $fix + } + if ($Defaultpermsresult -match "user has no permission" -and $Explicitpermsresult -match "user has permission") { + $FIX="FIX --> Please re-grant user $($User.PrimarySmtpAddress) permissions over the affected public folder, for more information please check the following articles https://aka.ms/removePFperm, https://aka.ms/addPFperm" + $Issue="$($User.PrimarySmtpAddress) user has corrupted permission over public folder $($PublicFolderInfo.publicfolder.identity)" + WritetoScreenANDlog -Issue $Issue -Fix $fix + } } - if ($UserPermSyncIssue -eq "no sync issue exist" -or $DefaultUserPermSyncIssue -eq "no sync issue exist") { - #No sync issue found + if ($Userpermsyncissue -eq "no sync issue exist" -and $Defaultuserpermsyncissue -eq "no sync issue exist") { + if ($Explicitpermsresult -match "user has no permission" -and $Defaultpermsresult -match "user has no permission") { + #user has no permission to delete + $FIX="FIX --> Please ensure that user $($User.PrimarySmtpAddress) has sufficient permissions to delete, for more information please check the following article https://aka.ms/addPFperm" + $Issue="Neither $($User.PrimarySmtpAddress) nor Default user have sufficient permissions to delete items inside $($PublicFolderInfo.publicfolder.identity)" + WritetoScreenANDlog -Issue $Issue -Fix $fix + } #if Default/user has sufficient permission might be perm is corrupted, we might need to re-add default/user permission again - if ($ExplicitPermsResult -match "user has permission") { + if ($Explicitpermsresult -match "user has permission") { #user has sufficient permission to delete but might be corrupted acl $FIX="FIX --> Please re-grant user $($User.PrimarySmtpAddress) permissions over the affected public folder, for more information please check the following articles https://aka.ms/removePFperm, https://aka.ms/addPFperm" - $Issue="$($User.PrimarySmtpAddress) user has corrupted permission over public folder $($PublicFolderInfo.PublicFolder.identity)" - WriteToScreenAndLog -Issue $Issue -Fix $fix + $Issue="$($User.PrimarySmtpAddress) user has corrupted permission over public folder $($PublicFolderInfo.publicfolder.identity)" + WritetoScreenANDlog -Issue $Issue -Fix $fix } - if ($DefaultPermsResult -match "user has permission" -and $ExplicitPermsResult -match "user has no permission") { + if ($Defaultpermsresult -match "user has permission" -and $Explicitpermsresult -match "user has no permission") { #user has sufficient permission to delete but might be corrupted acl $FIX="FIX --> Please re-grant Default user permissions over the affected public folder or add the permission for the affected user explicitly, for more information please check the following articles https://aka.ms/removePFperm, https://aka.ms/addPFperm" - $Issue="Default user has corrupted permission over public folder $($PublicFolderInfo.PublicFolder.identity)" - WriteToScreenAndLog -Issue $Issue -Fix $fix - } - } - if ($UserPermSyncIssue -eq "no sync issue exist" -and $DefaultUserPermSyncIssue -eq "no sync issue exist") { - if ($ExplicitPermsResult -match "user has no permission" -and $DefaultPermsResult -match "user has no permission") { - #user has no permission to delete - $FIX="FIX --> Please ensure that user $($User.PrimarySmtpAddress) has sufficient permissions to delete, for more information please check the following article https://aka.ms/addPFperm" - $Issue="Neither $($User.PrimarySmtpAddress) nor Default user have sufficient permissions to delete items inside $($PublicFolderInfo.PublicFolder.identity)" - WriteToScreenAndLog -Issue $Issue -Fix $fix + $Issue="Default user has corrupted permission over public folder $($PublicFolderInfo.publicfolder.identity)" + WritetoScreenANDlog -Issue $Issue -Fix $fix } } } catch { #log the error and quit - $ErrorEncountered=$Global:error[0].Exception + $Errorencountered=$Global:error[0].Exception $CurrentDescription = "Validating if user has sufficient permissions to delete" - $CurrentStatus = "Failure with error: "+$ErrorEncountered - LogError -Function "Validate user permissions" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + $CurrentStatus = "Failure with error: "+$Errorencountered + logerror -Function "Validate user permissions" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription Write-Host "Error encountered during executing the script!"-ForegroundColor Red - Write-Host $ErrorEncountered -ForegroundColor Red + Write-Host $Errorencountered -ForegroundColor Red Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 break @@ -292,32 +324,32 @@ function ValidatePublicFolderIssue { function ValidatePublicFolderQuota { param([PSCustomObject]$PublicFolderInfo) #Validate if DefaultPublicFolderProhibitPostQuota at the organization level applies - if ($PublicFolderInfo.PublicFolder.ProhibitPostQuota -eq "unlimited") { + if ($PublicFolderInfo.Publicfolder.ProhibitPostQuota -eq "unlimited") { #Checking if public folder total size has reached organization public folder DefaultPublicFolderProhibitPostQuota value!" - if ($PublicFolderInfo.PublicFolderSize -ge $PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) { + if ($PublicFolderInfo.Publicfoldersize -ge $PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) { #validate if Giant PF to lower the PF size down else increase Org DefaultPublicFolderProhibitPostQuota if ($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota -ge 21474836480) { - $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to avoid having Giant public folders with sizes exceeding 20GB, then delete or move items from that giant folder $($PublicFolderInfo.PublicFolder.Identity) to reduce the size of that public folder to an appropriate size accommodating with newly modified organization values." - $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) size has exceeded Organization DefaultPublicFolderProhibitPostQuota value!" - WriteToScreenAndLog -Issue $Issue -Fix $Fix + $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to avoid having Giant public folders with sizes exceeding 20GB, then delete or move items from that giant folder $($PublicFolderInfo.Publicfolder.Identity) to reduce the size of that public folder to an appropriate size accomadating with newly modified organization values." + $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) size has exceeded Organization DefaultPublicFolderProhibitPostQuota value!" + WritetoScreenANDlog -Issue $Issue -Fix $Fix } else { - $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to accommodate the public folder $($PublicFolderInfo.PublicFolder.Identity) size:$($PublicFolderInfo.PublicFolderSize) Bytes" - $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) size has exceeded Organization DefaultPublicFolderProhibitPostQuota value!" - WriteToScreenAndLog -Issue $Issue -Fix $Fix + $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to accomodate the public folder $($PublicFolderInfo.Publicfolder.Identity) size:$($PublicFolderInfo.Publicfoldersize) Bytes" + $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) size has exceeded Organization DefaultPublicFolderProhibitPostQuota value!" + WritetoScreenANDlog -Issue $Issue -Fix $Fix } } } else { - [Int64]$PFProhibitPostQuota=[Int64]$PublicFolderInfo.PublicFolder.ProhibitPostQuota.split("(")[1].split(" ")[0].replace(",", "") - if ($PublicFolderInfo.PublicFolderSize -ge $PFProhibitPostQuota) { - #validate if Giant PF to lower the PF size down else increase PFProhibitPostQuota or inherit Org DefaultPublicFolderProhibitPostQuota + [Int64]$PFProhibitPostQuota=[Int64]$PublicFolderInfo.Publicfolder.ProhibitPostQuota.split("(")[1].split(" ")[0].replace(",", "") + if ($PublicFolderInfo.Publicfoldersize -ge $PFProhibitPostQuota) { + #validate if Giant PF to lower the PF size down else increase PFProhibitPostQuota or inhertit Org DefaultPublicFolderProhibitPostQuota if ($PFProhibitPostQuota -ge 21474836480) { - $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to avoid having Giant public folders with sizes exceeding 20GB, then delete or move items from that giant folder $($PublicFolderInfo.PublicFolder.Identity) to reduce the size of that public folder to an appropriate size accommodating with newly modified organization values." - $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) size has exceeded Individual Public Folder ProhibitPostQuota value" - WriteToScreenAndLog -Issue $Issue -Fix $Fix + $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to avoid having Giant public folders with sizes exceeding 20GB, then delete or move items from that giant folder $($PublicFolderInfo.Publicfolder.Identity) to reduce the size of that public folder to an appropriate size accomadating with newly modified organization values." + $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) size has exceeded Individual Public Folder ProhibitPostQuota value" + WritetoScreenANDlog -Issue $Issue -Fix $Fix } else { - $Fix= "FIX --> Please follow the following article https://aka.ms/setpf to modify the Public Folder ProhibitPostQuota:$PFProhibitPostQuota Bytes value to accommodate the public folder $($PublicFolderInfo.PublicFolder.Identity) size:$($PublicFolderInfo.PublicFolderSize) Bytes" - $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) size has exceeded Individual Public Folder ProhibitPostQuota value" - WriteToScreenAndLog -Issue $Issue -Fix $Fix + $Fix= "FIX --> Please follow the following article https://aka.ms/setpf to modify the Public Folder ProhibitPostQuota:$PFProhibitPostQuota Bytes value to accomodate the public folder $($PublicFolderInfo.Publicfolder.Identity) size:$($PublicFolderInfo.Publicfoldersize) Bytes" + $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) size has exceeded Individual Public Folder ProhibitPostQuota value" + WritetoScreenANDlog -Issue $Issue -Fix $Fix } } } @@ -325,36 +357,36 @@ function ValidatePublicFolderQuota { function ValidateDumpsterChildren { param([PSCustomObject]$PublicFolderInfo) try { - $HasChildren= Get-PublicFolder $PublicFolderInfo.PublicFolderDumpster.EntryId -ErrorAction stop -GetChildren - $CurrentDescription = "Validating if dumpster folder:$($PublicFolderInfo.PublicFolderDumpster.EntryId)" + $Haschildren= Get-PublicFolder $PublicFolderInfo.Publicfolderdumpster.EntryId -ErrorAction stop -GetChildren + $CurrentDescription = "Validating if dumpster folder:$($PublicFolderInfo.Publicfolderdumpster.EntryId) has children" $CurrentStatus = "Success" - LogError -Function "Validate if dumpster folder has children" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + logerror -Function "Validate if dumpster folder has children" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription } catch { - $ErrorEncountered=$Global:error[0].Exception - $CurrentDescription = "Validating if dumpster folder:$($PublicFolderInfo.PublicFolderDumpster.EntryId) has children" - $CurrentStatus = "Failure with error: "+$ErrorEncountered - LogError -Function "Validate if dumpster folder has children" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + $Errorencountered=$Global:error[0].Exception + $CurrentDescription = "Validating if dumpster folder:$($PublicFolderInfo.Publicfolderdumpster.EntryId) has children" + $CurrentStatus = "Failure with error: "+$Errorencountered + logerror -Function "Validate if dumpster folder has children" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription Write-Host "Error encountered during executing the script!"-ForegroundColor Red - Write-Host $ErrorEncountered -ForegroundColor Red + Write-Host $Errorencountered -ForegroundColor Red Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 break } - if ($null -ne $HasChildren) { - $Fix= "FIX --> Please follow the following article https://aka.ms/setpf to move $($PublicFolderInfo.PublicFolder.Identity) dumpster children found to under NON_IPM_SUBTREE scope e.g. \NON_IPM_SUBTREE\DUMPSTER_ROOT\DUMPSTER_EXTEND\RESERVED_1\RESERVED_1" - $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) dumpster has $($HasChildren.Name.count) subfolder(s) which is a blocker for deletion operations over the public folder!`nDumpster subfolder(s) found:`n----------------------------`n$($HasChildren.identity)" - WriteToScreenAndLog -Issue $Issue -Fix $Fix + if ($null -ne $Haschildren) { + $Fix= "FIX --> Please follow the following article https://aka.ms/setpf to move $($PublicFolderInfo.Publicfolder.Identity) dumpster children found to under NON_IPM_SUBTREE scope e.g. \NON_IPM_SUBTREE\DUMPSTER_ROOT\DUMPSTER_EXTEND\RESERVED_1\RESERVED_1" + $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) dumpster has $($Haschildren.Name.count) subfolder(s) which is a blocker for deletion operations over the public folder!`nDumpster subfolder(s) found:`n----------------------------`n$($Haschildren.identity)" + WritetoScreenANDlog -Issue $Issue -Fix $Fix } } -function ValidateMEPfGuid { +function ValidateMEPFGuid { param([PSCustomObject]$PublicFolderInfo) #validate if MailRecipientGuid parameter is found empty/null - if ($PublicFolderInfo.PublicFolder.MailEnabled -eq $true) { - $HasValue=$PublicFolderInfo.PublicFolder.MailRecipientGuid.Guid - if ($null -eq $HasValue -or $HasValue -eq "00000000-0000-0000-0000-000000000000") { + if ($PublicFolderInfo.Publicfolder.MailEnabled -eq $true) { + $Hasvalue=$PublicFolderInfo.Publicfolder.MailRecipientGuid.Guid + if ($null -eq $Hasvalue -or $Hasvalue -eq "00000000-0000-0000-0000-000000000000") { $Fix= "FIX --> Please follow the following article https://aka.ms/EnableMPF to mail enable the affected public folder to generate a GUID over MailRecipientGuid parameter, validate MailRecipientGuid parameter has a GUID using https://aka.ms/getpf article then mail disable the affected public folder back again using https://aka.ms/disablempf article to be able to remove the public folder as requested." - $Issue="Mail-enabled public folder $($PublicFolderInfo.PublicFolder.Identity) is unhealthy e.g MailRecipientGuid parameter is found empty/null which is a blocker for deletion operations over the public folder" - WriteToScreenAndLog -Issue $Issue -Fix $Fix + $Issue="Mail-enabled public folder $($PublicFolderInfo.Publicfolder.Identity) is unhealthy e.g MailRecipientGuid parameter is found empty/null which is a blocker for deletion operations over the public folder" + WritetoScreenANDlogDlog -Issue $Issue -Fix $Fix } } } @@ -364,7 +396,35 @@ function ExtractLog { if (!(Test-Path "$ExportPath\logs_$ts")) { mkdir "$ExportPath\logs_$ts" -Force | Out-Null } - $PublicFolderInfo | Export-Clixml -Path "$ExportPath\logs_$ts\PublicFolderInfo.xml" + $PublicFolderInfo | Export-Clixml -Path "$ExportPath\logs_$ts\PublicFolderInfo$($PublicFolderInfo.Publicfolder.Name).xml" +} +function AskForFeedback { + Write-Host "Please rate the script experience & tell us what you liked or what we can do better over https://aka.ms/PFDumpsterFeedback!" -ForegroundColor Cyan + "Please rate the script experience & tell us what you liked or what we can do better over https://aka.ms/PFDumpsterFeedback!" | Out-File $ExportPath\$Script:ReportName -Append +} +function QuitEXOSession { + if ($null -eq $Sessioncheck) { + try { + Write-Host "Quiting EXO PowerShell session..." -ForegroundColor Yellow + Disconnect-ExchangeOnline -ErrorAction Stop -Confirm:$false + $CurrentDescription= "Disconnecting from EXO" + $CurrentStatus = "Success" + logerror -CurrentStatus $CurrentStatus -Function "Disconnecting from EXO" -CurrentDescription $CurrentDescription + Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow + Start-Sleep -Seconds 3 + break + } catch { + $Errorencountered=$Global:error[0].Exception + $CurrentDescription = "Disconnecting from EXO" + $CurrentStatus = "Failure" + logerror -CurrentStatus $CurrentStatus -Function "Disconnecting from EXO" -CurrentDescription $CurrentDescription + Write-Host "Error encountered during executing the script!"-ForegroundColor Red + Write-Host $Errorencountered -ForegroundColor Red + Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow + Start-Sleep -Seconds 3 + break + } + } } #Intro $ts = Get-Date -Format yyyyMMdd_HHmmss @@ -381,57 +441,29 @@ if ($null -eq $ExportPath -or $ExportPath -eq "") { mkdir $ExportPath -Force | Out-Null } } - -[string]$Description = "This script illustrates issues related to deleting public folder items or removing the public folder on PublicFolder $PFolder, BLOCKERS will be reported down, please ensure to mitigate them!`n" +[string]$Description = "This script illustrates issues related to deleting public folder items or removing the public folder on Publicfolder $Pfolder, BLOCKERS will be reported down, please ensure to mitigate them!`n" Write-Host $Description -ForegroundColor Cyan $Description | Out-File $ExportPath\$Script:ReportName -Append - #Connect to EXO PS -$SessionCheck = Get-PSSession | Where-Object { $_.Name -like "*ExchangeOnline*" -and $_.State -match "opened" } -if ($null -eq $SessionCheck) { +$Sessioncheck = Get-PSSession | Where-Object { $_.Name -like "*Exchangeonline*" -and $_.State -match "opened" } +if ($null -eq $Sessioncheck) { Connect2EXO } - #Main Function -$PublicFolderInfo=GetPublicFolderInfo($PFolder) +$PublicFolderInfo=GetPublicFolderInfo($Pfolder) #if the issue is related to a user who is not able to delete an item inside a public folder -if (![string]::IsNullOrEmpty($AffectedUser)) { - ValidatePublicFolderIssue -PublicFolderInfo $PublicFolderInfo -AffectedUser $AffectedUser +if (![string]::IsNullOrEmpty($Affecteduser)) { + ValidatePublicFolderIssue -PublicFolderInfo $PublicFolderInfo -Affecteduser $Affecteduser } +ValidateDumpsterFlag($PublicFolderInfo) ValidateContentMBXUniqueness($PublicFolderInfo) ValidateEntryIDMapping($PublicFolderInfo) ValidateContentMBXQuota($PublicFolderInfo) ValidatePublicFolderQuota($PublicFolderInfo) -ValidateDumpsterFlag($PublicFolderInfo) ValidateDumpsterChildren($PublicFolderInfo) -ValidateMEPfGuid($PublicFolderInfo) +ValidateMEPFGuid($PublicFolderInfo) ValidateParentPublicFolder($PublicFolderInfo) - -#Ask for feedback -Write-Host "Please rate the script experience & tell us what you liked or what we can do better over https://aka.ms/PFDumpsterFeedback!" -ForegroundColor Cyan -"Please rate the script experience & tell us what you liked or what we can do better over https://aka.ms/PFDumpsterFeedback!" | Out-File $ExportPath\$Script:ReportName -Append - -#Quit EXO session - -if ($null -eq $SessionCheck) { - try { - Write-Host "Quitting EXO PowerShell session..." -ForegroundColor Yellow - Disconnect-ExchangeOnline -ErrorAction Stop -Confirm:$false - $CurrentDescription= "Disconnecting from EXO V2" - $CurrentStatus = "Success" - LogError -CurrentStatus $CurrentStatus -Function "Disconnecting from EXO V2" -CurrentDescription $CurrentDescription - } catch { - $ErrorEncountered=$Global:error[0].Exception - $CurrentDescription = "Disconnecting from EXO V2" - $CurrentStatus = "Failure" - LogError -CurrentStatus $CurrentStatus -Function "Disconnecting from EXO V2" -CurrentDescription $CurrentDescription - Write-Host "Error encountered during executing the script!"-ForegroundColor Red - Write-Host $ErrorEncountered -ForegroundColor Red - Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow - Start-Sleep -Seconds 3 - break - } -} +AskForFeedback +QuitEXOSession # End of the Diag -Write-Host "`nLog file was exported in the following location: $ExportPath" -ForegroundColor Yellow -Start-Sleep -Seconds 3 + From f96b7e9170fff25186638e65a1cd7194aef6ffa7 Mon Sep 17 00:00:00 2001 From: hazemembaby <71065889+hazemembaby@users.noreply.github.com> Date: Sun, 11 Jun 2023 17:57:00 +0300 Subject: [PATCH 2/6] modify script to comply with CSpellCheck --- PublicFolders/ValidateEXOPFDumpster.ps1 | 326 ++++++++++++------------ 1 file changed, 163 insertions(+), 163 deletions(-) diff --git a/PublicFolders/ValidateEXOPFDumpster.ps1 b/PublicFolders/ValidateEXOPFDumpster.ps1 index cf9aa1b766..496c0d1e1c 100644 --- a/PublicFolders/ValidateEXOPFDumpster.ps1 +++ b/PublicFolders/ValidateEXOPFDumpster.ps1 @@ -4,12 +4,12 @@ param( [Parameter(Mandatory = $false)] [String]$ExportPath, [Parameter(Mandatory = $true)] - [String]$Pfolder, + [String]$PFolder, [Parameter(Mandatory = $false)] - [String]$Affecteduser) + [String]$AffectedUser) $Script:ReportName = "ValidatePFDumpsterREPORT.txt" #Requires -Modules @{ModuleName="ExchangeOnlineManagement"; ModuleVersion="3.0.0" } -function logerror { +function LogError { param( [Parameter(Mandatory = $true)] [string]$CurrentStatus, @@ -25,9 +25,9 @@ function logerror { Function = $Function Description = $CurrentDescription Status = $CurrentStatus - } | Export-Csv $ExportPath\ValidatePFDumpsterCheckslogging.csv -NoTypeInformation -Append + } | Export-Csv $ExportPath\ValidatePFDumpsterChecksLogging.csv -NoTypeInformation -Append } -function WritetoScreenANDlog { +function WriteToScreenAndLog { param( [Parameter(Mandatory = $true)] [String]$Issue, @@ -49,127 +49,127 @@ function Connect2EXO { Connect-ExchangeOnline -ErrorAction Stop $CurrentDescription= "Connecting to EXO" $CurrentStatus = "Success" - logerror -CurrentStatus $CurrentStatus -Function "Connecting to EXO" -CurrentDescription $CurrentDescription + LogError -CurrentStatus $CurrentStatus -Function "Connecting to EXO" -CurrentDescription $CurrentDescription Write-Host "Connected to EXO successfully" -ForegroundColor Cyan } catch { - $Errorencountered=$Global:error[0].Exception + $ErrorEncountered=$Global:error[0].Exception $CurrentDescription = "Connecting to EXO" $CurrentStatus = "Failure" - logerror -CurrentStatus $CurrentStatus -Function "Connecting to EXO" -CurrentDescription $CurrentDescription + LogError -CurrentStatus $CurrentStatus -Function "Connecting to EXO" -CurrentDescription $CurrentDescription Write-Host "Error encountered during executing the script!"-ForegroundColor Red - Write-Host $Errorencountered -ForegroundColor Red + Write-Host $ErrorEncountered -ForegroundColor Red Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 break } } -function ValidateDumpsterExistance { - param([PSCustomObject]$Publicfolder) +function ValidateDumpsterExistence { + param([PSCustomObject]$PublicFolder) try { - $Publicfolderdumpster=Get-PublicFolder $Publicfolder.DumpsterEntryId -ErrorAction stop - $CurrentDescription = "Retrieving: $($Publicfolder.Identity) dumpster for diagnosing" + $PublicFolderDumpster=Get-PublicFolder $PublicFolder.DumpsterEntryId -ErrorAction stop + $CurrentDescription = "Retrieving: $($PublicFolder.Identity) dumpster for diagnosing" $CurrentStatus = "Success" - logerror -Function "Retrieve public folder $($Publicfolder.Identity) dumpster" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription - return $Publicfolderdumpster + LogError -Function "Retrieve public folder $($PublicFolder.Identity) dumpster" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + return $PublicFolderDumpster } catch { - $Issue="Public folder $($Publicfolder.Identity) Dumpster is not existing!" + $Issue="Public folder $($PublicFolder.Identity) Dumpster is not existing!" $Fix="FIX --> Please raise a support request for microsoft including the report & logs folder" - WritetoScreenANDlog -Issue $Issue -Fix $Fix - $Errorencountered=$Global:error[0].Exception - $CurrentDescription = "Retrieving: $($Publicfolder.Identity) dumpster for diagnosing" - $CurrentStatus = "Failure with error: "+$Errorencountered - logerror -Function "Retrieve public folder $($Publicfolder.Identity) dumpster" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + WriteToScreenAndLog -Issue $Issue -Fix $Fix + $ErrorEncountered=$Global:error[0].Exception + $CurrentDescription = "Retrieving: $($PublicFolder.Identity) dumpster for diagnosing" + $CurrentStatus = "Failure with error: "+$ErrorEncountered + LogError -Function "Retrieve public folder $($PublicFolder.Identity) dumpster" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription AskForFeedback QuitEXOSession } } function GetPublicFolderInfo { - param([String]$Pfolder) + param([String]$PFolder) try { - $Publicfolder=Get-PublicFolder $Pfolder -ErrorAction stop - Write-Host "Retrieving Publicfolder $($Publicfolder.Identity) information for diagnosing!,please wait as this might take awhile...." -ForegroundColor Yellow - $Publicfolderdumpster=ValidateDumpsterExistance($Publicfolder) - $Publicfolderstats=Get-PublicFolderStatistics $Publicfolder.EntryId -ErrorAction stop - $pfmbx=Get-mailbox -PublicFolder $Publicfolder.ContentMailboxGuid.Guid - $PfMBXstats=Get-mailboxStatistics $Publicfolder.ContentMailboxGuid.Guid -ErrorAction stop + $PublicFolder=Get-PublicFolder $PFolder -ErrorAction stop + Write-Host "Retrieving PublicFolder $($PublicFolder.Identity) information for diagnosing!,please wait as this might take awhile...." -ForegroundColor Yellow + $PublicFolderDumpster=ValidateDumpsterExistence($PublicFolder) + $PublicFolderStats=Get-PublicFolderStatistics $PublicFolder.EntryId -ErrorAction stop + $PfMbx=Get-mailbox -PublicFolder $PublicFolder.ContentMailboxGuid.Guid + $PfMbxStats=Get-mailboxStatistics $PublicFolder.ContentMailboxGuid.Guid -ErrorAction stop $IPM_SUBTREE=Get-PublicFolder \ -ErrorAction stop $NON_IPM_SUBTREE=Get-PublicFolder \NON_IPM_SUBTREE -ErrorAction stop $DUMPSTER_ROOT=Get-PublicFolder \NON_IPM_SUBTREE\DUMPSTER_ROOT -ErrorAction stop $OrganizationConfig =Get-OrganizationConfig -ErrorAction stop [Int64]$DefaultPublicFolderProhibitPostQuota=[Int64]$OrganizationConfig.DefaultPublicFolderProhibitPostQuota.Split("(")[1].split(" ")[0].Replace(",", "") [Int64]$DefaultPublicFolderIssueWarningQuota=[Int64]$OrganizationConfig.DefaultPublicFolderIssueWarningQuota.Split("(")[1].split(" ")[0].Replace(",", "") - [Int64]$Publicfoldersize=[Int64]$Publicfolderstats.TotalItemSize.Split("(")[1].split(" ")[0].replace(",", "")+[Int64]$Publicfolderstats.TotaldeletedItemSize.Split("(")[1].split(" ")[0].replace(",", "") + [Int64]$PublicFolderSize=[Int64]$PublicFolderStats.TotalItemSize.Split("(")[1].split(" ")[0].replace(",", "")+[Int64]$PublicFolderStats.TotalDeletedItemSize.Split("(")[1].split(" ")[0].replace(",", "") [PSCustomObject]$PublicFolderInfo=@{ - Publicfolder = $Publicfolder - Publicfolderdumpster = $Publicfolderdumpster - pfmbx = $pfmbx - Publicfolderstats = $Publicfolderstats - PfMBXstats = $PfMBXstats + PublicFolder = $PublicFolder + PublicFolderDumpster = $PublicFolderDumpster + PfMbx = $PfMbx + PublicFolderStats = $PublicFolderStats + PfMbxStats = $PfMbxStats IPM_SUBTREE = $IPM_SUBTREE NON_IPM_SUBTREE = $NON_IPM_SUBTREE DUMPSTER_ROOT = $DUMPSTER_ROOT - Publicfoldersize = $Publicfoldersize + PublicFolderSize = $PublicFolderSize DefaultPublicFolderProhibitPostQuota = $DefaultPublicFolderProhibitPostQuota DefaultPublicFolderIssueWarningQuota = $DefaultPublicFolderIssueWarningQuota } return $PublicFolderInfo - $CurrentDescription = "Retrieving: $($Publicfolder.identity) & its dumpster for diagnosing" + $CurrentDescription = "Retrieving: $($PublicFolder.identity) & its dumpster for diagnosing" $CurrentStatus = "Success" - logerror -Function "Retrieve public folder & its dumpster statistics" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + LogError -Function "Retrieve public folder & its dumpster statistics" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription } catch { - $Errorencountered=$Global:error[0].Exception - $CurrentDescription = "Retrieving: $($Publicfolder.Identity) & its dumpster for diagnosing" - $CurrentStatus = "Failure with error: "+$Errorencountered - logerror -Function "Retrieve public folder & its dumpster statistics" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + $ErrorEncountered=$Global:error[0].Exception + $CurrentDescription = "Retrieving: $($PublicFolder.Identity) & its dumpster for diagnosing" + $CurrentStatus = "Failure with error: "+$ErrorEncountered + LogError -Function "Retrieve public folder & its dumpster statistics" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription Write-Host "Error encountered during executing the script!"-ForegroundColor Red - Write-Host $Errorencountered -ForegroundColor Red + Write-Host $ErrorEncountered -ForegroundColor Red QuitEXOSession #write log and exit function } } function ValidateContentMBXUniqueness { param([PSCustomObject]$PublicFolderInfo) - if ($PublicFolderInfo.Publicfolder.ContentMailboxGuid.Guid -ne $PublicFolderInfo.Publicfolderdumpster.ContentMailboxGuid.Guid) { + if ($PublicFolderInfo.PublicFolder.ContentMailboxGuid.Guid -ne $PublicFolderInfo.PublicFolderDumpster.ContentMailboxGuid.Guid) { ExtractLog($PublicFolderInfo) $Fix= "FIX --> Please raise a support request for microsoft including the report & logs folder" - $Issue="Public folder $($Publicfolder.Identity) & its dumpster doesn't have the same content public folder mailbox" - WritetoScreenANDlog -Issue $Issue -Fix $Fix + $Issue="Public folder $($PublicFolder.Identity) & its dumpster doesn't have the same content public folder mailbox" + WriteToScreenAndLog -Issue $Issue -Fix $Fix } } function ValidateEntryIDMapping { param([PSCustomObject]$PublicFolderInfo) - if ($PublicFolderInfo.Publicfolder.EntryId -ne $PublicFolderInfo.Publicfolderdumpster.DumpsterEntryID -or $PublicFolderInfo.Publicfolder.DumpsterEntryID -ne $PublicFolderInfo.Publicfolderdumpster.EntryId) { + if ($PublicFolderInfo.PublicFolder.EntryId -ne $PublicFolderInfo.PublicFolderDumpster.DumpsterEntryID -or $PublicFolderInfo.PublicFolder.DumpsterEntryID -ne $PublicFolderInfo.PublicFolderDumpster.EntryId) { if (!(Test-Path -Path "$ExportPath\logs_$ts\PublicFolderInfo.xml")) { ExtractLog($PublicFolderInfo) } - $Issue="Public folder $($Publicfolder.Identity) EntryId & DumpsterEntryID values are not mapped properly" + $Issue="Public folder $($PublicFolder.Identity) EntryId & DumpsterEntryID values are not mapped properly" $Fix="FIX --> Please raise a support request for microsoft including the report & logs folder" - WritetoScreenANDlog -Issue $Issue -Fix $Fix + WriteToScreenAndLog -Issue $Issue -Fix $Fix } } function ValidateContentMBXQuota { param([PSCustomObject]$PublicFolderInfo) - [Int64]$pfmbxRecoverableItemsQuotainB=[Int64]$PublicFolderInfo.pfmbx.RecoverableItemsQuota.Split("(")[1].split(" ")[0].Replace(",", "") - [Int64]$PfMBXstatsinB=[Int64]$PublicFolderInfo.PfMBXstats.TotalDeletedItemSize.Value.tostring().Split("(")[1].split(" ")[0].Replace(",", "") - if ($PfMBXstatsinB -ge $pfmbxRecoverableItemsQuotainB ) { + [Int64]$PfMbxRecoverableItemsQuotaInB=[Int64]$PublicFolderInfo.PfMbx.RecoverableItemsQuota.Split("(")[1].split(" ")[0].Replace(",", "") + [Int64]$PfMbxStatsInB=[Int64]$PublicFolderInfo.PfMbxStats.TotalDeletedItemSize.Value.ToString().Split("(")[1].split(" ")[0].Replace(",", "") + if ($PfMbxStatsInB -ge $PfMbxRecoverableItemsQuotaInB ) { $article="https://aka.ms/PFrecovery" $RecoverDeletedItems="https://aka.ms/cannotdeleteitemsOWA" $Fix="FIX --> To resolve a scenario where content public folder mailbox TotalDeletedItemSize value has reached RecoverableItemsQuota value, users could manually clean up the dumpster using: ->Outlook $RecoverDeletedItems ->MFCMAPI please refer to the following $article to check steps related to get to public folder dumpster using MFCMAPI then select unrequired items to be purged permanently" - $Issue="Public folder mailbox $($PublicFolderInfo.pfmbx.name) TotalDeletedItemSize value has reached its RecoverableItemsQuota value" - WritetoScreenANDlog -Issue $Issue -Fix $Fix + $Issue="Public folder mailbox $($PublicFolderInfo.PfMbx.name) TotalDeletedItemSize value has reached its RecoverableItemsQuota value" + WriteToScreenAndLog -Issue $Issue -Fix $Fix } } function ValidateParentPublicFolder { param([PSCustomObject]$PublicFolderInfo) #Validate where is the removal taking place under IPM_Subtree or Non_IPM_Subtree depends on the pf identity e.g \pf1 - if ($PublicFolderInfo.Publicfolder.FolderPath.Contains("DUMPSTER_ROOT")) { + if ($PublicFolderInfo.PublicFolder.FolderPath.Contains("DUMPSTER_ROOT")) { #Validate till Non_Ipm_Subtree - if ($PublicFolderInfo.Publicfolder.ParentFolder -ne $PublicFolderInfo.NON_IPM_SUBTREE.EntryId) { - $ParentPublicFolderInfo=GetPublicFolderInfo($PublicFolderInfo.Publicfolder.ParentFolder) + if ($PublicFolderInfo.PublicFolder.ParentFolder -ne $PublicFolderInfo.NON_IPM_SUBTREE.EntryId) { + $ParentPublicFolderInfo=GetPublicFolderInfo($PublicFolderInfo.PublicFolder.ParentFolder) ValidateContentMBXUniqueness($ParentPublicFolderInfo) ValidateEntryIDMapping($ParentPublicFolderInfo) ValidateContentMBXQuota($ParentPublicFolderInfo) @@ -178,8 +178,8 @@ function ValidateParentPublicFolder { } #Validate on IPM_Subtree else { - if (![string]::IsNullOrEmpty($PublicFolderInfo.Publicfolder.ParentFolder)) { - $ParentPublicFolderInfo=GetPublicFolderInfo($PublicFolderInfo.Publicfolder.ParentFolder) + if (![string]::IsNullOrEmpty($PublicFolderInfo.PublicFolder.ParentFolder)) { + $ParentPublicFolderInfo=GetPublicFolderInfo($PublicFolderInfo.PublicFolder.ParentFolder) ValidateContentMBXUniqueness($ParentPublicFolderInfo) ValidateEntryIDMapping($ParentPublicFolderInfo) ValidateContentMBXQuota($ParentPublicFolderInfo) @@ -189,20 +189,20 @@ function ValidateParentPublicFolder { } function ValidateDumpsterFlag { param([PSCustomObject]$PublicFolderInfo) - if ($PublicFolderInfo.Publicfolder.AdminFolderFlags -eq "DumpsterFolder") { - $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) is a dumpster folder, content folder and its dumpster are linked to each other, that link cannot be undone, in other words admins cannot delete dumpster only" - $Fix="FIX --> Please move $($PublicFolderInfo.Publicfolder.Identity) public folder to be under NON_IPM_SUBTREE using Set-PublicFolder command, for more information please check https://aka.ms/setpf" - WritetoScreenANDlog -Issue $Issue -Fix $Fix + if ($PublicFolderInfo.PublicFolder.AdminFolderFlags -eq "DumpsterFolder") { + $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) is a dumpster folder, content folder and its dumpster are linked to each other, that link cannot be undone, in other words admins cannot delete dumpster only" + $Fix="FIX --> Please move $($PublicFolderInfo.PublicFolder.Identity) public folder to be under NON_IPM_SUBTREE using Set-PublicFolder command, for more information please check https://aka.ms/setpf" + WriteToScreenAndLog -Issue $Issue -Fix $Fix AskForFeedback QuitEXOSession } } function GetUserPermissions { param([PSCustomObject]$Perms) - $workingpermissions=@("editor", "owner", "publishingeditor", "deleteallitems") + $WorkingPermissions=@("editor", "owner", "PublishingEditor", "DeleteAllItems") if ($null -ne $Perms) { foreach ($perm in $Perms.AccessRights) { - if ($workingpermissions.Contains($($perm.ToLower()))) { + if ($WorkingPermissions.Contains($($perm.ToLower()))) { return "user has permission" } } @@ -214,10 +214,10 @@ function GetUserPermissions { } } function ValidateUserPermissions { - param([PSCustomObject]$Perms, [PSCustomObject]$Permsuserpfmbx) - if ($Perms.AccessRights.count -eq $Permsuserpfmbx.AccessRights.count) { + param([PSCustomObject]$Perms, [PSCustomObject]$PermsUserPfMbx) + if ($Perms.AccessRights.count -eq $PermsUserPfMbx.AccessRights.count) { foreach ($Perm in $perms.AccessRights) { - if (!$Permsuserpfmbx.AccessRights.contains($Perm)) { + if (!$PermsUserPfMbx.AccessRights.contains($Perm)) { return "sync issue exist" } } @@ -229,92 +229,92 @@ function ValidatePublicFolderIssue { param([Parameter(Mandatory = $true)] [PSCustomObject]$PublicFolderInfo, [Parameter(Mandatory = $false)] - [string]$Affecteduser) - #validate explict permission & default permission if item + [string]$AffectedUser) + #validate explicit permission & default permission if item try { - $User=Get-Mailbox $Affecteduser -ErrorAction stop - $Userpfmbx=Get-mailbox -PublicFolder $($User.EffectivePublicFolderMailbox) -ErrorAction stop - $Explicitperms=Get-PublicFolderClientPermission $PublicFolderInfo.Publicfolder.EntryId -User $User.Guid.Guid.tostring() -ErrorAction SilentlyContinue - $Defaultperms=Get-PublicFolderClientPermission $PublicFolderInfo.Publicfolder.EntryId -User Default -ErrorAction SilentlyContinue + $User=Get-Mailbox $AffectedUser -ErrorAction stop + $UserPfMbx=Get-mailbox -PublicFolder $($User.EffectivePublicFolderMailbox) -ErrorAction stop + $ExplicitPerms=Get-PublicFolderClientPermission $PublicFolderInfo.PublicFolder.EntryId -User $User.Guid.Guid.ToString() -ErrorAction SilentlyContinue + $DefaultPerms=Get-PublicFolderClientPermission $PublicFolderInfo.PublicFolder.EntryId -User Default -ErrorAction SilentlyContinue #Validate if there's no perm sync issue - $Explicitpermsuserpfmbx=Get-PublicFolderClientPermission $PublicFolderInfo.Publicfolder.Identity -User $User.Guid.Guid.tostring() -ErrorAction SilentlyContinue -Mailbox $userpfmbx.ExchangeGuid.Guid - $Defaultpermsuserpfmbx=Get-PublicFolderClientPermission $PublicFolderInfo.Publicfolder.Identity -User Default -ErrorAction SilentlyContinue -Mailbox $userpfmbx.ExchangeGuid.Guid - $Userpermsyncissue=ValidateUserPermissions -Permsuserpfmbx $Explicitpermsuserpfmbx -Perms $Explicitperms - $Defaultuserpermsyncissue=ValidateUserPermissions -Permsuserpfmbx $Defaultpermsuserpfmbx -Perms $Defaultperms - $Explicitpermsresult=GetUserPermissions($Explicitperms) - $Defaultpermsresult=GetUserPermissions($Defaultperms) - if ($Userpermsyncissue -eq "sync issue exist") { - #explicituser sync perm issue + $ExplicitPermsUserPfMbx=Get-PublicFolderClientPermission $PublicFolderInfo.PublicFolder.Identity -User $User.Guid.Guid.ToString() -ErrorAction SilentlyContinue -Mailbox $userPfMbx.ExchangeGuid.Guid + $DefaultPermsUserPfMbx=Get-PublicFolderClientPermission $PublicFolderInfo.PublicFolder.Identity -User Default -ErrorAction SilentlyContinue -Mailbox $userPfMbx.ExchangeGuid.Guid + $UserPermSyncIssue=ValidateUserPermissions -PermsUserPfMbx $ExplicitPermsUserPfMbx -Perms $ExplicitPerms + $DefaultUserPermSyncIssue=ValidateUserPermissions -PermsUserPfMbx $DefaultPermsUserPfMbx -Perms $DefaultPerms + $ExplicitPermsResult=GetUserPermissions($ExplicitPerms) + $DefaultPermsResult=GetUserPermissions($DefaultPerms) + if ($UserPermSyncIssue -eq "sync issue exist") { + #ExplicitUser sync perm issue #validate that user has sufficient perms - if ($Explicitpermsresult -match "user has no permission") { + if ($ExplicitPermsResult -match "user has no permission") { #user has no sufficient perm $FIX="FIX --> Please ensure that user $($User.PrimarySmtpAddress) has sufficient permissions to delete, for more information please check the following article https://aka.ms/addPFperm" - $Issue="$($User.PrimarySmtpAddress) have no sufficient permissions to delete items inside $($PublicFolderInfo.publicfolder.identity)" - WritetoScreenANDlog -Issue $Issue -Fix $fix + $Issue="$($User.PrimarySmtpAddress) have no sufficient permissions to delete items inside $($PublicFolderInfo.PublicFolder.identity)" + WriteToScreenAndLog -Issue $Issue -Fix $fix } #user has sufficient perm $FIX="FIX --> Please ensure that user $($User.PrimarySmtpAddress) permissions are synced properly over his EffectivePublicFolderMailbox $($User.EffectivePublicFolderMailbox), for more information please check the following article https://aka.ms/Fixpfpermissue" $Issue="$($User.PrimarySmtpAddress) has permissions sync problems over EffectivePublicFolderMailbox $($User.EffectivePublicFolderMailbox)!" - WritetoScreenANDlog -Issue $Issue -Fix $fix + WriteToScreenAndLog -Issue $Issue -Fix $fix } - if ($Defaultuserpermsyncissue -eq "sync issue exist" ) { - #Defaultuser sync perm issue + if ($DefaultUserPermSyncIssue -eq "sync issue exist" ) { + #DefaultUser sync perm issue #validate that Default has sufficient perms - if ($Defaultpermsresult -match "user has no permission" -and $Explicitpermsresult -match "user has no permission") { + if ($DefaultPermsResult -match "user has no permission" -and $ExplicitPermsResult -match "user has no permission") { #Default user has no sufficient perm $FIX="FIX --> Please ensure that either $($User.PrimarySmtpAddress) or Default user has sufficient permissions to delete, for more information please check the following article https://aka.ms/addPFperm" - $Issue="Neither $($User.PrimarySmtpAddress) nor Default user have sufficient permissions to delete items inside $($PublicFolderInfo.publicfolder.identity)" - WritetoScreenANDlog -Issue $Issue -Fix $fix + $Issue="Neither $($User.PrimarySmtpAddress) nor Default user have sufficient permissions to delete items inside $($PublicFolderInfo.PublicFolder.identity)" + WriteToScreenAndLog -Issue $Issue -Fix $fix } #Default user has sufficient perm - if ($Defaultpermsresult -match "user has permission" -and $Explicitpermsresult -match "user has no permission") { + if ($DefaultPermsResult -match "user has permission" -and $ExplicitPermsResult -match "user has no permission") { $FIX="FIX --> Please ensure that Default user permissions are synced properly over user EffectivePublicFolderMailbox $($User.EffectivePublicFolderMailbox), for more information please check the following article https://aka.ms/Fixpfpermissue" $Issue="Default user has permissions sync problems over user EffectivePublicFolderMailbox $($User.EffectivePublicFolderMailbox)!" - WritetoScreenANDlog -Issue $Issue -Fix $fix + WriteToScreenAndLog -Issue $Issue -Fix $fix $FIX="FIX --> Please ensure that user $($User.PrimarySmtpAddress) has sufficient permissions to delete, for more information please check the following article https://aka.ms/addPFperm" - $Issue="$($User.PrimarySmtpAddress) have no sufficient permissions to delete items inside $($PublicFolderInfo.publicfolder.identity)" - WritetoScreenANDlog -Issue $Issue -Fix $fix + $Issue="$($User.PrimarySmtpAddress) have no sufficient permissions to delete items inside $($PublicFolderInfo.PublicFolder.identity)" + WriteToScreenAndLog -Issue $Issue -Fix $fix } - if ($Defaultpermsresult -match "user has permission" -and $Explicitpermsresult -match "user has permission") { + if ($DefaultPermsResult -match "user has permission" -and $ExplicitPermsResult -match "user has permission") { $FIX="FIX --> Please re-grant user $($User.PrimarySmtpAddress) permissions over the affected public folder, for more information please check the following articles https://aka.ms/removePFperm, https://aka.ms/addPFperm" - $Issue="$($User.PrimarySmtpAddress) user has corrupted permission over public folder $($PublicFolderInfo.publicfolder.identity)" - WritetoScreenANDlog -Issue $Issue -Fix $fix + $Issue="$($User.PrimarySmtpAddress) user has corrupted permission over public folder $($PublicFolderInfo.PublicFolder.identity)" + WriteToScreenAndLog -Issue $Issue -Fix $fix } - if ($Defaultpermsresult -match "user has no permission" -and $Explicitpermsresult -match "user has permission") { + if ($DefaultPermsResult -match "user has no permission" -and $ExplicitPermsResult -match "user has permission") { $FIX="FIX --> Please re-grant user $($User.PrimarySmtpAddress) permissions over the affected public folder, for more information please check the following articles https://aka.ms/removePFperm, https://aka.ms/addPFperm" - $Issue="$($User.PrimarySmtpAddress) user has corrupted permission over public folder $($PublicFolderInfo.publicfolder.identity)" - WritetoScreenANDlog -Issue $Issue -Fix $fix + $Issue="$($User.PrimarySmtpAddress) user has corrupted permission over public folder $($PublicFolderInfo.PublicFolder.identity)" + WriteToScreenAndLog -Issue $Issue -Fix $fix } } - if ($Userpermsyncissue -eq "no sync issue exist" -and $Defaultuserpermsyncissue -eq "no sync issue exist") { - if ($Explicitpermsresult -match "user has no permission" -and $Defaultpermsresult -match "user has no permission") { + if ($UserPermSyncIssue -eq "no sync issue exist" -and $DefaultUserPermSyncIssue -eq "no sync issue exist") { + if ($ExplicitPermsResult -match "user has no permission" -and $DefaultPermsResult -match "user has no permission") { #user has no permission to delete $FIX="FIX --> Please ensure that user $($User.PrimarySmtpAddress) has sufficient permissions to delete, for more information please check the following article https://aka.ms/addPFperm" - $Issue="Neither $($User.PrimarySmtpAddress) nor Default user have sufficient permissions to delete items inside $($PublicFolderInfo.publicfolder.identity)" - WritetoScreenANDlog -Issue $Issue -Fix $fix + $Issue="Neither $($User.PrimarySmtpAddress) nor Default user have sufficient permissions to delete items inside $($PublicFolderInfo.PublicFolder.identity)" + WriteToScreenAndLog -Issue $Issue -Fix $fix } #if Default/user has sufficient permission might be perm is corrupted, we might need to re-add default/user permission again - if ($Explicitpermsresult -match "user has permission") { + if ($ExplicitPermsResult -match "user has permission") { #user has sufficient permission to delete but might be corrupted acl $FIX="FIX --> Please re-grant user $($User.PrimarySmtpAddress) permissions over the affected public folder, for more information please check the following articles https://aka.ms/removePFperm, https://aka.ms/addPFperm" - $Issue="$($User.PrimarySmtpAddress) user has corrupted permission over public folder $($PublicFolderInfo.publicfolder.identity)" - WritetoScreenANDlog -Issue $Issue -Fix $fix + $Issue="$($User.PrimarySmtpAddress) user has corrupted permission over public folder $($PublicFolderInfo.PublicFolder.identity)" + WriteToScreenAndLog -Issue $Issue -Fix $fix } - if ($Defaultpermsresult -match "user has permission" -and $Explicitpermsresult -match "user has no permission") { + if ($DefaultPermsResult -match "user has permission" -and $ExplicitPermsResult -match "user has no permission") { #user has sufficient permission to delete but might be corrupted acl $FIX="FIX --> Please re-grant Default user permissions over the affected public folder or add the permission for the affected user explicitly, for more information please check the following articles https://aka.ms/removePFperm, https://aka.ms/addPFperm" - $Issue="Default user has corrupted permission over public folder $($PublicFolderInfo.publicfolder.identity)" - WritetoScreenANDlog -Issue $Issue -Fix $fix + $Issue="Default user has corrupted permission over public folder $($PublicFolderInfo.PublicFolder.identity)" + WriteToScreenAndLog -Issue $Issue -Fix $fix } } } catch { #log the error and quit - $Errorencountered=$Global:error[0].Exception + $ErrorEncountered=$Global:error[0].Exception $CurrentDescription = "Validating if user has sufficient permissions to delete" - $CurrentStatus = "Failure with error: "+$Errorencountered - logerror -Function "Validate user permissions" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + $CurrentStatus = "Failure with error: "+$ErrorEncountered + LogError -Function "Validate user permissions" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription Write-Host "Error encountered during executing the script!"-ForegroundColor Red - Write-Host $Errorencountered -ForegroundColor Red + Write-Host $ErrorEncountered -ForegroundColor Red Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 break @@ -324,32 +324,32 @@ function ValidatePublicFolderIssue { function ValidatePublicFolderQuota { param([PSCustomObject]$PublicFolderInfo) #Validate if DefaultPublicFolderProhibitPostQuota at the organization level applies - if ($PublicFolderInfo.Publicfolder.ProhibitPostQuota -eq "unlimited") { + if ($PublicFolderInfo.PublicFolder.ProhibitPostQuota -eq "unlimited") { #Checking if public folder total size has reached organization public folder DefaultPublicFolderProhibitPostQuota value!" - if ($PublicFolderInfo.Publicfoldersize -ge $PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) { + if ($PublicFolderInfo.PublicFolderSize -ge $PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) { #validate if Giant PF to lower the PF size down else increase Org DefaultPublicFolderProhibitPostQuota if ($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota -ge 21474836480) { - $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to avoid having Giant public folders with sizes exceeding 20GB, then delete or move items from that giant folder $($PublicFolderInfo.Publicfolder.Identity) to reduce the size of that public folder to an appropriate size accomadating with newly modified organization values." - $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) size has exceeded Organization DefaultPublicFolderProhibitPostQuota value!" - WritetoScreenANDlog -Issue $Issue -Fix $Fix + $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to avoid having Giant public folders with sizes exceeding 20GB, then delete or move items from that giant folder $($PublicFolderInfo.PublicFolder.Identity) to reduce the size of that public folder to an appropriate size accommodating with newly modified organization values." + $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) size has exceeded Organization DefaultPublicFolderProhibitPostQuota value!" + WriteToScreenAndLog -Issue $Issue -Fix $Fix } else { - $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to accomodate the public folder $($PublicFolderInfo.Publicfolder.Identity) size:$($PublicFolderInfo.Publicfoldersize) Bytes" - $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) size has exceeded Organization DefaultPublicFolderProhibitPostQuota value!" - WritetoScreenANDlog -Issue $Issue -Fix $Fix + $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to accommodate the public folder $($PublicFolderInfo.PublicFolder.Identity) size:$($PublicFolderInfo.PublicFolderSize) Bytes" + $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) size has exceeded Organization DefaultPublicFolderProhibitPostQuota value!" + WriteToScreenAndLog -Issue $Issue -Fix $Fix } } } else { - [Int64]$PFProhibitPostQuota=[Int64]$PublicFolderInfo.Publicfolder.ProhibitPostQuota.split("(")[1].split(" ")[0].replace(",", "") - if ($PublicFolderInfo.Publicfoldersize -ge $PFProhibitPostQuota) { - #validate if Giant PF to lower the PF size down else increase PFProhibitPostQuota or inhertit Org DefaultPublicFolderProhibitPostQuota + [Int64]$PFProhibitPostQuota=[Int64]$PublicFolderInfo.PublicFolder.ProhibitPostQuota.split("(")[1].split(" ")[0].replace(",", "") + if ($PublicFolderInfo.PublicFolderSize -ge $PFProhibitPostQuota) { + #validate if Giant PF to lower the PF size down else increase PFProhibitPostQuota or inherit Org DefaultPublicFolderProhibitPostQuota if ($PFProhibitPostQuota -ge 21474836480) { - $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to avoid having Giant public folders with sizes exceeding 20GB, then delete or move items from that giant folder $($PublicFolderInfo.Publicfolder.Identity) to reduce the size of that public folder to an appropriate size accomadating with newly modified organization values." - $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) size has exceeded Individual Public Folder ProhibitPostQuota value" - WritetoScreenANDlog -Issue $Issue -Fix $Fix + $Fix= "FIX --> Please follow the following article https://aka.ms/Setorgconfig to modify the Organization DefaultPublicFolderProhibitPostQuota:$($PublicFolderInfo.DefaultPublicFolderProhibitPostQuota) Bytes & DefaultPublicFolderIssueWarningQuota:$($PublicFolderInfo.DefaultPublicFolderIssueWarningQuota) Bytes values to avoid having Giant public folders with sizes exceeding 20GB, then delete or move items from that giant folder $($PublicFolderInfo.PublicFolder.Identity) to reduce the size of that public folder to an appropriate size accommodating with newly modified organization values." + $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) size has exceeded Individual Public Folder ProhibitPostQuota value" + WriteToScreenAndLog -Issue $Issue -Fix $Fix } else { - $Fix= "FIX --> Please follow the following article https://aka.ms/setpf to modify the Public Folder ProhibitPostQuota:$PFProhibitPostQuota Bytes value to accomodate the public folder $($PublicFolderInfo.Publicfolder.Identity) size:$($PublicFolderInfo.Publicfoldersize) Bytes" - $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) size has exceeded Individual Public Folder ProhibitPostQuota value" - WritetoScreenANDlog -Issue $Issue -Fix $Fix + $Fix= "FIX --> Please follow the following article https://aka.ms/setpf to modify the Public Folder ProhibitPostQuota:$PFProhibitPostQuota Bytes value to accommodate the public folder $($PublicFolderInfo.PublicFolder.Identity) size:$($PublicFolderInfo.PublicFolderSize) Bytes" + $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) size has exceeded Individual Public Folder ProhibitPostQuota value" + WriteToScreenAndLog -Issue $Issue -Fix $Fix } } } @@ -357,36 +357,36 @@ function ValidatePublicFolderQuota { function ValidateDumpsterChildren { param([PSCustomObject]$PublicFolderInfo) try { - $Haschildren= Get-PublicFolder $PublicFolderInfo.Publicfolderdumpster.EntryId -ErrorAction stop -GetChildren - $CurrentDescription = "Validating if dumpster folder:$($PublicFolderInfo.Publicfolderdumpster.EntryId) has children" + $HasChildren= Get-PublicFolder $PublicFolderInfo.PublicFolderDumpster.EntryId -ErrorAction stop -GetChildren + $CurrentDescription = "Validating if dumpster folder:$($PublicFolderInfo.PublicFolderDumpster.EntryId) has children" $CurrentStatus = "Success" - logerror -Function "Validate if dumpster folder has children" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + LogError -Function "Validate if dumpster folder has children" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription } catch { - $Errorencountered=$Global:error[0].Exception - $CurrentDescription = "Validating if dumpster folder:$($PublicFolderInfo.Publicfolderdumpster.EntryId) has children" - $CurrentStatus = "Failure with error: "+$Errorencountered - logerror -Function "Validate if dumpster folder has children" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + $ErrorEncountered=$Global:error[0].Exception + $CurrentDescription = "Validating if dumpster folder:$($PublicFolderInfo.PublicFolderDumpster.EntryId) has children" + $CurrentStatus = "Failure with error: "+$ErrorEncountered + LogError -Function "Validate if dumpster folder has children" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription Write-Host "Error encountered during executing the script!"-ForegroundColor Red - Write-Host $Errorencountered -ForegroundColor Red + Write-Host $ErrorEncountered -ForegroundColor Red Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 break } - if ($null -ne $Haschildren) { - $Fix= "FIX --> Please follow the following article https://aka.ms/setpf to move $($PublicFolderInfo.Publicfolder.Identity) dumpster children found to under NON_IPM_SUBTREE scope e.g. \NON_IPM_SUBTREE\DUMPSTER_ROOT\DUMPSTER_EXTEND\RESERVED_1\RESERVED_1" - $Issue="Public folder $($PublicFolderInfo.Publicfolder.Identity) dumpster has $($Haschildren.Name.count) subfolder(s) which is a blocker for deletion operations over the public folder!`nDumpster subfolder(s) found:`n----------------------------`n$($Haschildren.identity)" - WritetoScreenANDlog -Issue $Issue -Fix $Fix + if ($null -ne $HasChildren) { + $Fix= "FIX --> Please follow the following article https://aka.ms/setpf to move $($PublicFolderInfo.PublicFolder.Identity) dumpster children found to under NON_IPM_SUBTREE scope e.g. \NON_IPM_SUBTREE\DUMPSTER_ROOT\DUMPSTER_EXTEND\RESERVED_1\RESERVED_1" + $Issue="Public folder $($PublicFolderInfo.PublicFolder.Identity) dumpster has $($HasChildren.Name.count) subfolder(s) which is a blocker for deletion operations over the public folder!`nDumpster subfolder(s) found:`n----------------------------`n$($HasChildren.identity)" + WriteToScreenAndLog -Issue $Issue -Fix $Fix } } -function ValidateMEPFGuid { +function ValidateMePfGuid { param([PSCustomObject]$PublicFolderInfo) #validate if MailRecipientGuid parameter is found empty/null - if ($PublicFolderInfo.Publicfolder.MailEnabled -eq $true) { - $Hasvalue=$PublicFolderInfo.Publicfolder.MailRecipientGuid.Guid - if ($null -eq $Hasvalue -or $Hasvalue -eq "00000000-0000-0000-0000-000000000000") { + if ($PublicFolderInfo.PublicFolder.MailEnabled -eq $true) { + $HasValue=$PublicFolderInfo.PublicFolder.MailRecipientGuid.Guid + if ($null -eq $HasValue -or $HasValue -eq "00000000-0000-0000-0000-000000000000") { $Fix= "FIX --> Please follow the following article https://aka.ms/EnableMPF to mail enable the affected public folder to generate a GUID over MailRecipientGuid parameter, validate MailRecipientGuid parameter has a GUID using https://aka.ms/getpf article then mail disable the affected public folder back again using https://aka.ms/disablempf article to be able to remove the public folder as requested." - $Issue="Mail-enabled public folder $($PublicFolderInfo.Publicfolder.Identity) is unhealthy e.g MailRecipientGuid parameter is found empty/null which is a blocker for deletion operations over the public folder" - WritetoScreenANDlogDlog -Issue $Issue -Fix $Fix + $Issue="Mail-enabled public folder $($PublicFolderInfo.PublicFolder.Identity) is unhealthy e.g MailRecipientGuid parameter is found empty/null which is a blocker for deletion operations over the public folder" + WriteToScreenAndLog -Issue $Issue -Fix $Fix } } } @@ -396,30 +396,30 @@ function ExtractLog { if (!(Test-Path "$ExportPath\logs_$ts")) { mkdir "$ExportPath\logs_$ts" -Force | Out-Null } - $PublicFolderInfo | Export-Clixml -Path "$ExportPath\logs_$ts\PublicFolderInfo$($PublicFolderInfo.Publicfolder.Name).xml" + $PublicFolderInfo | Export-Clixml -Path "$ExportPath\logs_$ts\PublicFolderInfo$($PublicFolderInfo.PublicFolder.Name).xml" } function AskForFeedback { Write-Host "Please rate the script experience & tell us what you liked or what we can do better over https://aka.ms/PFDumpsterFeedback!" -ForegroundColor Cyan "Please rate the script experience & tell us what you liked or what we can do better over https://aka.ms/PFDumpsterFeedback!" | Out-File $ExportPath\$Script:ReportName -Append } function QuitEXOSession { - if ($null -eq $Sessioncheck) { + if ($null -eq $SessionCheck) { try { - Write-Host "Quiting EXO PowerShell session..." -ForegroundColor Yellow + Write-Host "Quitting EXO PowerShell session..." -ForegroundColor Yellow Disconnect-ExchangeOnline -ErrorAction Stop -Confirm:$false $CurrentDescription= "Disconnecting from EXO" $CurrentStatus = "Success" - logerror -CurrentStatus $CurrentStatus -Function "Disconnecting from EXO" -CurrentDescription $CurrentDescription + LogError -CurrentStatus $CurrentStatus -Function "Disconnecting from EXO" -CurrentDescription $CurrentDescription Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 break } catch { - $Errorencountered=$Global:error[0].Exception + $ErrorEncountered=$Global:error[0].Exception $CurrentDescription = "Disconnecting from EXO" $CurrentStatus = "Failure" - logerror -CurrentStatus $CurrentStatus -Function "Disconnecting from EXO" -CurrentDescription $CurrentDescription + LogError -CurrentStatus $CurrentStatus -Function "Disconnecting from EXO" -CurrentDescription $CurrentDescription Write-Host "Error encountered during executing the script!"-ForegroundColor Red - Write-Host $Errorencountered -ForegroundColor Red + Write-Host $ErrorEncountered -ForegroundColor Red Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 break @@ -441,19 +441,19 @@ if ($null -eq $ExportPath -or $ExportPath -eq "") { mkdir $ExportPath -Force | Out-Null } } -[string]$Description = "This script illustrates issues related to deleting public folder items or removing the public folder on Publicfolder $Pfolder, BLOCKERS will be reported down, please ensure to mitigate them!`n" +[string]$Description = "This script illustrates issues related to deleting public folder items or removing the public folder on PublicFolder $PFolder, BLOCKERS will be reported down, please ensure to mitigate them!`n" Write-Host $Description -ForegroundColor Cyan $Description | Out-File $ExportPath\$Script:ReportName -Append #Connect to EXO PS -$Sessioncheck = Get-PSSession | Where-Object { $_.Name -like "*Exchangeonline*" -and $_.State -match "opened" } -if ($null -eq $Sessioncheck) { +$SessionCheck = Get-PSSession | Where-Object { $_.Name -like "*ExchangeOnline*" -and $_.State -match "opened" } +if ($null -eq $SessionCheck) { Connect2EXO } #Main Function -$PublicFolderInfo=GetPublicFolderInfo($Pfolder) +$PublicFolderInfo=GetPublicFolderInfo($PFolder) #if the issue is related to a user who is not able to delete an item inside a public folder -if (![string]::IsNullOrEmpty($Affecteduser)) { - ValidatePublicFolderIssue -PublicFolderInfo $PublicFolderInfo -Affecteduser $Affecteduser +if (![string]::IsNullOrEmpty($AffectedUser)) { + ValidatePublicFolderIssue -PublicFolderInfo $PublicFolderInfo -AffectedUser $AffectedUser } ValidateDumpsterFlag($PublicFolderInfo) ValidateContentMBXUniqueness($PublicFolderInfo) @@ -461,7 +461,7 @@ ValidateEntryIDMapping($PublicFolderInfo) ValidateContentMBXQuota($PublicFolderInfo) ValidatePublicFolderQuota($PublicFolderInfo) ValidateDumpsterChildren($PublicFolderInfo) -ValidateMEPFGuid($PublicFolderInfo) +ValidateMePfGuid($PublicFolderInfo) ValidateParentPublicFolder($PublicFolderInfo) AskForFeedback QuitEXOSession From f875c76c567a8dc3e306d87e1b9cb3fd78424f3a Mon Sep 17 00:00:00 2001 From: hazemembaby <71065889+hazemembaby@users.noreply.github.com> Date: Mon, 12 Jun 2023 17:25:28 +0300 Subject: [PATCH 3/6] add logging under new function --- PublicFolders/ValidateEXOPFDumpster.ps1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/PublicFolders/ValidateEXOPFDumpster.ps1 b/PublicFolders/ValidateEXOPFDumpster.ps1 index 496c0d1e1c..7a967ef356 100644 --- a/PublicFolders/ValidateEXOPFDumpster.ps1 +++ b/PublicFolders/ValidateEXOPFDumpster.ps1 @@ -79,6 +79,10 @@ function ValidateDumpsterExistence { $CurrentDescription = "Retrieving: $($PublicFolder.Identity) dumpster for diagnosing" $CurrentStatus = "Failure with error: "+$ErrorEncountered LogError -Function "Retrieve public folder $($PublicFolder.Identity) dumpster" -CurrentStatus $CurrentStatus -CurrentDescription $CurrentDescription + if (!(Test-Path "$ExportPath\logs_$ts")) { + mkdir "$ExportPath\logs_$ts" -Force | Out-Null + } + $PublicFolder | Export-Clixml -Path "$ExportPath\logs_$ts\PublicFolderInfo$($PublicFolder.Name).xml" AskForFeedback QuitEXOSession } @@ -141,7 +145,7 @@ function ValidateContentMBXUniqueness { function ValidateEntryIDMapping { param([PSCustomObject]$PublicFolderInfo) if ($PublicFolderInfo.PublicFolder.EntryId -ne $PublicFolderInfo.PublicFolderDumpster.DumpsterEntryID -or $PublicFolderInfo.PublicFolder.DumpsterEntryID -ne $PublicFolderInfo.PublicFolderDumpster.EntryId) { - if (!(Test-Path -Path "$ExportPath\logs_$ts\PublicFolderInfo.xml")) { + if (!(Test-Path -Path "$ExportPath\logs_$ts\$($PublicFolderInfo.PublicFolder.Name).xml")) { ExtractLog($PublicFolderInfo) } $Issue="Public folder $($PublicFolder.Identity) EntryId & DumpsterEntryID values are not mapped properly" From a0f5f30f00343d1f5d7723b659d661b4564c6e63 Mon Sep 17 00:00:00 2001 From: hazemembaby <71065889+hazemembaby@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:22:21 +0300 Subject: [PATCH 4/6] modify script --- PublicFolders/ValidateEXOPFDumpster.ps1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/PublicFolders/ValidateEXOPFDumpster.ps1 b/PublicFolders/ValidateEXOPFDumpster.ps1 index 7a967ef356..1f5e18550c 100644 --- a/PublicFolders/ValidateEXOPFDumpster.ps1 +++ b/PublicFolders/ValidateEXOPFDumpster.ps1 @@ -203,7 +203,7 @@ function ValidateDumpsterFlag { } function GetUserPermissions { param([PSCustomObject]$Perms) - $WorkingPermissions=@("editor", "owner", "PublishingEditor", "DeleteAllItems") + $WorkingPermissions=@("Editor", "Owner", "PublishingEditor", "DeleteAllItems").ToLower() if ($null -ne $Perms) { foreach ($perm in $Perms.AccessRights) { if ($WorkingPermissions.Contains($($perm.ToLower()))) { @@ -382,6 +382,7 @@ function ValidateDumpsterChildren { WriteToScreenAndLog -Issue $Issue -Fix $Fix } } +#MePf=Mail Enabled Public Folder function ValidateMePfGuid { param([PSCustomObject]$PublicFolderInfo) #validate if MailRecipientGuid parameter is found empty/null @@ -403,8 +404,9 @@ function ExtractLog { $PublicFolderInfo | Export-Clixml -Path "$ExportPath\logs_$ts\PublicFolderInfo$($PublicFolderInfo.PublicFolder.Name).xml" } function AskForFeedback { - Write-Host "Please rate the script experience & tell us what you liked or what we can do better over https://aka.ms/PFDumpsterFeedback!" -ForegroundColor Cyan - "Please rate the script experience & tell us what you liked or what we can do better over https://aka.ms/PFDumpsterFeedback!" | Out-File $ExportPath\$Script:ReportName -Append + $Feedback="Please rate the script experience & tell us what you liked or what we can do better over https://aka.ms/PFDumpsterFeedback!" + Write-Host $Feedback -ForegroundColor Cyan + $Feedback | Out-File $ExportPath\$Script:ReportName -Append } function QuitEXOSession { if ($null -eq $SessionCheck) { @@ -416,7 +418,6 @@ function QuitEXOSession { LogError -CurrentStatus $CurrentStatus -Function "Disconnecting from EXO" -CurrentDescription $CurrentDescription Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 - break } catch { $ErrorEncountered=$Global:error[0].Exception $CurrentDescription = "Disconnecting from EXO" @@ -426,7 +427,6 @@ function QuitEXOSession { Write-Host $ErrorEncountered -ForegroundColor Red Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 - break } } } From 3b298f8584d05e35244cff218d79c152a6ebc9d3 Mon Sep 17 00:00:00 2001 From: hazemembaby <71065889+hazemembaby@users.noreply.github.com> Date: Thu, 15 Jun 2023 18:39:12 +0300 Subject: [PATCH 5/6] add Exit under Quit function --- PublicFolders/ValidateEXOPFDumpster.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PublicFolders/ValidateEXOPFDumpster.ps1 b/PublicFolders/ValidateEXOPFDumpster.ps1 index 1f5e18550c..33923c70e4 100644 --- a/PublicFolders/ValidateEXOPFDumpster.ps1 +++ b/PublicFolders/ValidateEXOPFDumpster.ps1 @@ -418,6 +418,7 @@ function QuitEXOSession { LogError -CurrentStatus $CurrentStatus -Function "Disconnecting from EXO" -CurrentDescription $CurrentDescription Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 + Exit } catch { $ErrorEncountered=$Global:error[0].Exception $CurrentDescription = "Disconnecting from EXO" @@ -427,6 +428,7 @@ function QuitEXOSession { Write-Host $ErrorEncountered -ForegroundColor Red Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 + Exit } } } From e29b098d3a4b59038aa447062dbdc6d771d037f1 Mon Sep 17 00:00:00 2001 From: hazemembaby <71065889+hazemembaby@users.noreply.github.com> Date: Mon, 19 Jun 2023 12:35:00 +0300 Subject: [PATCH 6/6] modify exit --- PublicFolders/ValidateEXOPFDumpster.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PublicFolders/ValidateEXOPFDumpster.ps1 b/PublicFolders/ValidateEXOPFDumpster.ps1 index 33923c70e4..3c6acef802 100644 --- a/PublicFolders/ValidateEXOPFDumpster.ps1 +++ b/PublicFolders/ValidateEXOPFDumpster.ps1 @@ -418,7 +418,7 @@ function QuitEXOSession { LogError -CurrentStatus $CurrentStatus -Function "Disconnecting from EXO" -CurrentDescription $CurrentDescription Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 - Exit + exit } catch { $ErrorEncountered=$Global:error[0].Exception $CurrentDescription = "Disconnecting from EXO" @@ -428,7 +428,7 @@ function QuitEXOSession { Write-Host $ErrorEncountered -ForegroundColor Red Write-Host "`nOutput was exported in the following location: $ExportPath" -ForegroundColor Yellow Start-Sleep -Seconds 3 - Exit + exit } } }