I recently used Microsoft’s new G-Suite to Office 365 Migration method to migrate a company from G-Suite to Office 365. Microsoft’s new method has a few benefits. Along with emails it also migrates user calendars and contacts to Exchange Online. This is great and and solves the need of paying a third party exorbitant amounts of money to handle a migration. I ran a test migration on a few accounts and it seemed to work well other than one small snag. In the Outlook desktop apps (both 2016 and 2019) users had no permissions for their primary Contacts folder. The contacts had migrated from Google but had no ability to edit them or create new ones. The Outlook Web App functioned correctly.
I tried resetting permissions with PowerShell but ended up with no success. I then opened a ticket with Microsoft and after some basic troubleshooting I was escalated. The next representative I spoke with had me do the same troubleshooting I had done prior to opening the ticket with Powershell. After a while on the phone I was finally escalated again. It took a few days before my ticket was picked back up however when I did I finally got a real resolution.
This resolution requires the EWS API to be installed, a PowerShell Script in an accessible folder, and the Application Impersonation Role. This role can take an hour to propagate however it is usually much faster.
EWS API: https://www.microsoft.com/en-us/download/details.aspx?id=42951
Update-Folders.ps1: https://gallery.technet.microsoft.com/exchange/PowerShell-Update-mailbox-79fd411a
Make sure to change the YourAdminUsername to the account you wish to use for the folder fix script!
Assign the impersonation role with a Global Admin account.:
Set-ExecutionPolicy RemoteSigned
$Cred = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Cred -Authentication Basic -AllowRedirection
Import-PSSession $Session
New-ManagementRoleAssignment -name:impersonationAssignmentName -Role:ApplicationImpersonation -User:YourAdminUsername
Get-PSSession | Remove-PSSession
Wait for your permissions to be propagated. We removed the session previously because that session wouldn’t have the commands needed to impersonate the users and change the flag needed on their Contacts folder. In the meantime be sure to install the EWS API and download / move to a folder your Powershell Script linked above. Once ready we can then change the PowerShell prompt to the directory containing the Update-Folders.ps1 script we downloaded earlier.
$cred = Get-Credential
$b = [byte[]]@(01, 04, 00, 00, 16, 00)
Get-Mailbox -ResultSize Unlimited | forEach {.\Update-Folders.ps1 -mailbox $_.PrimarySMTPAddress -FolderPaths "WellKnownFolderName.Contacts" -AddFolderProperties @{"0x36DA0102" = $b} -credentials $Cred -EwsURL "https://outlook.office365.com/EWS/Exchange.asmx" -Impersonate}
This script will go through and change a flag on all mailbox Contact folders to allow the correct permissions. This can take a while to propagate but should work for everyone. The alternative method is to do it for each device’s Outlook profile and affected Mailbox.
Download the MFCMAPI version x86 or 64-bit corresponding with the installed version of Outlook. I am not 100% sure that they need to match up but this is how it was instructed to me. MFCMAPI: https://github.com/stephenegriffin/mfcmapi/releases/tag/19.0.19115.01
In MFCMAPI follow these instructions:
Make sure Outlook is completely closed and open MFCMAPI.
Select Session > Logon
Select the affected Outlook Profile and press OK.
Double click the affected mailbox.
If the selected mailbox is the Root Mailbox expand “IPM_SUBTREE” and select “Contacts“.
If it is not the root mailbox you will expand “Top of Information Store” and select “Contacts“.
In right pane find and double click: PR_EXTENDED_FOLDER_FLAGS
Store current value in a secure location for backup and replace the value with:
010400801200070401000000
Open Outlook
Good luck and if you need any help or find errors in this please leave a comment below!
1 Comment
Looping over the mailboxes with Get-Mailbox and forEach, is REALLY slow.
Generating a CSV of mailboxes and supplying the file path to the script seems to be much quicker (2-3 secs per mailbox as opposed to 15-20 secs)
Get-Mailbox -ResultSize unlimited | select primarysmtpaddress | Export-Csv -Path mailboxes.csv -NoTypeInformation
.\Update-Folders.ps1 -Mailbox .\mailboxes.csv -FolderPaths “WellKnownFolderName.Contacts” -AddFolderProperties @{“0x36DA0102” = $b} -credentials $Cred -EwsURL “https://outlook.office365.com/EWS/Exchange.asmx” -Impersonate