During a migration you might need to add a bunch of new users to a bunch of shared mailboxes. Now you could go about doing that in different ways, but I made this script to automatically give full mailbox permission and Send As permission to a mailbox from a CSV file with a list of Users and Mailboxes in the file. Headers are UPN and Mailbox respectively and will be needed for the script
UPN | Mailbox |
---|---|
user1@ldlnet.net | mailbox1@ldlnet.net |
user2@ldlnet.net | mailbox1@ldlnet.net |
user3@ldlnet.net | mailbox1@ldlnet.net |
user4@ldlnet.net | mailbox2@ldlnet.net |
user5@ldlnet.net | mailbox2@ldlnet.net |
user1@ldlnet.net | mailbox3@ldlnet.net |
user3@ldlnet.net | mailbox3@ldlnet.net |
You want to save the file to your C:\Drive and note the path as that will be used as a parameter in the script. This code will Connect to Exchange Online, it will download it if you need it, it will then authenticate you. Once authenticated, it will pull the CSV values. Next it will loop through each row in grant the permissions accordingly, it will let you know if there are any errors or warning and display a final listing of the permissions and send as permissions for the mailbox. All this will be logged in a log file in a created directory on your C drive.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | <# .SYNOPSIS Adds full mailbox permissions and send as permissions to users and mailboxes you specify in a CSV file. There is no option for one or the other, this script will always do both and only do full access and send. I might upgrade this in future versions if I find some scripts out there that will do this better. The CSV must contain two headers UPN and Mailbox. One to One mapping user to mailbox. You will need to add another entry to add same user to another mailbox or multiple users to the same mailbox. Example CSV UPN,Mailbox lance@me.com,FirstMailbox@me.com lance@me.com,SecondMailbox@me.com kulwinder@me.com,FirstMailbox@me.com ***YOU MUST INPUT THE PATH TO THE CSV FILE IN THE CMDLET!*** .NOTES Name: Add-FullAndSendToMailboxFromCSV.ps1 Author: Lance Lingerfelt Version: 1.0 Modify Date: 2024-07-15 Parameter Values: $CSVPath is manditory and sets the path where your input file with your user and mailbox values CSV is located. Log File Location: Path = "C:\BaringsScripts\Logs\Add-FullAndSendToMailboxFromCSV/<MM>/<DD>/" Name = "<RunTimeDate_nnn>.log" .EXAMPLE Run the Script with the Retention Policy as Default MRM Policy .\Add-FullAndSendToMailboxFromCSV.ps1 -CSVPath 'C:\Temp\filename.csv' #> [CmdletBinding(SupportsShouldProcess = $true)] Param( [Parameter(Mandatory = $true)] [string] $CSVPath ) # ================================================ # DO NOT MODIFY BEGIN # ================================================ $ErrorActionPreference = 'SilentlyContinue' $Date = Get-Date -Format "MM/dd/yyyy" # Set Logging Configuration $Log = [PSCustomObject]@{ Path = "C:\BaringsScripts\Logs\Add-FullAndSendToMailboxFromCSV" Name = "$($Date).log" } # ================================================ # DO NOT MODIFY END # ================================================ # ================================================ # SCRIPT BEGIN # ================================================ # Create New Logger Instance if Enabled if ($PSCmdlet.ShouldProcess("Create New Logger Instance", $Log.Path)) { # Import Logger Module try { if ( -not (Get-Module -Name PoShLog -ListAvailable) ) { Install-Module -Name PoShLog -Scope CurrentUser -Force } else { Import-Module -Name PoShLog -Force } } catch { Write-Host -Object "Unable to import logger module. Error: $($_.Exception.Message)" exit 1 } # Create New Logger Instance. Verbose logging level. Log to file and console. Start Logger. New-Logger | ` Set-MinimumLevel -Value Verbose | ` Add-SinkFile -Path "$($Log.Path)\$($Log.Name)" -OutputTemplate ` '{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}' -RollingInterval Day | ` Add-SinkConsole | ` Start-Logger # Log Start of Script Write-VerboseLog "Start of Script." Write-Host "Start of Script." -ForegroundColor DarkGreen } if ($PSCmdlet.ShouldProcess("Create New Exchange Online Instance", $Log.Path)) { # Import ExchangeOnlineManagement Module try { if ( -not (Get-Module -Name ExchangeOnlineManagement -ListAvailable) ) { Install-Module -Name ExchangeOnlineManagement -Scope CurrentUser -Force } else { Import-Module -Name ExchangeOnlineManagement -Force } } catch { Write-Host -Object "Unable to import ExchangeOnlineManagement module. Error: $($_.Exception.Message)" Write-VerboseLog "Unable to import ExchangeOnlineManagement module. Error: $($_.Exception.Message)" exit 1 } } #Connect Exchange Online Write-Host "Connecting To Exchange Online" -ForegroundColor Green Write-VerboseLog "Connecting To Exchange Online" Connect-ExchangeOnline -ShowBanner:$False #Import the CSV file form the cmdlet input Write-Host "Importing CSV Values" -ForegroundColor Green Write-VerboseLog "Importing CSV Values" $MailboxIds = Import-CSV -Path $CSVPath #Add the Full Mailbox Access and Send-As Permissions based on the data in the CSV file. Foreach ($MailboxId in $MailboxIds) { # Check if the user specified in Group exists $userExists = @() $userExists += Get-User -Identity $MailboxId.UPN -ErrorAction SilentlyContinue -Resultsize Unlimited $userExists += Get-Contact -Identity $MailboxId.UPN -ErrorAction SilentlyContinue -ResultSize Unlimited # Check if the distribution group specified in GroupName exists $mailboxExists = Get-Mailbox -Identity $MailboxID.Mailbox -ErrorAction SilentlyContinue if ($userExists -and $mailboxExists) { #Set the Warning variable #$warnvar = "This is the warning variable" # Both user and group exist, so proceed with updating the permissions try { Write-Host "Adding Full Mailbox Access Permission for User: [$($MailboxId.UPN)] to mailbox: [$($mailboxId.Mailbox)]" -ForegroundColor Green Write-VerboseLog "Adding Full Mailbox Access Permission for User: [$($MailboxId.UPN)] to mailbox: [$($mailboxId.Mailbox)]" Add-MailboxPermission -Identity $MailboxId.Mailbox -User $MailboxId.UPN -AccessRights FullAccess -AutoMapping:$True -ErrorAction SilentlyContinue -WarningVariable warnvar if ($warnvar) { Write-VerboseLog "You had a warning: $($warnvar) Recorded in the Log File in: $($Log.Path)" } else { Write-VerboseLog "No Warnings Recorded" } } catch { Write-Host "Failed to add full access permission for $($MailboxId.UPN) Error: $($_.Exception.Message)" -ForegroundColor Red Write-VerboseLog "Failed to add full access permission for $($MailboxId.UPN) Error: $($_.Exception.Message)" } try { Write-Host "Adding Send-As Permission for User: [$($MailboxId.UPN)] to mailbox: [$($MailboxId.Mailbox)]" -ForegroundColor Cyan Write-VerboseLog "Adding Send-As Permission for User: [$($MailboxId.UPN)] to mailbox: [$($MailboxId.Mailbox)]" Add-RecipientPermission -Identity $MailboxId.Mailbox -AccessRights SendAs -Trustee $MailboxId.UPN -Confirm:$False -ErrorAction SilentlyContinue -WarningVariable warnvar | Out-Null if ($warnvar) { Write-VerboseLog "You had a warning: $($warnvar) Recorded in the Log File in: $($Log.Path)" } else { Write-VerboseLog "No Warnings Recorded" } } catch { Write-Host "Failed to add Send-As permission for [$($MailboxId.UPN)] Error: $($_.Exception.Message)" -ForegroundColor Red Write-VerboseLog "Failed to add Send-As permission for [$($MailboxId.UPN)] Error: $($_.Exception.Message)" } } elseif (-not $mailboxExists) { # Mailbox doesn't exist, display a message Write-Host "The mailbox [$($MailboxId.Mailbox)] specified in Mailbox column doesn't exist. Skipping." -ForegroundColor DarkRed Write-VerboseLog "The mailbox [$($MailboxId.Mailbox)] specified in Mailbox column doesn't exist. Skipping." } elseif (-not $userExists) { # User doesn't exist, display a message Write-Host "User [$(MailboxID.UPN)] specified in User column doesn't exist. Skipping." -ForegroundColor DarkRed Write-VerboseLog "User [$(MailboxID.UPN)] specified in User column doesn't exist. Skipping." } } #Create an array of mailbox identity values to use for cmdlets below. $mbxlist = @() foreach ($MailboxId in $MailboxIds){ $mbxlist += $mailboxId.Mailbox } #Get the final list of mailbox vaules that are unique $finalmbxlist =@() $finalmbxlist += $mbxlist | Get-Unique #Show the mailbox permissions of each mailbox upon completion of adding the users to each mailbox foreach ($finalmbx in $finalmbxlist) { Write-Host "Showing Final Mailbox Permissions for Mailbox: [$($finalmbx)]" -ForegroundColor Green Write-VerboseLog "Showing Final Mailbox Permissions for Mailbox: [$($finalmbx)]" Get-MailboxPermission -Identity $finalmbx | Format-Table -AutoSize -Wrap #Show the Send-As permissions for each mailbox upon completion of adding the users to each mailbox Write-Host "Showing Final Send-As Permissions for Mailbox: [$($finalmbx)]" -ForegroundColor Cyan Write-VerboseLog "Showing Final Send-As Permissions for Mailbox: [$($finalmbx)]" Get-RecipientPermission -Identity $finalmbx | Format-Table -AutoSize -Wrap } # Disconnect from Microsoft 365 PowerShell sessions Write-VerboseLog "Disconnecting Exchange Online module" Write-Host "Disconnecting Exchange Online module" -ForegroundColor Red Disconnect-ExchangeOnline -Confirm:$False Write-VerboseLog "End of Script" Write-Host "End of Script" -ForegroundColor DarkRed # ================================================ # SCRIPT END # ================================================ |
Look over the code and let me know if you have better way to handle the warnings and errors. I could not put the warning messages in the catch statement and had to do an if/else statement for the warning handling. I also could not use the WarningAction of SilentlyContinue and log the warning as it would NOT display in the variable, Not to worry since you see the warning and then review it in the log file if needed. I would like to put the output of the final permissions settings in the log file rather than just display it, but if you really need that, put it to an array and then to a CSV file. I have done that in other scripts and it works well.
I plan to update this script with modifications to let you add what permissions you want for the Recipient Permissions and Mailbox Permissions. I would also like to add menu functionality to provide a user to perform multiple mailbox tasks via the menu as in one of my other scripts based on the DNS PowerShell tool.
About Lance Lingerfelt
Lance Lingerfelt is an M365 Specialist and Evangelist with over 20 years of experience in the Information Technology field. Having worked in enterprise environments to small businesses, he is able to adapt and provide the best IT Training and Consultation possible. With a focus on AI, the M365 Stack, and Healthcare, he continues to give back to the community with training, public speaking events, and this blog.