Public Folders in Microsoft Exchange are a feature that allows users to store and share information with others in their organization. They are typically used for collaboration and archiving purposes, providing a centralized location for users to access and manage shared content such as documents, calendars, contacts, and email messages.
Like an Exchange mailbox, you can export Public folders to PST, and we will discuss how to do it in this tutorial.
Requirements
- Access to an Exchange organization. Our tutorial focuses on Exchange Online/Exchange Server Subscription Edition (SE). For Exchange Online, you need to install the current Exchange Online PowerShell module (ExchangeOnlineManagement) and use Connect-ExchangeOnline to establish an authenticated session. Modern authentication is used, and interactive sign-in supports MFA.
Note that you also need sufficient Exchange Online RBAC permissions to run the public-folder cmdlets used in our tutorial. Public-folder management permissions include the Public Folder Management role group; the exact permissions depend on the cmdlet and operation being performed. - A Windows machine with a supported version of classic Outlook for Windows installed and configured with access to the target public folders. Note that our script requires classic Outlook for Windows because it relies on the Outlook COM object model. New Outlook for Windows does not support Outlook COM/VSTO add-ins and automation. Because Microsoft is continuing to transition Outlook for Windows toward the new Outlook experience, you should treat this COM-based method as a client-side, compatibility-dependent option rather than a long-term enterprise automation platform.
- Existing public folders are accessible in your Outlook client.
Listing Public Folders and User Permissions
Knowing which public folder to export is one part of exporting Exchange public folders to PST. Another is ensuring the user who will export the public folder can access it.
From the user’s perspective, they have access to the public folder if they can access it in Outlook. But for administrators, it is crucial to know how to list public folders and user permissions.
Public folders are contained inside public folder mailboxes. There can be many public folder mailboxes and also many public folders in each.
Using the Exchange Admin Center, you can view the public folder mailboxes:

And public folders.

Connect to Exchange Online
Before running the Exchange Online PowerShell commands in our article, you need to install and import the current ExchangeOnlineManagement module if it is not already installed:
Install-Module ExchangeOnlineManagement -Scope CurrentUser
Import-Module ExchangeOnlineManagement
Then connect to Exchange Online using the command below:
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
The sign-in process uses modern authentication and can prompt for MFA when MFA is required by your organization’s Microsoft Entra policies. After completing the export and any other Exchange Online tasks, disconnect the session with the command:
Disconnect-ExchangeOnline -Confirm:$false
Keep in mind that the account used to connect must have the Exchange Online RBAC permissions required for the public-folder cmdlets used below.
Run these commands in PowerShell to list all public folder mailboxes and public folders:
Get-Mailbox -PublicFolder -ResultSize Unlimited Get-PublicFolder -Recurse -ResultSize Unlimited | Select-Object Name, ParentPath, MailboxOwnerId

To get public folder permissions, the command you want is Get-PublicFolderClientPermission. To list permissions for one public folder, run this command:
Get-PublicFolderClientPermission -Identity <Public Folder>
For example, to get the UK London Sales permissions:
Get-PublicFolderClientPermission -Identity '\UK London Sales'

But if you want to get the permissions for all public folders, you do so like this:
Get-PublicFolder -Recurse -ResultSize Unlimited | Get-PublicFolderClientPermission

