Scripts and Background
One of the issues with this type of migration is Free Busy sharing between Office 365 and Lotus Notes users. This requires a bit of a special setup as well as a third-party tool to handle the query traffic between users of both email systems. In this scenario we used the Quest Coexistence product to provide this. This entails a multi-tiered approach to mailboxes and mail objects in Office 365. The underlying function of free busy has a dependency on the SMTP domain of the user to query. So we have this in Office 365:
Office 365 Users – User have a domain of @cloud.domain.com
Lotus Notes Users – A contact with @lotus.domain.com is used to direct email to Lotus Notes
How does this play into Free Busy?
Well, a user in Office 365, when trying to lookup Free Busy information on a user looks up the user in the Global Address List (GAL). If the user has a mailbox then that object is queried for free busy information. If the user is a contact, then Outlook / Exchange Online tries to look up information using something called ‘Availability Address Space’. This value can be set per domain and it tells Exchange where to direct Free Busy queries. If this has been configured, then Outlook will receive results from this remote server. The remote server could be an Exchange server or in my scenario, a Quest server, which responds back with a users information.
Forwarders
During the mailbox migration process where Quest is copying emails to Office 365 mailboxes, a forwarder needs to be present on that mailbox. This is because the end-user still is using their Lotus Notes mailbox and needs to have all of their emails routed to that mailbox. This makes the forwarder an important detail in the migration. Once a mailbox migration is complete, is it also import to make sure no forwarder is present. That way emails will not be delivered to Lotus Notes, which will either create a loop, or leave emails in Lotus Notes that the user will not have access to.
PowerShell Script for Forwarders
Here is a sample script I used to check these and even have cmdlets to remove forwarders as needed:
# Mailboxes for forwarder check $CSV = import-csv 'c:\migration\currentusers.csv' ForEach ($Line in $CSV) { $Mailbox = $Line.UPN $Forward = (Get-Mailbox $Mailbox).ForwardingAddress If ($Forward -eq $null) { Write-Host "The mailbox for $Mailbox " -ForegroundColor White -NoNewLine Write-Host "has no forwarder." -ForegroundColor Green } Else { Write-Host "The mailbox for $Mailbox " -ForegroundColor White -NoNewLine Write-Host "has a forwarder!" -ForegroundColor Red # Set-Mailbox $Mailbox -ForwardingAddress $Null } }
If forwarders are found, then RED warning text will be displayed.
If forwarders are found, then green text will be displayed.
There is one line at the end that is commented out. This line is commented out to prevent forwarders from being removed. If a forwarder needs to be removed, then simply remove the ‘#’ in the front of the line like so:
Set-Mailbox $Mailbox -ForwardingAddress $Null
Retention Polices
Another important step is to adjust the Retention Policies for a mailbox after it has been moved to Office 365. The reason this should be done is that even if you are not using Retention Policies on-premises or in Office 365, a policy will be applied by default to your mailbox:
In most cases this needs to be removed or replaced with a current policy. There is no automatic way to do so and a PowerShell script is the easiest way to check and/or apply a new policy to a group of mailboxes in Office 365.
$Mailbox = Get-Mailbox $Policy = '18 Month Email Delete and Purge' ForEach ($Line in $Mailbox) { $Name = $Line.DisplayName $Retention = $Line.RetentionPolicy If ($Retention -eq $Policy) { Write-Host "The mailbox for $Name " -ForegroundColor White -NoNewLine Write-Host "has the right Retention Policy." -ForegroundColor Green } Else { Write-Host "The mailbox for $Name " -ForegroundColor White -NoNewLine Write-Host "has the wrong retention policy!" -ForegroundColor Red # Set-Mailbox $Mailbox -RetentionPolicy $Policy } }
This policy checks each mailbox to see if it has the correct Retention Policy. If the policies are wrong, we get lots of red:
To fix these, we simply remove the comment from the ‘Set-Mailbox’ line.
Room Calendar Changes
When creating rooms, we noticed that permissions applied for the calendar portion of a room mailbox sometimes had a restricted view for the ‘Default’ user, which is everyone trying to view the calendar. The script below simply reports what is set, sets the correct permission for the default account to limited details and then reports the end status help provide proof of the change.
$Rooms = Get-Mailbox "Room*" Foreach ($Line in $Rooms) { $Room = $Line.Alias $Calendar = $Room+":\Calendar" # Write mailbox name and dividing line for reporting and visual aide Write-host "Room $Room" -Foregroundcolor Green Write-host "---------------------------------------------" -Foregroundcolor Green # Check before change write-host "Before" -ForegroundColor Yellow Get-MailboxFolderPermission $Calendar #Change permissions Set-MailboxFolderPermission -Identity $Calendar -User Default -AccessRights LimitedDetails #After Check write-host "After" -ForegroundColor yellow Get-MailboxFolderPermission $Calendar }
Granting Full Permission
The Quest utility uses many accounts with special access to mailboxes in Office 365. One of the needed rights is full access to a mailbox. this can be done with a configuration change in Quest, or with PowerShell in Exchange Online.
# All mailboxes $CSV = import-csv 'C:\migration\EmailAddresses.csv' # All migwiz accounts $csv2 = import-csv 'C:\migration\migwizaccounts.csv' Foreach ($line in $CSV) { # Store current mailbox to be referenced in a variable $Mailbox = $Line.UPN # Add each migration account to each mailbox with Full Permission foreach ($line2 in $CSV2) { $Name = $Line2.Name Add-MailboxPermission -Identity $Mailbox -User $Name -AccessRights FullAccess -InheritanceType All } }
Final Words
While these scripts are not a comprehensive list of what can be done for migrations with PowerShell. They are simply a sample of some tasks that can be automated with PowerShell. There are plenty of other tasks that could be automated or even turned into one large menu driven script to handle a migration if there was a desire to do so. Simply use this blog article as a helpful pointer as to what could be done.