Scripts/Get-MailboxPermissions.ps1
function Get-MailboxPermissions { <# .SYNOPSIS Retrieves delegated permissions for all mailboxes in Microsoft 365. .DESCRIPTION Retrieves detailed information about mailbox delegated permissions, including Full Access, Send As, Send on Behalf, Calendar permissions, and Inbox permissions for all mailboxes. .PARAMETER OutputDir Specifies the output directory for the delegated permissions report. Default: Output\Mailbox Permissions .PARAMETER Encoding Specifies the encoding of the CSV output file. Default: UTF8 .PARAMETER UserIds UserIds is the UserIds parameter filtering the log entries by the account of the user who performed the actions. .PARAMETER LogLevel Specifies the level of logging: None: No logging Minimal: Critical errors only Standard: Normal operational logging Default: Standard .EXAMPLE Get-MailboxPermissions Retrieves delegated permissions for all mailboxes and exports to a CSV file in the default directory. .EXAMPLE Get-MailboxPermissions -OutputDir C:\Temp -Encoding UTF32 Retrieves delegated permissions and saves the output to C:\Temp with UTF-32 encoding. .EXAMPLE Get-MailboxPermissions -OutputDir "Reports" -Encoding UTF8 Retrieves delegated permissions and saves the report in the Reports folder with UTF-8 encoding. #> [CmdletBinding()] param ( [string]$outputDir = "Output\Delegated Permissions", [string]$Encoding = "UTF8", [ValidateSet('None', 'Minimal', 'Standard')] [string]$LogLevel = 'Standard', [string]$UserIds ) Set-LogLevel -Level ([LogLevel]::$LogLevel) $summary = @{ TotalMailboxes = 0 MailboxesProcessed = 0 MailboxesWithPermissions = 0 PermissionStats = @{ FullAccess = 0 SendAs = 0 SendOnBehalf = 0 Calendar = 0 Inbox = 0 } StartTime = Get-Date ProcessingTime = $null } Write-LogFile -Message "=== Starting Mailbox Permissions Collection ===" -Color "Cyan" -Level Minimal $date = [datetime]::Now.ToString('yyyyMMddHHmmss') $outputFile = "$($date)-MailboxDelegatedPermissions.csv" if (!(test-path $OutputDir)) { New-Item -ItemType Directory -Force -Name $OutputDir > $null } else { if (!(Test-Path -Path $OutputDir)) { Write-LogFile -Message "[Error] Custom directory invalid: $OutputDir" -Level Minimal -color "Red" } } $outputDirectory = Join-Path $outputDir $outputFile try { Get-EXOMailbox -ResultSize 1 > $null } catch { write-logFile -Message "[INFO] Ensure you are connected to M365 by running the Connect-M365 command before executing this script" -Color "Yellow" -Level Minimal Write-logFile -Message "[ERROR] An error occurred: $($_.Exception.Message)" -Color "Red" -Level Minimal throw } $results = @() Write-LogFile -Message "[INFO] Retrieving mailbox list..." -Level Standard if ($UserIds) { $userIdList = $UserIds -split ',' Write-LogFile -Message "[INFO] Filtering mailboxes for users: $UserIds" -Level Standard $mailboxes = Get-EXOMailbox -ResultSize unlimited -Properties UserPrincipalName, DisplayName, GrantSendOnBehalfTo, RecipientTypeDetails | Where-Object { $userIdList -contains $_.UserPrincipalName } } else { $mailboxes = Get-EXOMailbox -ResultSize unlimited -Properties UserPrincipalName, DisplayName, GrantSendOnBehalfTo, RecipientTypeDetails } $totalMailboxes = $mailboxes.Count $summary.TotalMailboxes = $mailboxes.Count Write-LogFile -Message "[INFO] Found $($summary.TotalMailboxes) mailboxes to process" -Level Standard $current = 0 foreach ($mailbox in $mailboxes) { $summary.MailboxesProcessed++ $current++ if ($LogLevel -eq 'Standard') { Write-Progress -Activity "Checking delegated permissions" -Status "Processing $($mailbox.DisplayName)" -PercentComplete (($current / $totalMailboxes) * 100) } # Get Full Access permissions $fullAccessDetails = Get-MailboxPermission -Identity $mailbox.UserPrincipalName | Where-Object { $_.IsInherited -eq $false -and $_.User -notlike "NT AUTHORITY\SELF" -and $_.User -notlike "DiscoverySearchMailbox" -and $_.User -notlike "S-1-5*" } # Get Send As permissions $sendAsDetails = $null try { $sendAsDetails = Get-RecipientPermission -Identity $mailbox.UserPrincipalName | Where-Object { $_.IsInherited -eq $false -and $_.Trustee -notlike "NT AUTHORITY\SELF" -and $_.User -notlike "DiscoverySearchMailbox" -and $_.Trustee -notlike "S-1-5*" } } catch [System.Management.Automation.CommandNotFoundException] { if ($LogLevel -eq 'Standard') { Write-LogFile -Message "[WARNING] Get-RecipientPermission cmdlet not available. Skipping Send As permissions check for $($mailbox.UserPrincipalName)." -Color "Yellow" -Level Standard } } catch { if ($LogLevel -eq 'Standard') { Write-LogFile -Message "[WARNING] Error getting Send As permissions for $($mailbox.UserPrincipalName): $($_.Exception.Message)" -Color "Yellow" -Level Standard } } # Get Send on Behalf permissions $sendOnBehalfUsers = $mailbox.GrantSendOnBehalfTo | Where-Object {$_ -ne $null} # Get Calendar Folder Permissions $calendarPermissions = @() try { $calendarPermissions = Get-MailboxFolderPermission -Identity "$($mailbox.UserPrincipalName):\Calendar" -ErrorAction Stop | Where-Object { $_.User.DisplayName -notlike "Default" -and $_.User.DisplayName -notlike "Anonymous" -and $_.User.DisplayName -notlike "NT AUTHORITY\SELF" } } catch { } # Get Inbox Folder Permissions $inboxPermissions = @() try { $inboxPermissions = Get-MailboxFolderPermission -Identity "$($mailbox.UserPrincipalName):\Inbox" -ErrorAction Stop | Where-Object { $_.User.DisplayName -notlike "Default" -and $_.User.DisplayName -notlike "Anonymous" -and $_.User.DisplayName -notlike "NT AUTHORITY\SELF" } } catch { } if ($fullAccessDetails) { $summary.PermissionStats.FullAccess += ($fullAccessDetails | Measure-Object).Count } if ($sendAsDetails) { $summary.PermissionStats.SendAs += ($sendAsDetails | Measure-Object).Count } if ($sendOnBehalfUsers) { $summary.PermissionStats.SendOnBehalf += ($sendOnBehalfUsers | Measure-Object).Count } if ($calendarPermissions) { $summary.PermissionStats.Calendar += ($calendarPermissions | Measure-Object).Count } if ($inboxPermissions) { $summary.PermissionStats.Inbox += ($inboxPermissions | Measure-Object).Count } $permissionEntry = [PSCustomObject]@{ UserPrincipalName = $mailbox.UserPrincipalName DisplayName = $mailbox.DisplayName RecipientTypeDetails = $mailbox.RecipientTypeDetails # Full Access Details FullAccessUsers = ($fullAccessDetails | ForEach-Object { $user = Get-EXORecipient $_.User -ErrorAction SilentlyContinue if ($user) { "$($user.DisplayName) ($($user.PrimarySmtpAddress))" } else { $_.User } }) -join '; ' FullAccessPermissions = ($fullAccessDetails | ForEach-Object { $user = Get-EXORecipient $_.User -ErrorAction SilentlyContinue $userName = if ($user) { "$($user.DisplayName) ($($user.PrimarySmtpAddress))" } else { $_.User } "$userName - Rights: $($_.AccessRights -join ','), Deny: $($_.Deny), Inheritance: $($_.InheritanceType)" }) -join ' | ' # Send As Details SendAsUsers = ($sendAsDetails | ForEach-Object { $user = Get-EXORecipient $_.Trustee -ErrorAction SilentlyContinue if ($user) { "$($user.DisplayName) ($($user.PrimarySmtpAddress))" } else { $_.Trustee } }) -join '; ' SendAsPermissions = ($sendAsDetails | ForEach-Object { $user = Get-EXORecipient $_.Trustee -ErrorAction SilentlyContinue $userName = if ($user) { "$($user.DisplayName) ($($user.PrimarySmtpAddress))" } else { $_.Trustee } "$userName - Type: $($_.AccessControlType), Rights: $($_.AccessRights), Inheritance: $($_.InheritanceType)" }) -join ' | ' # Send on Behalf Details SendOnBehalfUsers = ($sendOnBehalfUsers | ForEach-Object { $user = Get-EXORecipient $_ -ErrorAction SilentlyContinue if ($user) { "$($user.DisplayName) ($($user.PrimarySmtpAddress))" } else { $_ } }) -join '; ' # Calendar Permissions CalendarUsers = ($calendarPermissions | ForEach-Object { "$($_.User.DisplayName) ($($_.User.ADRecipient.PrimarySmtpAddress)) - $($_.AccessRights)" }) -join '; ' CalendarPermissions = ($calendarPermissions | ForEach-Object { "$($_.User.DisplayName): $($_.AccessRights)" }) -join ' | ' # Inbox Permissions InboxUsers = ($inboxPermissions | ForEach-Object { "$($_.User.DisplayName) ($($_.User.ADRecipient.PrimarySmtpAddress)) - $($_.AccessRights)" }) -join '; ' InboxPermissions = ($inboxPermissions | ForEach-Object { "$($_.User.DisplayName): $($_.AccessRights)" }) -join ' | ' # Permission Counts FullAccessCount = ($fullAccessDetails | Measure-Object).Count SendAsCount = ($sendAsDetails | Measure-Object).Count SendOnBehalfCount = ($sendOnBehalfUsers | Measure-Object).Count CalendarPermissionCount = ($calendarPermissions | Measure-Object).Count InboxPermissionCount = ($inboxPermissions | Measure-Object).Count } if ($permissionEntry.FullAccessCount -gt 0 -or $permissionEntry.SendAsCount -gt 0 -or $permissionEntry.SendOnBehalfCount -gt 0 -or $permissionEntry.CalendarPermissionCount -gt 0 -or $permissionEntry.InboxPermissionCount -gt 0) { $summary.MailboxesWithPermissions++ } $results += $permissionEntry } $results | Export-Csv -Path $outputDirectory -NoTypeInformation -Encoding $Encoding $summary.ProcessingTime = (Get-Date) - $summary.StartTime Write-LogFile -Message "`n=== Mailbox Permissions Analysis Summary ===" -Color "Cyan" -Level Standard Write-LogFile -Message "Processing Statistics:" -Level Standard Write-LogFile -Message " Total Mailboxes: $($summary.TotalMailboxes)" -Level Standard Write-LogFile -Message " Mailboxes Processed: $($summary.MailboxesProcessed)" -Level Standard Write-LogFile -Message " Mailboxes with Permissions: $($summary.MailboxesWithPermissions)" -Level Standard Write-LogFile -Message "`nPermission Counts:" -Level Standard Write-LogFile -Message " Full Access: $($summary.PermissionStats.FullAccess)" -Level Standard Write-LogFile -Message " Send As: $($summary.PermissionStats.SendAs)" -Level Standard Write-LogFile -Message " Send on Behalf: $($summary.PermissionStats.SendOnBehalf)" -Level Standard Write-LogFile -Message " Calendar: $($summary.PermissionStats.Calendar)" -Level Standard Write-LogFile -Message " Inbox: $($summary.PermissionStats.Inbox)" -Level Standard Write-LogFile -Message "`nOutput:" -Level Standard Write-LogFile -Message " Output File: $outputDirectory" -Level Standard Write-LogFile -Message " Processing Time: $($summary.ProcessingTime.ToString('mm\:ss'))" -Color "Green" -Level Standard } |