Monday, March 27, 2017

Configure Legacy (on-premise) Public Folder Access for a Cloud Mailbox in Hybrid Deployment


While working on a project for on-premise Exchange 2010 SP3 to Exchange Online migration, I came to scenario where users whose mailboxes are migrated to Exchange online required access to Public folder which are homed on on-premise Exchange 2010 Server. An Office 365 user who is not represented by a Mail-user object on-premise AD, won't be able to access legacy on-premise public folder.

I referred to Microsoft TechNet article "Configure legacy on-premises public folders for a hybrid deployment" Article URL which cover all the prerequisites and task which need to be performed however my this blogs contain the step by step guide with detailed snapshots.

My environment-
  • Exchange Server 2010 Service Pack 3 RU 15.
  •  Hybrid with Office 365.
General Prerequisites for Public Folder migration-
  1. Outlook Anywhere should be enabled and functional on the on-premise Exchange 2010 Server.
  2. Exchange online organization is upgraded to latest version which is supported for Public Folder.
  3. Outlook Clients are upgraded to the latest update.
Step 1- Install CAS Server Role on Mailbox Server-
If public folders are on Exchange 2010 or later servers, then we need to install the Client Access Server role on all mailbox servers that have a public folder database. This allows the Microsoft Exchange RpcClientAccess service to be running, which allows for all clients to access public folders.

Step 2- Create empty mailbox database on each public folder server-
New-MailboxDatabase -Server PFServerwithCAS -Name PFMBDB -IsExcludedFromProvisioning $True




Confirm DB-








Step 3- Create Mailbox for Proxy-
Create a proxy mailbox within the new mailbox database and hide the mailbox from the address book. The SMTP of this mailbox will be returned by AutoDiscover as the DefaultPublicFolderMailbox SMTP, so that by resolving this SMTP the client can reach the legacy exchange server for public folder access.

New-Mailbox -Name PFMailbox1 -Database PFMBDB

Provide Password for this mailbox “P@ssw0rd”

UserPrincipleName pfmailbox1@domain.com








Step 4- Hide the mailbox from Address List-

Set-Mailbox -Identity PFMailbox1 -HiddenFromAddressListsEnabled $true

Step 5- Enable Autodiscover to return the proxy public folder mailboxes

Set-MailboxDatabase PFMBDB -RpcClientAccessServer MaiboxServerName

Note- Repeat the preceding steps for every public folder server in your organization.

Step 6- Download Scripts
  • Sync-MailPublicFolders.ps1
  • SyncMailPublicFolders.strings.psd1
Save the files to the local computer on which you’ll be running PowerShell. For example, C:\PFScripts.

Step 7- Configure Directory synchronization-
The Directory Synchronization service doesn’t synchronize mail-enabled public folders. Running the following script will synchronize the mail-enabled public folders across premises. Special permissions assigned to mail-enabled public folders will need to be recreated in the cloud since cross-premise permission are not supported in Hybrid Deployment scenarios.
  • On the legacy Exchange server, run the following command to synchronize mail-enabled public folders from your local on-premises Active Directory to O365.
         Sync-MailPublicFolders.ps1 -Credential (Get-Credential) -CsvSummaryFile:sync_summary.csv

NOTE- Credential is your Office 365 user name and password, and CsvSummaryFile is the path to where you would like to log synchronization operations and errors, in .csv format.






















Review the error on the log file to resolve the issue. For me the error was “Proxy addresses is already being used, please choose another proxy address.” I fixed this and everything went well.

Step 8- Configure Exchange Online users to access on-premises public folders
The final step in this procedure is to configure the Exchange Online organization and to allow access to the legacy on-premises public folders. Enable the exchange online organization to access the on-premises public folders. You will point to all the proxy public folder mailboxes that you created.

Connect to Exchange Online and Run below Command-

Set-OrganizationConfig -PublicFoldersEnabled Remote -RemotePublicFolderMailboxes PFMailbox1







We must wait until Active Directory synchronization has completed to see the changes. This process can take up to 3 hours to complete. However, we can always force directory synchronization at any time. 

Step 8- How do I know this worked?
Log on to Outlook for a user who is in Exchange Online and perform the following public folder tests:
  • View the hierarchy.
  • Check permissions
  • Create and delete public folders.
  • Post content to and delete content from a public folder.


Wednesday, May 11, 2016

Field Experience: Public Folder Migration from Exchange 2010 to Office 365

While working on a project for Office 365 migration, Public folder migration is a very critical task which needs to be done. I was referring to Microsoft TechNet article “Use batch migration to migrate legacy public folders to Office 365 and Exchange Online” https://technet.microsoft.com/en-us/library/dn874017(v=exchg.150).aspx which cover all the prerequisites and task which need to be performed however my this blogs contain the step by step guide and details of issues which I faced while performing the migration task and how I resolved.

My environment-
-         Exchange Server 2010 SP3 RU12 Single Server.
-         Hybrid with Office365.

