Entra / Microsoft 365 · Exchange Online
Report permissions folder level
Uses Exchange Online Management module (REST).
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-ExchangeOnline -ShowBanner:$false
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
$Modules = Get-Module | ? { $_.Name -eq "ExchangeOnlineManagement" }If ($Null -eq $Modules) {Write-Host "Please connect to the Exchange Online Management module before running this script!"; break }# Find mailboxes$Mbx = Get-ExoMailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited | Select DisplayName, ExternalDirectoryObjectId, UserPrincipalName, Name$Report = [System.Collections.Generic.List[Object]]::new()$ProgressDelta = 100/($Mbx.count); $PercentComplete = 0; $MbxNumber = 0# Loop through mailboxes to fetch folders and procvess themForEach ($M in $Mbx) {$MbxNumber++$MbxStatus = $M.DisplayName + " ["+ $MbxNumber +"/" + $Mbx.Count + "]"Write-Progress -Activity "Processing mailbox" -Status $MbxStatus -PercentComplete $PercentComplete$PercentComplete += $ProgressDelta# Get Folders to check - not interested in system folders and focusing on folders that are usually delegated# We also don't check empty folders...$Folders = Get-ExoMailboxFolderStatistics -Identity $M.ExternalDirectoryObjectId | ? {$_.FolderType -eq "User Created" -or $_.FolderType -eq "Inbox" -or $_.FolderType -eq "SentItems" -or $_.FolderType -eq "Contacts" -or $_.FolderType -eq "Calendar" -and $_.ItemsInFolder -gt 0 } | Select Name, itemsinfolder# Loop through folder to extract pernmissions for each oneForEach ($Folder in $Folders) {$FolderName = $M.Name + ":\" + $Folder.Name$Permissions = (Get-ExoMailboxFolderPermission -Identity $FolderName -ErrorAction SilentlyContinue)ForEach ($Permission in $Permissions) { # Check each permission, ignoring ones we don't have any interest in$User = $Permission.UserIf (($User -ne "Default" -and $User -ne "Anonymous") -and ($User -ne $M.DisplayName -and $Permission.AccessRights -ne "None")) {$i = 1ForEach ($Access in $Permission.AccessRights) { # Break up the array of access rights into a formatted string for the reportIf ($i -eq 1) { $AccessRights = $Access; $i++ } Else {$AccessRights = $AccessRights + "; " + $Access }}$ReportLine = [PSCustomObject]@{Mailbox = $M.DisplayNameFolder = $Folder.NamePermission = $AccessRightsAssignedto = $User }$Report.Add($ReportLine) }}# Debug line -uncomment if you want to see these messages# Write-Host "Mailbox:" $M.Name "Permission" $Permission.AccessRights "on" $Folder.Name "for" $User}}$Report | Export-CSV -NoTypeInformation c:\temp\FolderDelegatedPermissions.CSVCLSWrite-Host "Finished processing" $Mbx.Count "mailboxes. The report file is in c:\temp\FolderDelegatedPermissions.CSV"
Attribution
Author
Office365itpros