Share via

Mailbox permissions syntax

Glenn Maxwell 13,721 Reputation points
2025-08-18T21:50:10.9+00:00

Hi All

I have a CSV file containing email addresses(both user mailboxes and shared mailboxes), and I need to fetch the following information: an export of all mailboxes along with the users who have access to them. This should include mailbox delegation permissions (Full Access, Send As, and Send On Behalf). Using the script below, I am able to generate output. Could you please guide me if any changes are required in the script? I would like the output to be in the format shown below. in the csv file should i use upn or email address. i am using exchange 2019 hybrid environment. all my users are created in onprem and migrated to online.

Display Name, email address, Full Access Send As, Send On Behalf

param(
    [string]$InputCSV  = "C:\temp\input.csv",   # Input CSV file
    [string]$ExportCSV = "C:\Temp\output.csv" # Output CSV file
)
$Results = @()
$Mailboxes = Import-Csv -Path $InputCSV

foreach ($Mailbox in $Mailboxes) {
    $ID = $Mailbox.UserPrincipalName
    if (Get-Mailbox $ID -ErrorAction SilentlyContinue) {
        # Full-Access Permissions
        $fullAccess = Get-MailboxPermission $ID | Where-Object { $_.IsInherited -eq $False } |
            Select-Object @{n="Mailbox";e={$ID}}, Identity, User, AccessRights
        $Results += $fullAccess
       
        # Send-As Permissions
        $sendAs = Get-RecipientPermission $ID | Where-Object { $_.IsInherited -eq $False } |
            Select-Object @{n="Mailbox";e={$ID}}, Identity, Trustee, AccessRights
        $Results += $sendAs
        
       # Send-On-Behalf-Of Permissions
        $sob = Get-Mailbox $ID | 
            Select-Object @{n="Mailbox";e={$ID}}, Identity, GrantSendOnBehalfTo
        $Results += $sob
    }
    else {
        Write-Host "No mailbox found for $ID"
    }
}
# Export results to CSV
$Results | Export-Csv -Path $ExportCSV -NoTypeInformation -Encoding UTF8
Write-Host "Export completed. Results saved to $ExportCSV"

Exchange Online
Exchange Online

A cloud-based service included in Microsoft 365, delivering scalable messaging and collaboration features with simplified management and automatic updates.

0 comments No comments

Answer accepted by question author

Anonymous
2025-08-19T04:49:51.6133333+00:00

Hi @Glenn Maxwell

Thank you for your question. I’ve reviewed your script and identified a core logic issue that could prevent it from generating a clean, correctly formatted CSV file. 

To resolve this, I’ve created and tested an improved version that outputs exactly in your requested format. Rather than combining permissions from different commands separately, the updated script gathers all permissions for each mailbox first, then builds a custom object to create a well‑organized report with the columns: Display Name, Email Address, Full Access, Send As, and Send On Behalf

This approach groups all permissions for each mailbox into a single row and exports them cleanly to a CSV, making your report much easier to read and use. 

param( 
    [string]$InputCSV  = "C:\temp\input.csv",   # Input CSV file path 
    [string]$ExportCSV = "C:\temp\output.csv"   # Output CSV file path 
) 
  
$Results = @() 
$Mailboxes = Import-Csv -Path $InputCSV 
  
foreach ($Mailbox in $Mailboxes) { 
    $ID = $Mailbox.UserPrincipalName 
    $mbx = Get-Mailbox $ID -ErrorAction SilentlyContinue 
  
    if ($mbx) { 
        $DisplayName  = $mbx.DisplayName 
        $EmailAddress = $mbx.PrimarySmtpAddress.ToString() 
  
        # Retrieve Full Access permissions (exclude inherited, SELF, and SID accounts) 
        $fullAccess = Get-MailboxPermission $ID | Where-Object { 
            $_.IsInherited -eq $false -and 
            $_.User -notlike "NT AUTHORITY\SELF" -and 
            $_.User -notlike "S-1-5-*" 
        } 
        $fullAccessUsers = $fullAccess | Select-Object -ExpandProperty User -Unique | ForEach-Object { $_.ToString() } -join "; " 
  
        # Retrieve Send As permissions 
        $sendAs = Get-RecipientPermission $ID | Where-Object { 
            $_.IsInherited -eq $false 
        } 
        $sendAsUsers = $sendAs | Select-Object -ExpandProperty Trustee -Unique | ForEach-Object { $_.ToString() } -join "; " 
  
        # Retrieve Send On Behalf permissions 
        $sendOnBehalfUsers = $mbx.GrantSendOnBehalfTo | ForEach-Object { 
            (Get-Recipient $_).Name 
        } -join "; " 
  
        # Create a custom object with mailbox and permissions info 
        $Results += [PSCustomObject]@{ 
            "Display Name"   = $DisplayName 
            "Email Address"  = $EmailAddress 
            "Full Access"    = $fullAccessUsers 
            "Send As"        = $sendAsUsers 
            "Send On Behalf" = $sendOnBehalfUsers 
        } 
    } 
    else { 
        Write-Host "No mailbox found for $ID" 
    } 
} 
  
# Export results to CSV 
$Results | Export-Csv -Path $ExportCSV -NoTypeInformation -Encoding UTF8 
  
Write-Host "Export completed. Results saved to $ExportCSV" 

For your input CSV file, you may use either the UserPrincipalName (UPN) or the primary email address. In a hybrid Exchange 2019 environment, I recommend using the UserPrincipalName attribute, as it is the most reliable and consistent identifier for mailboxes across both on‑premises and online environments. 

Example CSV format: 

input.csv
UserPrincipalName 
******@yourdomain.com 
******@yourdomain.com 

Please ensure your input CSV contains valid UPNs or primary email addresses matching mailboxes in your Exchange environment. 

Once you’ve run this updated script, let me know how it goes. I’ll be happy to help with any further adjustments or troubleshooting you may need.


If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".   

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Was this answer helpful?

0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.