General Prerequisites for Public Folder migration-
-         Backup of Public Folder databases.
-         Backup of Active Directory incase if you need to perform changes in AD.
-         The Exchange 2010 server needs to be running Exchange 2010 SP3 RU8 or later.
-    In Office 365 and Exchange Online, you need to be a member of the Organization Management role group.
-     In Exchange 2010, you need to be a member of the Organization Management or Server Management RBAC role groups.
-     If any public folder in your organization is greater than 2 GB, we recommend either deleting content from that folder or splitting it up into multiple public folders.
-         First move all user mailboxes to Office 365 and Exchange Online.
-         Outlook Anywhere needs to be enabled on the legacy Exchange server.
-         Downtime will be required for some steps.
-       No orphaned public folder mail objects in Active Directory, meaning objects in Active Directory without a corresponding Exchange object, if any please remove them.
-       SMTP email address configured for public folders in Active Directory match the SMTP email addresses on the Exchange objects and should be trusted domain for O365.
-       No duplicate public folder objects in Active Directory, to avoid a situation where two or more Active Directory objects are pointing to the same mail-enabled public folder.

Public Folder Prerequisites-
-         If any public folder contain space or any special character in between, we need to remove prior to performing the migration.
o   Open Public Folder management console.
o   Go to Public Folder Properties check the name.

-         Mail enabled public folder should have valid email address.
o   Open Public Folder management console.
o   Go to Public Folder Properties.
o   Go to Email address and verify.

-         Mail enabled public folder should have valid Proxy Address
o   Go to Adsiedit.msc
o   Connect to Domain naming Context.
o   Expand DC=ABC,DC=COM
o   Expand CN=Microsoft Exchange System Objects.
o   Go to the properties of Public Folder.
o   Verify Proxy Address.

Note: Each mail enabled public folder should have primary SMTP address which will be in form for SMTP:emailadress@abc.com

-         Public Folder MailNickName should not contain space
o   Go to Adsiedit.msc
o   Connect to Domain naming Context.
o   Expand DC=ABC,DC=COM
o   Expand CN=Microsoft Exchange System Objects.
o   Go to the properties of Public Folder.
o   Verify MailNickName

Initiate migration activities-



Create folder on the C drive of Exchange Server as C:\PFScripts & copy all the scripts there-










Step 2: Download the following files from Mail-enabled Public Folders - directory sync script:


Save all the Scripts to the same location.

Scripts details-
  • Export-PublicFolderStatistics.ps1-This script creates the folder name-to-folder size mapping file. You’ll run this script on the legacy Exchange server.
  • Export-PublicFolderStatistics.psd1-This support file is used by the Export-PublicFolderStatistics.ps1 script and should be downloaded to the same location.
  • PublicFolderToMailboxMapGenerator.ps1-This script creates the public folder-to-mailbox mapping file by using the output from the Export-PublicFolderStatistics.ps1 script. You’ll run this script on the legacy Exchange server.
  • PublicFolderToMailboxMapGenerator.strings.psd1-This support file is used by the PublicFolderToMailboxMapGenerator.ps1 script and should be downloaded to the same location.
  • Create-PublicFolderMailboxesForMigration.ps1-This script creates the target public folder mailboxes for the migration. In addition, this script calculates the number of mailboxes necessary to handle the estimated user load, based on the guidelines for the number of user logons per public folder mailbox recommended in Limits for public folders.
  • Create-PublicFolderMailboxesForMigration.strings.psd1-This support file is used by the Create-PublicFolderMailboxesForMigration.ps1 script and should be downloaded to the same location.
  • Sync-MailPublicFolders.ps1-This script synchronizes mail-enabled public folder objects between your local Exchange deployment and Office 365. You'll run this script on the legacy Exchange server.
  • SyncMailPublicFolders.strings.psd1-This is a support file used by the Sync-MailPublicFolders.ps1 script and should be copied to the same location as the preceding scripts.

Step 3: Created Accepted Domain for Public folder-

New-AcceptedDomain -Name "PublicFolderDestination_78c0b207_5ad2_4fee_8cb9_f373175b3f99" -DomainName o365domain.onmicrosoft.com -DomainType InternalRelay






Step 4: Get public folder statistics-

Get-PublicFolderStatistics -ResultSize Unlimited | Where {$_.Name -like "*\*"} | Format-List Name, Identity






Step 5: Checks the public folder migration status, if any previous record of a successful migration. If there is, you’ll need to set that value to $false. If the value is set to $true, the migration request will fail.

Get-OrganizationConfig | Format-List PublicFoldersLockedforMigration, PublicFolderMigrationComplete


Step 6: Run the following command to take a snapshot of the original source folder structure.

Get-PublicFolder -Recurse | Export-CliXML C:\PFMigration\Legacy_PFStructure.xml


Step 7: Run the following command to take a snapshot of public folder statistics such as item count, size, and owner. 

Get-PublicFolderStatistics -ResultSize Unlimited | Export-CliXML C:\PFMigration\Legacy_PFStatistics.xml


