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 {
    <#
.DESCRIPTION
    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.
.PARAMETER Help
    Displays helpful information about the script.
.PARAMETER Identity
    Specifies the user(s) you wish to give shared mailbox access to.
.PARAMETER Mailbox
    Specifies the shared mailbox(es) you wish update access on.
.PARAMETER TicketNumber
    Enter the ticket number of the request for shared mailbox access. 
.PARAMETER SendAs
    Grants SendAs access to the user specified on the shared mailbox specified.
.EXAMPLE
    Add-SharedMailboxPermission -Help
.EXAMPLE
    Add-SharedMailboxPermission -Identity 'Mike Polselli' -Mailbox 'SharedMailbox' -TicketNumber 12345
.EXAMPLE
    Add-SharedMailboxPermission -Identity 'Mike Polselli' -Mailbox 'SharedMailbox','SharedMailbox Two' -TicketNumber 12345
.Example
    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
        break
    }
    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) {
                $Table.Add($MB,$MB)
            }
            [System.Collections.ArrayList]$Output = $Table.GetEnumerator() | Select-Object Value | ConvertTo-Html -Fragment -As Table
            $Output.RemoveAt(2)

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

        span.Bold {
            font-weight: bold;
        }
    </style>
    </head>

    <body>
        Hello $($UserName.Name),<br/>
        You have been given access to the following mailbox(es).<br/>
        <br>
        <span class="Bold">$Output</span>
        <br/>
        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/>
        <br/>
        Best Regards,<br/>
        CompanyName
        <p id="Note">Note: Do not reply to this email, this was an automated task and this mailbox is not monitored.</p>
    </body>
"@
            $Properties = @{
                To          = 'helpdesk@company.com'
                Cc          = $UserName.UserPrincipalName
                From        = 'noreply@company.com'
                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 {
        "'$PSItem'"
    }
}

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 {
        "'$PSItem'"
    }
}

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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s