Important Limitations of the Outlook COM Export Method
Keep in mind that this export method relies on Outlook COM automation:
New-Object -ComObject Outlook.Application
Because of this, during the export process, you will require:
- Microsoft Outlook installed on the machine;
- an interactive user session;
- a configured Outlook profile with access to the public folders.
Note that this method is not a good option for:
- server-side automation;
- scheduled background tasks;
- CI/CD pipelines;
- non-interactive PowerShell sessions.
Keep in mind that in many cases, Outlook COM automation may behave unpredictably on Windows Server systems or disconnected RDP sessions (this is happening because Outlook was originally designed as a desktop app).
For large-scale or long-term enterprise workflows, you should not build new unattended automation around Outlook COM. The COM-based method depends on classic Outlook and an interactive Windows session, while New Outlook does not provide the Outlook COM object model. You should use Microsoft Purview eDiscovery for compliance and investigation workflows, or an appropriate server-side/API-based method when the requirement is to automate exports at scale.
Note. This method exports public folder content through the Outlook MAPI client and not directly from Exchange databases/Exchange Online.
Alternative Methods to Export Exchange Public Folders
Depending on your Exchange environment and compliance requirements, Outlook COM automation may not always be the best option for exporting public folder content. In enterprise environments, you should prefer server-side/compliance-oriented export methods.
| Method | Supported Environment | Notes |
|---|---|---|
| Outlook COM + PST | Exchange Online / Exchange Server SE | Simple but requires Outlook and interactive session |
| Microsoft Purview eDiscovery | Exchange Online | Recommended for compliance and eDiscovery exports; mailbox items can be exported to PST |
| New-MailboxExportRequest | Exchange Server On-Premises | Native server-side PST export for mailboxes |
Keep in mind that the New-MailboxExportRequest cmdlet cannot export modern Exchange public folders directly because public folders are not regular user mailboxes. This cmdlet is mainly used for mailbox PST exports in Exchange Server on-premises environments.
Tip. Although modern Unicode PST files support sizes up to 50 GB by default (and can be increased), very large PST files may reduce Outlook performance and increase the risk of corruption. For large public folders, you should consider exporting into multiple smaller PST files where practical.
Using Microsoft Purview eDiscovery for Exchange Online
For Exchange Online, you should use Microsoft Purview eDiscovery when the export is part of a compliance, investigation, or legal discovery workflow. Keep in mind that the classic Content Search and classic eDiscovery experiences were retired on August 31, 2025. New searches and exports are performed through the Microsoft Purview eDiscovery experience. The modern eDiscovery experience is primarily portal-based. Note that it is not a replacement for the Outlook COM script above: the Outlook method is a client-side export of a public folder through classic Outlook, while eDiscovery searches Exchange Online data and exports matching results as part of an investigation workflow.
Important: Legacy PowerShell export commands. Note that you should not use older tutorials that instruct you to automate Microsoft 365 eDiscovery PST exports through the legacy New-ComplianceSearchAction, Get-ComplianceSearchAction, or Set-ComplianceSearchAction export workflow. Microsoft retired the classic Content Search and eDiscovery experiences in 2025, and you should not treat the legacy export workflow as the current automation interface for Microsoft 365 eDiscovery. For new programmatic eDiscovery workflows, you need to use the Microsoft Graph eDiscovery API where the required eDiscovery licensing and permissions are available. For interactive investigations and occasional exports, use the Microsoft Purview eDiscovery portal.
Public folder search location
When searching Exchange Online public folders with Microsoft Purview eDiscovery, you should check if public folders are included in the search scope. In the eDiscovery search, you can use the organization-wide All public folders data source when you need to search content stored in Exchange public folder mailboxes. Do not assume that searching user mailboxes automatically includes public folders (public folder content is a separate search location).
You should use Purview eDiscovery when your goal is to search, investigate, preserve, or export matching content. If the requirement is to create a direct PST copy of a specific public-folder hierarchy, the Outlook-based method described earlier remains a different client-side workflow.
Note that, unlike Outlook COM automation, Microsoft Purview eDiscovery exports do not require Outlook to be installed on the workstation. The export is performed through the Microsoft Purview service rather than through the Outlook client.
Export a Public Folder to PST with PowerShell and Classic Outlook
You can use PowerShell to run the Outlook COM-based export in a repeatable way. However, because the script depends on Classic Outlook and an interactive Windows session, this method is not suitable for unattended/server-side automation. The export can be scripted with PowerShell by using the Outlook Object Model through COM automation.
Copy the code below and save it as Export-PublicFolder.ps1. You can also download this script from this Gist.
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]$PublicFolderPath,
[Parameter(Mandatory)]
[string]$PstFilePath
)
$Outlook = $null
$namespace = $null
$pfTopFolder = $null
$allPublicFolders = $null
$PublicFolderToExport = $null
$pstStore = $null
$pstRootFolder = $null
try {
## Initialize the Outlook COM object
$Outlook = New-Object -ComObject Outlook.Application
$namespace = $Outlook.GetNameSpace("MAPI")
## Find the Exchange Public Folder store in the current Outlook profile
$pfStores = @(
$namespace.Stores |
Where-Object { $_.ExchangeStoreType -eq 2 }
)
if ($pfStores.Count -eq 0) {
throw "Exchange Public Folder store was not found in the current Outlook profile."
}
if ($pfStores.Count -gt 1) {
throw "Multiple Exchange Public Folder stores were found in the current Outlook profile."
}
$pfStore = $pfStores[0]
$pfTopFolder = $pfStore.GetRootFolder()
## Find the specified public folder in the Outlook MAPI hierarchy
$folderPathParts = $PublicFolderPath -split '\\' |
Where-Object { $_ -and $_.Trim() }
# Skip the "All Public Folders" level because it is the first child
# of the Public Folder store in the Outlook hierarchy.
try {
$allPublicFolders = $pfTopFolder.Folders.Item("All Public Folders")
}
catch {
throw "The 'All Public Folders' folder was not found in the current Outlook profile."
}
if ($null -eq $allPublicFolders) {
throw "The 'All Public Folders' folder was not found in the current Outlook profile."
}
$PublicFolderToExport = $allPublicFolders
foreach ($folderName in $folderPathParts) {
try {
$PublicFolderToExport =
$PublicFolderToExport.Folders.Item($folderName)
}
catch {
throw "Public folder '$PublicFolderPath' was not found in the current Outlook profile."
}
}
## Create the PST export folder if it doesn't exist
$pstFolder = Split-Path -Path $PstFilePath -Parent
if ($pstFolder -and !(Test-Path -LiteralPath $pstFolder)) {
try {
$null = New-Item -ItemType Directory -Path $pstFolder -ErrorAction Stop
Write-Verbose "Output folder [$pstFolder] created."
}
catch {
throw "Failed to create the output folder [$pstFolder]. $($_.Exception.Message)"
}
}
## Do not overwrite an existing PST
if (Test-Path -LiteralPath $PstFilePath) {
throw "The PST file already exists: [$PstFilePath]. Specify a new PST file path."
}
## Attach the PST to the Outlook session
$namespace.AddStore($PstFilePath)
## Find the newly attached PST Store by its file path
$pstStore = $namespace.Stores |
Where-Object { $_.FilePath -eq $PstFilePath } |
Select-Object -First 1
if ($null -eq $pstStore) {
throw "The PST store [$PstFilePath] could not be found after attaching it to Outlook."
}
## Get the root Folder of the PST.
## Folder.CopyTo() requires a Folder object, not a Store object.
$pstRootFolder = $pstStore.GetRootFolder()
Write-Verbose "PST [$PstFilePath] attached as [$($pstStore.DisplayName)]."
## Start export
Write-Verbose "Starting public folder export to [$PstFilePath]."
$exportedFolder = $PublicFolderToExport.CopyTo($pstRootFolder)
if ($null -eq $exportedFolder) {
throw "The public folder [$PublicFolderPath] was not successfully copied to the PST."
}
Write-Verbose "Public folder export to [$PstFilePath] is finished."
}
catch {
throw
}
finally {
## Detach the PST if it was successfully attached
if ($pstRootFolder -and $namespace) {
try {
$namespace.RemoveStore($pstRootFolder)
Write-Verbose "PST [$PstFilePath] detached."
}
catch {
Write-Warning "Failed to detach PST [$PstFilePath]. $($_.Exception.Message)"
}
}
## Release COM objects
if ($pstRootFolder) {
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($pstRootFolder)
}
if ($pstStore) {
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($pstStore)
}
if ($PublicFolderToExport) {
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($PublicFolderToExport)
}
if ($allPublicFolders) {
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($allPublicFolders)
}
if ($pfTopFolder) {
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($pfTopFolder)
}
if ($namespace) {
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($namespace)
}
if ($Outlook) {
try {
$Outlook.Quit()
}
catch {
Write-Warning "Failed to close Outlook: $($_.Exception.Message)"
}
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($Outlook)
}
## Force garbage collection of remaining COM wrappers
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
}
Once you’ve saved the script, run it in PowerShell like so:
.\Export-PublicFolder.ps1 `
-PublicFolderPath 'UK Liverpool Sales' `
-PstFilePath C:\PublicFolderExport\uk_liverpool_sales.pst `
-Verbose
- -PublicFolderPath — This parameter accepts the public folder path relative to the ‘All Public Folders’ level. For example, ‘UK Liverpool Sales’ translates to “Public Folders – <ACCOUNT>\All Public Folders\UK Liverpool Sales’
- Suppose the UK Liverpool Sales public folder has a subfolder called Comp&Ben; then you can specify it as -PublicFolderPath ‘UK Liverpool Sales\Comp&Ben’.
- -PstFilePath — This parameter specifies the output PST file. If that path doesn’t exist, the script will create it. If the folder cannot be created, the script will terminate.

Note that our script is intentionally simplified for demonstration purposes. In production environments, you may want to extend it with logging, stronger validation, detailed error handling, and operational safeguards for large exports. Our script does not require recursive folder traversal because Folder.CopyTo() copies the selected folder together with its child folders and items.
Now check if the PST file has been created successfully:
Test-Path $PstFilePath
Possible Improvements for the Export Script
The example above demonstrates the basic approach for exporting Exchange public folders to PST using Outlook COM automation. However, in production environments, you can extend this script with additional reliability and automation features.
Folder hierarchy is preserved automatically
The Folder.CopyTo() method copies the selected public folder together with its child folders and items. Therefore, the script does not need to recursively call CopyTo() for each subfolder. Adding a recursive loop can result in duplicate folder exports.
Add Logging for Export Operations
For better troubleshooting and auditing, you should consider adding logging support to the script. For example, you can log:
- export start/end time;
- processed public folders;
- failed exports;
- PST file paths;
- permission-related errors.
You can use a simple approach like the following:
Start-Transcript
Stop-Transcript
or you can write custom log entries using:
Add-Content
Add Error Handling per Public Folder
Currently, a single export failure may terminate the entire script execution.
In larger environments, we recommend you to wrap each folder export operation inside separate try/catch blocks so that one problematic public folder does not stop the entire export process.
Note that this is extremely important when:
- permissions differ between folders;
- corrupted items exist;
- large folders timeout during export.
Adding a Progress Indicator
When you exporting large public folders, the process may run for a long time without visible activity. You can improve the user experience by adding progress indicators with:
Write-Progress
This helps you to monitor:
- currently processed folder;
- overall export progress;
- long-running export operations.
Troubleshooting Common Public Folder Export Errors
Outlook not found / COM object creation failed
In case the script returns errors similar to:
New-Object : Cannot create COM object Outlook.Application
or:
Retrieving the COM class factory for component failed
this usually means that Microsoft Outlook is not installed on the machine or Outlook has not been launched/configured at least once for the current user profile.
In order to fix this problem, follow the next steps:
- Install a supported version of classic Outlook for Windows (such as Microsoft 365 Apps/Outlook LTSC 2024);
- Create and config an Outlook profile;
- Launch Outlook once interactively;
- Run the PowerShell console under the same user profile.
MAPI errors
Some environments may return MAPI-related errors when exporting large public folders/when Outlook cached mode is corrupted.
Common examples include:
- MAPI_E_NOT_FOUND
- MAPI_E_FAILONEPROVIDER
- Cannot expand the folder
In order to resolve these problems, you should:
- Restart Outlook and PowerShell;
- Recreate the Outlook profile;
- Ensure the public folder is fully visible in Outlook;
- Disable Cached Exchange Mode temporarily;
- Verify if Outlook can open the public folder manually before running the script.
PST file locked
In case the PST file is already mounted in Outlook or opened by another process, the export may fail with access or file lock errors.
For example:
The process cannot access the file because it is being used by another process.
In order to fix this problem:
- Close Outlook completely;
- Ensure the PST file is not already attached;
- Use a different PST filename;
- Check antivirus software that may lock PST files during scanning.
Permission denied
In case the export completes with access denied errors/empty PST files, verify if the user has sufficient permissions on the public folder. You can do that by using the command:
Get-PublicFolderClientPermission -Identity '\PublicFolderName'
Note that at minimum, the exporting user should have Reviewer/higher permissions to the target public folder.
Wrapping up
Exporting public folders to PST with Outlook is primarily an interactive, client-side process. PowerShell can make the workflow more repeatable and easier to standardize, but it does not make Outlook COM suitable for unattended/server-side automation.
For compliance, investigation, or large-scale automated workflows, you should consider Microsoft Purview eDiscovery or an appropriate server-side/API-based approach instead.

Hello Cyril Kardashevsky
Server Details:
Windows 2008R2
Exchange 2010
Client Details:
Windows 10
Office 365 Apps
Error Description:
Error appears from line 50 – 52
I am trying to run this script directly from a domain joined Windows 10 client with Office365 Apps (32bit). Unfortunately it does not work. I have adjusted the path to C:BackupPublic Folders but that didn’t help either.
Can you possibly comment exactly the parts of the script to customize this way with the needed content?
Thanks for feedback
Hi,
I’m getting the same errors, any luck fixing this anybody?
Hi Cyril, could you expand on how you are constructing the variable: $PublicFolderToExport = $Outlook.Session.Folders.Item(‘Public Folders – Helpdesk’)…..
what are the elements level-1, level-2 etc… I’m trying to translate this to my environment where I have a structure:
\All Public Folders
\TestFolder1
If I merely substitute your value of ‘Public Folders – Helpdesk’ with ‘TestFolder1’ I get an error… so I’d like to understand how that folder path is being constructd & passed to the function…
Many thanks!
Hi June,
I am getting following error while I executing the script.
The attempted operation failed. An object could not be found.
At line:25 char:1
Write-Verbose : Cannot bind argument to parameter ‘Message’ because it is null.
At line:39 char:15
You cannot call a method on a null-valued expression.
The error indicates that the Public Folder Path you specified to the script is not found or there was no match. Ensure the public folder path does not include the “Public Folders – \All Public Folders\” part and should be specified in the script as it is written in Outlook.
Dear
Thanks for the script. It’s working for me.
However, the script exports the folder I specify, but also all sub folders and their items.
How can I avoid that sub folders and their items are exported too?
I just want to export specific public folders in the middle of the PF name space.
Thanks for the feedback.
Regards
Peter