Step 8: Run the following command to take a snapshot of the permissions.

Get-PublicFolder -Recurse | Get-PublicFolderClientPermission | Select-Object Identity,User -ExpandPropertyAccessRights | Export-CliXML C:\PFMigration\Legacy_PFPerms.xml


Step 9: Output will be listed in the folder C:\PFMigration-


Step 10: Connect to Exchange online-

$UserCredential = Get-Credential


$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection


Import-PSSession $Session



















Step 11: The following example will discover any existing serial migration requests.

Get-PublicFolderMigrationRequest | Get-PublicFolderMigrationRequestStatistics -IncludeReport | Format-List





Step 12: The following example removes any existing public folder serial migration requests.

Get-PublicFolderMigrationRequest | Remove-PublicFolderMigrationRequest

Step 13: The following example will discover any existing batch migration requests.

$batch = Get-MigrationBatch | ?{$_.MigrationType.ToString() -eq "PublicFolder"}

Step 14: The following example removes any existing public folder batch migration requests.

$batch | Remove-MigrationBatch -Confirm:$false






Step 15: In Office 365 or Exchange Online PowerShell, run the following command to see if any public folders mailboxes exist.

Get-Mailbox -PublicFolder


.\Export-PublicFolderStatistics.ps1 C:\PFMigration\PFmapNameToSize.csv exchange.abc.com

.\PublicFolderToMailboxMapGenerator.ps1 100MB C:\PFMigration\PFmapNameToSize.csv C:\PFMigration\PFmapFolderToMailbox.csv

Step 17: Create new mailbox for public folder-

New-Mailbox -PublicFolder Mailbox1 -HoldForMigration:$true







Mailbox name should be same as generated by PublicFolderToMailboxMapGenerator.ps1

Step 18: On the legacy Exchange server, run the following command to synchronize mail-enabled public folders from your local Active Directory to Exchange Online

Sync-MailPublicFolders.ps1 -Credential (Get-Credential) -CsvSummaryFile:c:\PFMigrations\sync_summary.csv














Step 19: Provide O365 Admin Credentials-




























Note:  All the warning were related to special character / SMTP address / MailNickName which fixed from ADSI Edit or Public folder properties.

Step 20: On the legacy Exchange server, get the following information that’s needed to run the migration request:

Get-Mailbox adsync | Select-Object LegacyExchangeDN









Step 21: Find the LegacyExchangeDN of any Mailbox server that has a public folder database.

Get-ExchangeServer exchangeserver | Select-Object -Expand ExchangeLegacyDN


Step 22: Find the FQDN of the Outlook Anywhere host name

Get-OutlookAnywhere | Format-Table Identity,ExternalHostName









Step 23: In Office 365 PowerShell, run the following commands to pass the information that was returned in the previous step to variables that will then be used in the migration request.

$Source_Credential = Get-Credential



$Source_RemoteMailboxLegacyDN = "<paste the value here>"

$Source_RemotePublicFolderServerLegacyDN = "<paste the value here>"

$Source_OutlookAnywhereExternalHostName = "<paste the value here>"

Step 24: In Exchange Online PowerShell, run the following commands to create the migration request.

$PfEndpoint = New-MigrationEndpoint -PublicFolder -Name PublicFolderEndpoint -RPCProxyServer $Source_OutlookAnywhereExternalHostName -Credentials $Source_Credential -SourceMailboxLegacyDN $Source_RemoteMailboxLegacyDN -PublicFolderDatabaseServerLegacyDN $Source_RemotePublicFolderServerLegacyDN -Authentication Basic

New-MigrationBatch -Name PublicFolderMigration -CSVData (Get-Content C:\PFMigration\PFmapFolderToMailbox.csv -Encoding Byte) -SourceEndpoint $PfEndpoint.Identity -NotificationEmails emailaddress@abc.com












Step 25: Start the migration using the following command:

Start-MigrationBatch PublicFolderMigration







Step 26: View Details-







Set-OrganizationConfig -PublicFoldersLockedForMigration:$true







Step 28: To complete the public folder migration, run the following command:

Complete-MigrationBatch PublicFolderMigration
















Step 29: Run the following command in Exchange Online PowerShell after migration is complete:

Set-OrganizationConfig -RemotePublicFolderMailboxes $Null -PublicFoldersEnabled Local



In Office 365 or Exchange Online PowerShell, assign some test mailboxes to use any newly migrated public folder mailbox as the default public folder mailbox-

Set-Mailbox -Identity <Test User> -DefaultPublicFolderMailbox <Public Folder Mailbox Identity>





Step 31: If the public folder content and hierarchy is acceptable and functions as expected, run the following Exchange Online PowerShell command to unlock the public folders for all other users.

Get-Mailbox -PublicFolder | Set-Mailbox -PublicFolder -IsExcludedFromServingHierarchy $false






Step 32: On the legacy Exchange server, run the following command to indicate that the public folder migration is complete:

Set-OrganizationConfig -PublicFolderMigrationComplete:$true