Add Shared Mailbox Permissions

In this post we’ll look at a tool I put together to quickly and easily add/update permissions for shared mailboxes while also informing the user, and updating your ticketing system.

function Add-SharedMailboxPermission {
    Developer:  Mike Polselli
    PSVersion:  5.1
    Language:   PowerShell
    Purpose:    Gives a specified user FullControl access of a shared mailbox(es).
                Can also add SendAs access.
                Additionally an email will be sent to the user and an update will be added to the ticket.
    Displays helpful information about the script.
    Specifies the user(s) you wish to give shared mailbox access to.
    Specifies the shared mailbox(es) you wish update access on.
.PARAMETER TicketNumber
    Enter the ticket number of the request for shared mailbox access. 
    Grants SendAs access to the user specified on the shared mailbox specified.
    Add-SharedMailboxPermission -Help
    Add-SharedMailboxPermission -Identity 'Mike Polselli' -Mailbox 'SharedMailbox' -TicketNumber 12345
    Add-SharedMailboxPermission -Identity 'Mike Polselli' -Mailbox 'SharedMailbox','SharedMailbox Two' -TicketNumber 12345
    Add-SharedMailboxPermission -Identity 'Mike Polselli' -Mailbox 'SharedMailbox','SharedMailbox Two' -TicketNumber 12345 -SendAs
    [cmdletbinding(DefaultParameterSetName = "Primary")]    
    param (
        [Parameter(ParameterSetName = "Primary", Mandatory = $true, Position = 0)][string[]]$Identity,
        [Parameter(ParameterSetName = "Primary", Mandatory = $true, Position = 1)][string[]]$Mailbox,
        [Parameter(ParameterSetName = "Primary", Mandatory = $true, Position = 2)][string]$TicketNumber,
        [Parameter(ParameterSetName = "Primary", Mandatory = $false, Position = 3)][switch]$SendAs,
        [Parameter(ParameterSetName = "Help")][switch]$Help
    if ($Help) {
        Get-Help $MyInvocation.MyCommand.Name -Full | more
    try {
        $Mailboxes = @()
        Connect-Exchange -Commands 'Add-MailboxPermission', 'Add-RecipientPermission' -ErrorAction Stop
        foreach ($Id in $Identity) {
            foreach ($MB in $Mailbox) {
                Write-Output "Adding $Id to $MB."
                $UserName = Get-ADUser -Filter { DisplayName -eq $Id } -ErrorAction Stop
                $Properties = @{
                    Identity     = $MB
                    User         = $UserName.SamAccountName
                    AccessRights = 'FullAccess'
                    Confirm      = $false
                    ErrorAction  = 'Stop'
                Add-MailboxPermission @Properties | Out-Null
                if ($SendAs) {
                    $Properties = @{
                        Identity     = $MB
                        AccessRights = 'SendAs'
                        Trustee      = $UserName.SamAccountName
                        Confirm      = $false
                        ErrorAction  = 'Stop'
                    Add-RecipientPermission @Properties | Out-Null

                # Capitalizes the mailbox name.
                $TextInfo = (Get-Culture).TextInfo
                $MailboxCap = $TextInfo.ToTitleCase($MB)
                $Mailboxes += $MailboxCap
            $Table = @{}
            foreach ($MB in $Mailboxes) {
            [System.Collections.ArrayList]$Output = $Table.GetEnumerator() | Select-Object Value | ConvertTo-Html -Fragment -As Table

            $HelpDeskURL = ""
            $Body = @"
    <style type="text/css">
        p#Note {
            font-weight: bold;
            font-size: 0.8em;

        span.Bold {
            font-weight: bold;

        Hello $($UserName.Name),<br/>
        You have been given access to the following mailbox(es).<br/>
        <span class="Bold">$Output</span>
        The mailbox(es) will show up in your Outlook in roughly 30-45 minutes.<br/>
        If the mailbox(es) have not shown up in that time please restart your Outlook and wait an additional 5-10 minutes.<br/>
        If you have any questions or concerns please direct them <span class="Bold"><a title ="$TicketNumber" href="$HelpDeskURL">here</a></span><br/>
        Best Regards,<br/>
        <p id="Note">Note: Do not reply to this email, this was an automated task and this mailbox is not monitored.</p>
            $Properties = @{
                To          = ''
                Cc          = $UserName.UserPrincipalName
                From        = ''
                Subject     = "[Ticket #$TicketNumber]"
                Body        = $Body
                BodyAsHTML  = $true
                SMTPServer  = 'serverAddress'
                UseSSL      = $true
                ErrorAction = 'Stop'
            Send-MailMessage @Properties
            Write-Output "Email sent to $Id. Ticket #$TicketNumber updated."
        Get-PSSession | Remove-PSSession
    catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
        Write-Warning "$Identity not found in AD. Please check AD."
        Get-PSSession | Remove-PSSession
    catch {
        Write-Warning $PSItem.Exception.Message
        Get-PSSession | Remove-PSSession

$IdentityBlock = {
    param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameter)

    (Get-ADUser -Filter * -SearchBase 'OU=Users,DC=Contoso,DC=org').Name | Where-Object {
        $PSItem -like "$WordToComplete*"
    } | ForEach-Object {

Register-ArgumentCompleter -CommandName Add-SharedMailboxPermission -ParameterName Identity -ScriptBlock $IdentityBlock

$MailboxBlock = {
    param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameter)

    (Import-Csv -Path \\$env:USERDNSDOMAIN\PowerShell\AllMailboxes.csv).Name | Where-Object {
        $PSItem -like "$WordToComplete*"
    } | ForEach-Object {

Register-ArgumentCompleter -CommandName Add-SharedMailboxPermission -ParameterName Mailbox -ScriptBlock $MailboxBlock

This tool leverages the Register-ArgumentCompleter cmdlet in a couple of spots, if you are unfamiliar with this cmdlet you can see it in action here.

I recommend using it along with a CSV or Excel file for the mailbox names as well. Trying to remember all of your shared mailbox names can be difficult or impossible if you have a ton and querying a list live will take quite some time.

See below for a quick live demo.