This script gathers all public folders created during the last X days and exports the gathered data to a CSV file.
The script is not limited to legacy or modern public folders. It can be used with Exchange Server 2007/2010 and Exchange Server 2013/2016.
Use this script to identify users or departments creating to many folders in the public folder hierarchy. The CSV can be used to provide better guidance on public folder usage or can be used for planning public folder content migrations to other team based solutions (aka Shared Mailboxes, etc.)
# EXAMPLE # Query legacy public folder server MYPFSERVER01 for all public folders created during the last 31 days .\Get-NewPublicFolders.ps1 -Days 31 -ServerName MYPFSERVER01 -Legacy # EXAMPLE # Query modern public folders for all public folders created during the last 31 days .\Get-NewPublicFolders.ps1 -Days 31
Public folders are one solution to provide a team collaboration tool for companies. Legacy public folders utilized a proprietary multi-master replication mechanism which was not planned to handle today's data volumes. Therefore, Exchange 2013 introduced modern public folders which utilize the robust DAG replication functionality. Due to the technology change between legacy public folders and modern public folders a migration is required.
You can migrate legacy public folders hosted on Exchange 2007 or Exchange 2010 to modern public folders hosted on Exchange 2013. Or you can migrate legacy public folders hosted on Exchange 2010 to modern public folders hosted on Exchange 2016. If a cloud migration is a viable option for your company, you are able to migrate legacy public folders hosted on Exchange 2007 or Exchange 2010 to modern public folders hosted in Exchange Online.
The requirements for legacy Exchange Servers are:
Since Exchange Server 2013 RTM the public folder migration scripts and the migration guidance have quite often been updated. The information provided at TechNet is very detailed for each migration option and there is no need to repeat each step in this blog post. Please see the link section for all hyperlinks.
Preparing a legacy public folder migration is pretty straight forward. The main issue companies are facing is the required downtime for finalizing the public folder migration batch. The required downtime cannot be determined exactly (not as exactly as requested by upper management). This means that you have to plan for scheduled maintenance during off-hours. In the past, a single migration request has been used to migrate legacy public folders. The new batch approach migrates public folder content using multiple requests within a single batch.
The Create-PublicFolderMailboxesForMigration.ps1 script uses the parameter EstimatedNumberOfConcurrentUsers to determine the overall number of public folder mailboxes serving the hierarchy. The TechNet articles explain this parameter as follows:
The estimated number of simultaneous user connections browsing a public folder hierarchy is usually less than the total number of users in an organization.
Exchange Server 2013 and Exchange Server 2016 currently support 2.000 concurrent connections to a single mailbox. This limit (2.000) is used by the Create-PublicFolderMailboxesForMigration.ps1 in conjunction with EstimatedNumberOfConcurrentUsers to determine the number of public folder mailboxes required to serve the public folder hierarchy. The current version of the script uses a coded limit of max 100 public folder mailboxes. This means that you can only serve 100 x 2.000 = 200.000 concurrent users accessing the public folder hierarchy.
Finalizing the migration request and setting the PublicFolderMigrationComplete attribute requires the legacy public folder information store to be restarted. Otherwise, the configuration change will not be picked up in the information store in a timely fashion. Remember to restart the information store service on all legacy public folder servers.
If your current public folder infrastructure is based on Exchange 2007 and you want to get rid of that Exchange version, you might think of replicating all content to Exchange 2010. This is not the best approach. Due to known content conversion issues, you might encounter data loss when replicating public folder content between Exchange 2007 and Exchange 2010.
The recommended approach is to migrate Exchange 2007 legacy public folders to Exchange 2013 modern public folders directly.
A recommended reading on legacy public folder migration from Exchange 2010 to Exchange 2016 is Butch Waller’s blog post “Migration to Modern Public Folders – Notes from the Field”
The PowerShell script referenced in that blog post does not work with Exchange 2007. You can use my PowerShell script which utilizes UTF8 encoding and runs with Exchange 2007 and Exchange 2010: https://gallery.technet.microsoft.com/Exchange-2010-Public-315ea9aa
Remark All limits mentioned in this post reflect the information available at the time of writing.
Do you need assistance with your Exchange Server setup? You have questions about your Exchange Server infrastructure and going hybrid with Office 365? Contact us at office365@granikos.eu or visit our website https://www.granikos.eu.
When you run your Exchange Organization in hybrid mode with Office 365 and you migrate your on-premise Public Folders to Office 365, you are required to configure a remote Public Folder Mailbox in the Exchange Organization settings.
With Public Folders on-premise your Exchange Online Org looks like this:
Get-OrganizationConfig | fl *public* DefaultPublicFolderAgeLimit : DefaultPublicFolderIssueWarningQuota : 1.7 GB (1,825,361,920 bytes) DefaultPublicFolderProhibitPostQuota : 2 GB (2,147,483,648 bytes) DefaultPublicFolderMaxItemSize : Unlimited DefaultPublicFolderDeletedItemRetention : 30.00:00:00 DefaultPublicFolderMovedItemRetention : 7.00:00:00 PublicFoldersLockedForMigration : False PublicFolderMigrationComplete : False PublicFoldersEnabled : Remote PublicComputersDetectionEnabled : False RootPublicFolderMailbox : 00000000-0000-0000-0000-000000000000 RemotePublicFolderMailboxes : {PublicFolder-Mailbox001}
With Public Folders on-premise your On-Premise Exchange Org looks like this:
Get-OrganizationConfig | fl *public* DefaultPublicFolderAgeLimit : DefaultPublicFolderIssueWarningQuota : Unlimited DefaultPublicFolderProhibitPostQuota : Unlimited DefaultPublicFolderMaxItemSize : Unlimited DefaultPublicFolderDeletedItemRetention : 30.00:00:00 DefaultPublicFolderMovedItemRetention : 7.00:00:00 PublicFoldersLockedForMigration : True PublicFolderMigrationComplete : True PublicFoldersEnabled : Local PublicComputersDetectionEnabled : False RootPublicFolderMailbox : ae0ef819-90d2-45d0-92b6-8b2062cf71a3 RemotePublicFolderMailboxes : {}
With Public Folders in Exchange Online your Exchange Online Org looks like this:
Get-OrganizationConfig | fl *public* DefaultPublicFolderAgeLimit : DefaultPublicFolderIssueWarningQuota : 1.7 GB (1,825,361,920 bytes) DefaultPublicFolderProhibitPostQuota : 2 GB (2,147,483,648 bytes) DefaultPublicFolderMaxItemSize : Unlimited DefaultPublicFolderDeletedItemRetention : 30.00:00:00 DefaultPublicFolderMovedItemRetention : 7.00:00:00 PublicFoldersLockedForMigration : False PublicFolderMigrationComplete : False PublicFoldersEnabled : Local PublicComputersDetectionEnabled : False RootPublicFolderMailbox : 5810bb30-cdda-4287-85a4-8a2547bb9b01 RemotePublicFolderMailboxes : {}
With Public Folders in Exchange Online your Exchange On-Premise Org looks like this:
Get-OrganizationConfig | fl *public* DefaultPublicFolderAgeLimit : DefaultPublicFolderIssueWarningQuota : Unlimited DefaultPublicFolderProhibitPostQuota : Unlimited DefaultPublicFolderMaxItemSize : Unlimited DefaultPublicFolderDeletedItemRetention : 30.00:00:00 DefaultPublicFolderMovedItemRetention : 7.00:00:00 PublicFoldersLockedForMigration : True PublicFolderMigrationComplete : True PublicFoldersEnabled : Remote PublicComputersDetectionEnabled : False RootPublicFolderMailbox : 00000000-0000-0000-0000-000000000000 RemotePublicFolderMailboxes : {mcsmemail.de/Users/PF365-Mailbox-01-55e3d544-ed5a-4557-9008-d8c1b6f06d86}
The remote public folder mailbox has been added to the on-premise Exchange confguration by using:
Set-OrganizationConfig -RemotePublicFolderMailboxes PF365-Mailbox-001 -PublicFoldersEnabled Remote
To be able to add the remote public folder mailbox in a hybrid configuration you are required to add the public folder mailbox (or mailboxes, if you have more than one serving the hierarchy) as a mail user.
Microsoft provides a PowerShell script as part of a script collection here.
When you run the Import-PublicFolderMailboxes.ps1 script you might run into the following error:
Cannot bind parameter 'Name' to the target. Exception setting "Name": "The length of the property is too long. The maximum length is 64 and the length of the value provided is 65." + CategoryInfo : WriteError: (:) [New-MailUser], ParameterBindingException + FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.Exchange.Management.RecipientTasks.NewMailUser + PSComputerName : ex2013.mcsmemail.de
The name attribute for a mail user is limited to 64 characters. But why are you exceeding the length when the mailbox name is only 17 characters long?
It turns out that the PowerSheel script adds a prefix name "" and ther mailbox GUID as a suffix. And voilá, the name exceeds the allowed length for the mail user name attribute.
Don't use more than 16 characters when naming the Public Folder mailboxes in Office 365.
Or modify the Import-PublicFolderMailboxes.ps1 script to fit your needs.
$hasPublicFolderServingHierarchy = $true; $displayName = $publicFolderMailbox.Name.ToString().Trim(); # ORIG: $name = "RemotePfMbx-" + $displayName + "-" + [guid]::NewGuid(); $name = $displayName + "-" + [guid]::NewGuid(); $externalEmailAddress = $publicFolderMailbox.PrimarySmtpAddress.ToString();
You need assistance with your Exchange Server setup? You have questions about your Exchange Server infrastructure and going hybrid? You are interested in what Exchange Server 2016 has to offer for your environment? Contact me at thomas@mcsmemail.de Follow at https://twitter.com/stensitzki
On Saturday, May 11th, the SharePoint Saturday Cologne will take place at Microsoft Office.
My session covers the migration of legacy public folders to modern public folders in the cloud.
Migrating from legacy public folders to modern public folders in Exchange Online is an error-prone process. Especially for Exchange organizations using legacy public folders since the early days. Real world examples from the field will show you how to determine the right migration approach. Additional information will help you to avoid the most common errors when migrating to modern public folders to the cloud. But what about after migrating to the? There is more. Prepare for decommissioning Public Folders by moving content to Microsoft Teams.
See you in Cologne.
When you want to migrate your legacy public folders from Exchange 2010 to modern public folders in Exchange Online you must prepare the public folder names for migration.
Public folder names are not allowd to contain the following:
The script Fix-PublicFolderNames.ps1 fixes the public folder names in preparation for migration to modern public folders.
# EXAMPLE # Rename and trim public folders found on Server MYPFSERVER .\Fix-PublicFolderNames -PublicFolderServer MYPFSERVER
This script will generate a report for Exchange 2007/2010 Public Folder Replication. It returns general information, such as the total number of public folders, total items in all public folders, the total size of all items, the top 20 largest folders, and more. Additionally, it lists each Public Folder and the replication status on each server.
By default, this script will scan the entire Exchange environment in the current domain and all public folders. This can be limited by using the -ComputerName and -FolderPath parameters.
Generate a public folder generation report for public folder \MYPUBLICFOLDER having replicas on servers MXSRV01, MXSRV02, MXSRV03
Get-PublicFolderReplicationReport.ps1 -ComputerName MXSRV01,MXSRV02,MXSRV03 -FolderPath "\MYPUBLICFOLDER" -Recurse -Subject "Public Folder Environment Report" -AsHTML -To postmaster@varunagroup.de -From postmaster@varunagroup.de -SmtpServer relay.mcsmemail.de -SendEmail
Example report
If you want to simplify the report generation, create an additional script: Run-PublicFolderReplicationReport.ps1
param( [string]$publicFolderPath = '' ) # Variables # Custom label for email subject $label = 'Exchange 2007' $recipients = 'pfreports@mcsmemail.de' $sender = 'postmaster@mcsmemail.de' # array of public folder servers to query $publicFolderServers = @('EX2007-01','EX2010-01') # SMTP server to relay mail $smtpServer = 'relay.mcsmemail.de' # Used to trigger a dedicated report for \GrFolder1\Folder1, \GrFolder1\Folder2 $granularRootFolder = @() # @("\Folder01") $subPath = '' # Check for granular folders, Added 2016-01-19 if($granularRootFolder -contains $publicFolderPath) { $subPath = $publicFolderPath $publicFolderPath = '' } # if($publicFolderPath -ne '') { Write-Host "Generating Public Folder reports for $($publicFolderPath)" # Generate report for a single public folder | Change COMPUTERNAME attribute for servers to analyse .\Get-PublicFolderReplicationReport.ps1 -ComputerName $publicFolderServers -FolderPath $publicFolderPath -Recurse -Subject "Public Folder Environment Report [$($publicFolderPath)] [$($label)]" -AsHTML -To $recipients -From $sender -SmtpServer $smtpServer -SendEmail } else { if($subPath -ne '') { $publicFolderPath = $subPath } else { $publicFolderPath = '\' } if($granularRootFolder.Count -ne 0) { Write-Host 'Following root folders will be excluded when using "\":' $($granularRootFolder) } Write-Host "Generating Public Folder reports for all folders in $($publicFolderPath)" $folders = Get-PublicFolder $publicFolderPath -GetChildren # Generate a single report for each folder in root $folderCount = ($folders | Measure-Object).Count $pfCount = 1 foreach($pf in $folders) { # Check, if folder is in list of granular folders if($granularRootFolder -notcontains $pf) { if($pf.ParentPath -eq '\') { $name = "$($pf.ParentPath)$($pf.Name)" } else { $name = "$($pf.ParentPath)\$($pf.Name)" } $activity = 'Generating Stats' $status = "Fetching $($name)" Write-Progress -Activity $activity -Status $status -PercentComplete (($pfCount/$folderCount)*100) .\Get-PublicFolderReplicationReport.ps1 -ComputerName $publicFolderServers -FolderPath $name -Recurse -Subject "Public Folder Environment Report [$($name)] [$($label)]" -AsHTML -To $recipients -From $sender -SmtpServer $smtpServer -SendEmail $pfCount++ } } }
Use the $granularRootFolder array to add root public folders which require a dedicated report for each sub-folder.
Additional credits go to Mike Walker (blog.mikewalker.me)
This Powershell script has been optimized using the ISESteroids™ add-on. Learn more about ISESteroids™ here.
When you want to migrate your modern public folders from Exchange 2013 or newer to modern public folders in Exchange Online, you must prepare the public folder names for migration.
Public folder names are not allowed to contain the following:
The script Fix-ModernPublicFolderNames.ps1 fixes the public folder names to prepare migration to modern public folders in Exchange Online.
# EXAMPLE 1 # Rename and trim public folders .\Fix-ModernPublicFolderNames.ps1 # EXAMPLE 2 # Rename and trim public folders, export list of renamed # folders and folders with renaming errors as text files .\Fix-ModernPublicFolderNames.ps1 -ExportFolderNames
Are you located in Germany, Austria, or Switzerland? Join the Exchange User Group DACH to collaborate with other Exchange enthusiasts. Follow us on Twitter @exusg.