Exchange Online: Export shared mailboxes permissions to CSV

Sometimes we have a need to audit permissions on our mailboxes. In case below I prepared a function in PowerShell which list or generate CSV file with shared mailboxes permissions in Microsoft 365 environment. In both Exchange and Exchange Online we can create shared mailboxes and share them with other users. To do that we must assign proper permissions to our Microsoft 365 users who have mailboxes in Exchange Online.

In Exchange and also Exchange Online for shared mailboxes we have 2 types of permissions we can set from Exchange Admin Center:

  • Full Access (or Read and Manage) – the Full Access permission allows the delegate to log on to this shared mailbox and behave as the owner of the mailbox.
  • Send As – the Send As permission allows the delegate to send email from shared mailbox. From the recipient’s perspective, the email is sent by this shared mailbox.

Of course we could see those permissions from panel but this is a bit problem where we want to list permission for whole organization and every shared mailbox. Thanks to PowerShell cmdlets for Exchange Online module we are able to list permission for user(s) who have Full Access permission to shared mailbox with usage of:

Get-MailboxPermission (ExchangePowerShell) | Microsoft Docs

and for Send As permissions:

Get-RecipientPermission (ExchangePowerShell) | Microsoft Docs

function Export-SharedMailboxesPermissions {
    <#
    .SYNOPSIS
    Script for generating shared mailboxes list with permissions assigned to users in Exchange Online.
 
    .DESCRIPTION
    Script gets list of all shared mailboxes in Exchange Online and list permissions assigned to users and also can export to csv file.
 
    .PARAMETER CSVFile
    Directory where generated csv file will be stored.
 
    .NOTES
    Version:        0.1;
 
    .EXAMPLE
    . .\Export-SharedMailboxesPermissions.ps1 
    Export-SharedMailboxesPermissions

    .EXAMPLE
    . .\Export-SharedMailboxesPermissions.ps1
    Export-SharedMailboxesPermissions -C "C:\SharedMailboxes.csv"
    #>
    Param
    ( 
        # Cmdlet switch to export generated shared mailboxes permissions to csv file
        [parameter(Position=0, ValueFromPipeline=$True, Mandatory=$false, ValueFromPipelineByPropertyName=$True)]
        [alias('C')]
        $CSVFile
    )
    Begin {
        # Check connection to Exchange Online
        try {
            $psSessions = Get-PSSession | Select-Object -Property State, Name
            if (((@($psSessions) -like '@{State=Opened; Name=ExchangeOnlineInternalSession*').Count -eq 0)) { 
                Get-Mailbox -ResultSize:1 -ErrorAction Stop
            }
        }
        catch {
            Write-Host "Not connected to Exchange Online, try connect typing Connect-ExchangeOnline before running this script" -BackgroundColor DarkRed 
        }
    }
    Process {
        # Get shared mailboxes from organization
        $SharedMailboxes = @(Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize:Unlimited)
        # For each shared mailboxes take some variables
        foreach ($SharedMailbox in $SharedMailboxes) { 
            # Shared mailbox primary SMTP Address
            $Email = $SharedMailbox.PrimarySmtpAddress 
            # Shared mailbox display name
            $Identity = $SharedMailbox.Identity
            # FullAccess permissions from non-system accounts (only user accounts)
            $FAMailboxPermissions = @(Get-MailboxPermission $SharedMailbox.UserPrincipalName | Where-Object {($_.User -like '*@*')})
            # SendAs permissions from non-system accounts (only user accounts)          
            $SAMailboxPermissions = @(Get-RecipientPermission $Email | Where-Object {($_.Trustee -like '*@*')})   
            # If CSVFile switch is used
            if ($CSVFile) {
                # If shared mailbox have more than 1 user assigned to permissions 
                if ($FAMailboxPermissions.Count -gt 1 -OR $SAMailboxPermissions.Count -gt 1) {
                    # For FullAccess permissions assigned to shared mailbox   
                    foreach ($row in $FAMailboxPermissions) {
                        # Create CSV row and append to file
                        $CSVOutput = New-Object PSObject -Property @{  
                            "Shared Mailbox Email Address" = $Email
                            "Identity" = $Identity 
                            "User" = Get-User $row.User | Select-Object -ExpandProperty Identity   
                            "FullAccess Permissions" = $row.AccessRights
                            "SendAs Permissions" =  $SAMailboxPermissions | Where-Object {$_.Trustee -eq $row.User} | Select-Object -ExpandProperty AccessRights
                        }                           
                        $CSVOutput | Select-Object "Shared Mailbox Email Address", "Identity", "User", "FullAccess Permissions", "SendAs Permissions" `
                        | Export-Csv -Path $CSVFile -Append -Encoding UTF8 -NoTypeInformation
                    }
                    # For accounts with SendAs permissions to shared mailbox    
                    foreach ($row in $SAMailboxPermissions) {
                        if (-not([string]$row.Trustee -in $FAMailboxPermissions.User)) {
                            $CSVOutput = New-Object -TypeName PSObject -Property @{
                                "Shared Mailbox Email Address" = $Email
                                "Identity" = $Identity 
                                "User" = Get-User $row.Trustee | Select-Object -ExpandProperty Identity   
                                "FullAccess Permissions" = ""
                                "SendAs Permissions" =  $SAMailboxPermissions | Where-Object {$_.Trustee -eq $row.Trustee} | Select-Object -ExpandProperty AccessRights
                            }
                            $CSVOutput | Select-Object "Shared Mailbox Email Address", "Identity", "User", "FullAccess Permissions", "SendAs Permissions" `
                            | Export-Csv -Path $CSVFile -Append -Encoding UTF8 -NoTypeInformation
                        }                        
                    }                      
                # If shared mailbox have 1 user assigned to permission
                } elseif ($FAMailboxPermissions.Count -eq 1 -OR $SAMailboxPermissions.Count -eq 1) {
                    if ($FAMailboxPermissions.Count -eq 1) {
                        $User = $FAMailboxPermissions.User 
                    } else {
                        $User = Get-User $SAMailboxPermissions.Identity
                    }
                    $CSVOutput = New-Object -TypeName PSObject -Property @{
                        "Shared Mailbox Email Address" = $Email
                        "Identity" = $Identity 
                        "User" = $User    
                        "FullAccess Permissions" = $FAMailboxPermissions.AccessRights
                        "SendAs Permissions" = $SAMailboxPermissions.AccessRights 
                    }
                    $CSVOutput | Select-Object "Shared Mailbox Email Address", "Identity", "User", "FullAccess Permissions", "SendAs Permissions" `
                    | Export-Csv -Path $CSVFile -Append -Encoding UTF8 -NoTypeInformation          
                } else {
                    Write-Host "Shared mailbox: " $Email " do not have permissions assigned"
                }
            # Write output with permissions assigned to user in console       
            } else {
                Write-Host Shared Mailbox Email Address: $Email -BackgroundColor DarkGray
                if ($FAMailboxPermissions -OR $SAMailboxPermissions) {
                    foreach ($user in $FAMailboxPermissions) {
                        $Username = Get-User $user.User
                        Write-Host -> User: $Username.Identity " " -NoNewline 
                        Write-Host Email: $Username.WindowsEmailAddress " " -ForegroundColor Green -NoNewline
                        $SendA = $SAMailboxPermissions | Where-Object {($_.Trustee -eq $Username.UserPrincipalName)}     
                        Write-Host Access Rights: $user.AccessRights $SendA.AccessRights -ForegroundColor Cyan
                    }
                    foreach ($user in $SAMailboxPermissions) {
                        if (-not($user.Trustee -in $FAMailboxPermissions.User)) {
                            $Username = Get-User $user.Trustee
                            Write-Host -> User: $Username.Identity " " -NoNewline 
                            Write-Host Email: $Username.WindowsEmailAddress " " -ForegroundColor Green -NoNewline    
                            Write-Host Access Rights: $user.AccessRights -ForegroundColor Cyan  
                        } 
                    }       
                } 
            }      
        }     
    }
    End {

    }
}

Running ExportSharedMailboxesPermissions function

Ok so let’s run function in PowerShell without parameter and list users and theirs permissions assigned to shared mailboxes in Exchange Online.

Now we run function with “C” switch and generate CSV file.

Running function and generate CSV file
CSV file generated with function ExportSharedMailboxesPermissions

In code of my function I want to share my point of view to case described in that post. I don’t have big experience in PowerShell scripting and this function was created because I have that need in my work. I think that it will be helpful for you.

Other articles in Microsoft 365 category.

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments