{"id":196444,"date":"2024-07-19T07:40:00","date_gmt":"2024-07-19T12:40:00","guid":{"rendered":"https:\/\/itblog.ldlnet.net\/?p=196444"},"modified":"2024-07-19T07:40:15","modified_gmt":"2024-07-19T12:40:15","slug":"add-fullandsendtomailboxfromcsv-ps1","status":"publish","type":"post","link":"https:\/\/itblog.ldlnet.net\/index.php\/2024\/07\/19\/add-fullandsendtomailboxfromcsv-ps1\/","title":{"rendered":"Add-FullAndSendToMailboxFromCSV.ps1"},"content":{"rendered":"\n<p>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<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">UPN<\/th><th class=\"has-text-align-left\" data-align=\"left\">Mailbox<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">user1@ldlnet.net<\/td><td class=\"has-text-align-left\" data-align=\"left\">mailbox1@ldlnet.net<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">user2@ldlnet.net<\/td><td class=\"has-text-align-left\" data-align=\"left\">mailbox1@ldlnet.net<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">user3@ldlnet.net<\/td><td class=\"has-text-align-left\" data-align=\"left\">mailbox1@ldlnet.net<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">user4@ldlnet.net<\/td><td class=\"has-text-align-left\" data-align=\"left\">mailbox2@ldlnet.net<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">user5@ldlnet.net<\/td><td class=\"has-text-align-left\" data-align=\"left\">mailbox2@ldlnet.net<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">user1@ldlnet.net<\/td><td class=\"has-text-align-left\" data-align=\"left\">mailbox3@ldlnet.net<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">user3@ldlnet.net<\/td><td class=\"has-text-align-left\" data-align=\"left\">mailbox3@ldlnet.net<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Example CSV file Input<\/figcaption><\/figure>\n\n\n\n<p>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.<\/p>\n\n\n<pre class=\"lang:PowerShell nums:True\" title=\"Add-FullAndSendToMailboxFromCSV.ps1\">\n\n<#\n\n.SYNOPSIS\n\nAdds 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\nwill 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.\nThe CSV must contain two headers UPN and Mailbox.\nOne 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.\n\nExample CSV\nUPN,Mailbox\nlance@me.com,FirstMailbox@me.com\nlance@me.com,SecondMailbox@me.com\nkulwinder@me.com,FirstMailbox@me.com\n\n***YOU MUST INPUT THE PATH TO THE CSV FILE IN THE CMDLET!***\n \n\n.NOTES\n\n    Name: Add-FullAndSendToMailboxFromCSV.ps1\n\n    Author: Lance Lingerfelt\n\n    Version: 1.0\n\n    Modify Date: 2024-07-15\n\n    Parameter Values:\n\n    $CSVPath is manditory and sets the path where your input file with your user and mailbox values CSV is located.\n\n    Log File Location:\n\n    Path = \"C:\\BaringsScripts\\Logs\\Add-FullAndSendToMailboxFromCSV\/<MM>\/<DD>\/\"\n    Name = \"<RunTimeDate_nnn>.log\"\n    \n\n.EXAMPLE\n\nRun the Script with the Retention Policy as Default MRM Policy\n\n    .\\Add-FullAndSendToMailboxFromCSV.ps1 -CSVPath 'C:\\Temp\\filename.csv'\n\n#>\n\n[CmdletBinding(SupportsShouldProcess = $true)]\n\nParam(\n\n   [Parameter(Mandatory = $true)]\n\n    [string] $CSVPath\n\n   )\n\n# ================================================\n#               DO NOT MODIFY BEGIN\n# ================================================\n\n$ErrorActionPreference = 'SilentlyContinue'\n\n$Date = Get-Date -Format \"MM\/dd\/yyyy\"\n\n# Set Logging Configuration\n$Log = [PSCustomObject]@{\n    Path = \"C:\\BaringsScripts\\Logs\\Add-FullAndSendToMailboxFromCSV\"\n    Name = \"$($Date).log\"\n}\n\n# ================================================\n#                DO NOT MODIFY END\n# ================================================\n\n# ================================================\n#                   SCRIPT BEGIN\n# ================================================\n\n# Create New Logger Instance if Enabled\nif ($PSCmdlet.ShouldProcess(\"Create New Logger Instance\", $Log.Path)) {\n    # Import Logger Module\n    try {\n        if ( -not (Get-Module -Name PoShLog -ListAvailable) ) {\n            Install-Module -Name PoShLog -Scope CurrentUser -Force\n        }\n        else {\n            Import-Module -Name PoShLog -Force\n        }\n    }\n    catch {\n        Write-Host -Object \"Unable to import logger module. Error: $($_.Exception.Message)\"\n        exit 1\n    }\n\n    # Create New Logger Instance. Verbose logging level. Log to file and console. Start Logger.\n    New-Logger | `\n        Set-MinimumLevel -Value Verbose | `\n        Add-SinkFile -Path \"$($Log.Path)\\$($Log.Name)\" -OutputTemplate `\n        '{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}' -RollingInterval Day | `\n        Add-SinkConsole | `\n        Start-Logger\n    \n    # Log Start of Script\n    Write-VerboseLog \"Start of Script.\" \n    Write-Host \"Start of Script.\" -ForegroundColor DarkGreen\n}\n\n\nif ($PSCmdlet.ShouldProcess(\"Create New Exchange Online Instance\", $Log.Path)) {\n    # Import ExchangeOnlineManagement Module\n    try {\n        if ( -not (Get-Module -Name ExchangeOnlineManagement -ListAvailable) ) {\n            Install-Module -Name ExchangeOnlineManagement -Scope CurrentUser -Force\n        }\n        else {\n            Import-Module -Name ExchangeOnlineManagement -Force\n        }\n    }\n    catch {\n        Write-Host -Object \"Unable to import ExchangeOnlineManagement module. Error: $($_.Exception.Message)\"\n        Write-VerboseLog \"Unable to import ExchangeOnlineManagement module. Error: $($_.Exception.Message)\"\n        exit 1\n    }\n}\n\n#Connect Exchange Online\nWrite-Host \"Connecting To Exchange Online\" -ForegroundColor Green\nWrite-VerboseLog \"Connecting To Exchange Online\"\nConnect-ExchangeOnline -ShowBanner:$False\n\n#Import the CSV file form the cmdlet input\nWrite-Host \"Importing CSV Values\" -ForegroundColor Green\nWrite-VerboseLog \"Importing CSV Values\"\n$MailboxIds = Import-CSV -Path $CSVPath\n\n#Add the Full Mailbox Access and Send-As Permissions based on the data in the CSV file.\nForeach ($MailboxId in $MailboxIds) {\n    \n    # Check if the user specified in Group exists\n    $userExists = @()\n    $userExists += Get-User -Identity $MailboxId.UPN -ErrorAction SilentlyContinue -Resultsize Unlimited\n    $userExists += Get-Contact -Identity $MailboxId.UPN -ErrorAction SilentlyContinue -ResultSize Unlimited\n\n    # Check if the distribution group specified in GroupName exists\n    $mailboxExists = Get-Mailbox -Identity $MailboxID.Mailbox -ErrorAction SilentlyContinue\n\n    if ($userExists -and $mailboxExists) {\n        \n        #Set the Warning variable\n        #$warnvar = \"This is the warning variable\"\n        \n        # Both user and group exist, so proceed with updating the permissions\n        try {\n            Write-Host \"Adding Full Mailbox Access Permission for User: [$($MailboxId.UPN)] to mailbox: [$($mailboxId.Mailbox)]\" -ForegroundColor Green\n            Write-VerboseLog \"Adding Full Mailbox Access Permission for User: [$($MailboxId.UPN)] to mailbox: [$($mailboxId.Mailbox)]\" \n            Add-MailboxPermission -Identity $MailboxId.Mailbox -User $MailboxId.UPN -AccessRights FullAccess -AutoMapping:$True -ErrorAction SilentlyContinue -WarningVariable warnvar\n            if ($warnvar) {\n                Write-VerboseLog \"You had a warning: $($warnvar) Recorded in the Log File in: $($Log.Path)\"\n            }\n            else { \n                Write-VerboseLog \"No Warnings Recorded\"\n            }\n           \n        }\n        catch {\n            Write-Host \"Failed to add full access permission for $($MailboxId.UPN) Error: $($_.Exception.Message)\" -ForegroundColor Red\n            Write-VerboseLog \"Failed to add full access permission for $($MailboxId.UPN) Error: $($_.Exception.Message)\"\n                        \n        }\n        try {\n            Write-Host \"Adding Send-As Permission for User: [$($MailboxId.UPN)] to mailbox: [$($MailboxId.Mailbox)]\" -ForegroundColor Cyan\n            Write-VerboseLog \"Adding Send-As Permission for User: [$($MailboxId.UPN)] to mailbox: [$($MailboxId.Mailbox)]\" \n            Add-RecipientPermission -Identity $MailboxId.Mailbox -AccessRights SendAs -Trustee $MailboxId.UPN -Confirm:$False -ErrorAction SilentlyContinue -WarningVariable warnvar | Out-Null\n            if ($warnvar) {\n                Write-VerboseLog \"You had a warning: $($warnvar) Recorded in the Log File in: $($Log.Path)\"\n            }\n            else { \n                Write-VerboseLog \"No Warnings Recorded\"\n            }\n        }\n        catch {\n            Write-Host \"Failed to add Send-As permission for [$($MailboxId.UPN)] Error: $($_.Exception.Message)\" -ForegroundColor Red\n            Write-VerboseLog \"Failed to add Send-As permission for [$($MailboxId.UPN)] Error: $($_.Exception.Message)\"\n                        \n        }\n    }\n    elseif (-not $mailboxExists) {\n        # Mailbox doesn't exist, display a message\n        Write-Host \"The mailbox [$($MailboxId.Mailbox)] specified in Mailbox column doesn't exist. Skipping.\" -ForegroundColor DarkRed\n        Write-VerboseLog \"The mailbox [$($MailboxId.Mailbox)] specified in Mailbox column doesn't exist. Skipping.\"\n    }\n    elseif (-not $userExists) {\n        # User doesn't exist, display a message\n        Write-Host \"User [$(MailboxID.UPN)] specified in User column doesn't exist. Skipping.\" -ForegroundColor DarkRed\n        Write-VerboseLog \"User [$(MailboxID.UPN)] specified in User column doesn't exist. Skipping.\"\n    }\n}\n    \n#Create an array of mailbox identity values to use for cmdlets below.\n$mbxlist = @()\n    foreach ($MailboxId in $MailboxIds){\n        $mbxlist += $mailboxId.Mailbox\n        }  \n\n#Get the final list of mailbox vaules that are unique\n$finalmbxlist =@()                        \n$finalmbxlist += $mbxlist | Get-Unique\n\n#Show the mailbox permissions of each mailbox upon completion of adding the users to each mailbox\nforeach ($finalmbx in $finalmbxlist) {\n    Write-Host \"Showing Final Mailbox Permissions for Mailbox: [$($finalmbx)]\" -ForegroundColor Green\n    Write-VerboseLog \"Showing Final Mailbox Permissions for Mailbox: [$($finalmbx)]\"\n    Get-MailboxPermission -Identity $finalmbx | Format-Table -AutoSize -Wrap\n\n#Show the Send-As permissions for each mailbox upon completion of adding the users to each mailbox\n    Write-Host \"Showing Final Send-As Permissions for Mailbox: [$($finalmbx)]\" -ForegroundColor Cyan\n    Write-VerboseLog \"Showing Final Send-As Permissions for Mailbox: [$($finalmbx)]\"\n    Get-RecipientPermission -Identity $finalmbx | Format-Table -AutoSize -Wrap\n}\n\n# Disconnect from Microsoft 365 PowerShell sessions\nWrite-VerboseLog \"Disconnecting Exchange Online module\"\nWrite-Host \"Disconnecting Exchange Online module\" -ForegroundColor Red\nDisconnect-ExchangeOnline -Confirm:$False\n\nWrite-VerboseLog \"End of Script\"\nWrite-Host \"End of Script\" -ForegroundColor DarkRed\n# ================================================\n#                   SCRIPT END\n# ================================================\n<\/pre>\n\n\n\n<p><em>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.<\/em><\/p>\n\n\n\n<p>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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">About Lance Lingerfelt<\/h2>\n\n\n\n<div class=\"wp-block-media-text is-stacked-on-mobile\" style=\"grid-template-columns:22% auto\"><figure class=\"wp-block-media-text__media\"><img loading=\"lazy\" decoding=\"async\" width=\"468\" height=\"412\" src=\"https:\/\/itblog.ldlnet.net\/wp-content\/uploads\/2024\/03\/ProfLDL1.jpg\" alt=\"Lance Lingerfelt Profile Photo\" class=\"wp-image-196223 size-full\"\/><\/figure><div class=\"wp-block-media-text__content\">\n<p class=\"has-small-font-size\">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.<\/p>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>During a migration you might need to add a bunch of new users to a bunch of shared mailboxes. Now you could<\/p>\n<p class=\"link-more\"><a class=\"myButt \" href=\"https:\/\/itblog.ldlnet.net\/index.php\/2024\/07\/19\/add-fullandsendtomailboxfromcsv-ps1\/\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":196400,"comment_status":"closed","ping_status":"closed","sticky":true,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,2,265,194,3],"tags":[151,303,8,315,13],"class_list":["post-196444","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-exchange","category-general","category-microsoft365","category-office365","category-powershell","tag-exchange-2019","tag-exchange-online","tag-powershell","tag-powershell-script","tag-script","odd"],"_links":{"self":[{"href":"https:\/\/itblog.ldlnet.net\/index.php\/wp-json\/wp\/v2\/posts\/196444","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itblog.ldlnet.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itblog.ldlnet.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itblog.ldlnet.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/itblog.ldlnet.net\/index.php\/wp-json\/wp\/v2\/comments?post=196444"}],"version-history":[{"count":7,"href":"https:\/\/itblog.ldlnet.net\/index.php\/wp-json\/wp\/v2\/posts\/196444\/revisions"}],"predecessor-version":[{"id":196453,"href":"https:\/\/itblog.ldlnet.net\/index.php\/wp-json\/wp\/v2\/posts\/196444\/revisions\/196453"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/itblog.ldlnet.net\/index.php\/wp-json\/wp\/v2\/media\/196400"}],"wp:attachment":[{"href":"https:\/\/itblog.ldlnet.net\/index.php\/wp-json\/wp\/v2\/media?parent=196444"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itblog.ldlnet.net\/index.php\/wp-json\/wp\/v2\/categories?post=196444"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itblog.ldlnet.net\/index.php\/wp-json\/wp\/v2\/tags?post=196444"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}