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.
Public Folders can be created to organize data into a hierarchical structure with multiple levels of folders and subfolders. Users can be granted specific permissions to access, edit, or delete items within these folders, allowing for controlled collaboration and information sharing within the organization.
Like an Exchange mailbox, you can export Public folders to PST, and we will discuss how to do so in this tutorial.
Table of Contents
Requirements
- Access to an Exchange organization. This tutorial will be using Exchange Online but should also work with Exchange Server 2016 and Exchange Server 2019.
- A Windows computer with Outlook 2016 or later.
- 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.
The following instructions assume you already have an Exchange PowerShell session open, whether Online or On-Premises.
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.
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
Export Public Folder to PST using Outlook
There are no built-in tools to export the content of Public Folders to PST files in the Exchange Server or Exchange Online. The PowerShell New-MailboxExportRequest cmdlet doesn’t support exporting Public Folder content to PST.
The most popular and easiest way to export the contents of a Public Folder to a PST file is the Import/Export feature built into Outlook. Let’s look at how to export the Public Folder content to the PST file using Outlook.
- Open Outlook and confirm that you can see the public folders.
- Click File → Open & Export → Import/Export.
- In the window that opens, select “Export to a file” and click Next.
- Select “Outlook Data File (.pst)” and click Next.
- Select the public folder you want to export and whether to include subfolders.
Note. Exporting the top-level public folder with all subfolders in one go is not advisable. Doing so can crash Outlook and potentially cause out-of-disk space problems on your computer.
- Specify the target PST filename and select “Replace duplicates with items exported”. Click Finish. In this example, I’m exporting the public folder to C:\Liverpool Accounting.pst.
- Optionally, add a password to protect the PST file. If you don’t want to add a password, leave the password fields blank and click OK.
- Wait for the export to finish.
- Confirm that the exported PST file exists.
Export Public Folder to PST using PowerShell
You can export public folders to PST using PowerShell, especially when you want to automate the process. This automation can be achieved using Microsoft.Office.Interop.Outlook Namespace.
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 ) ## Initialize the Outlook COM Object $Outlook = New-Object -ComObject Outlook.Application ## Compose the top public folder path <Public Folders - ACCOUNT_NAME\All Public Folders> $pfTopFolder = $Outlook.Session.Folders | Where-Object { $_.Name -like "Public Folders -*" } ## Append the specified $PublicFolderPath $PublicFolderPath = (($pfTopFolder.Name) + '\All Public Folders\' + $PublicFolderPath) Write-Verbose "Public Folder Parent = $PublicFolderPath" ## Split the folder path into levels $pfPath = $PublicFolderPath.Split('\') ## Initialize the public folder object to export. $PublicFolderToExport = $Outlook.Session.Folders.Item($pfPath[0]).Folders.Item($pfPath[1]) ## Append each public folder level for ($i = 2; $i -lt ($pfPath.count); $i++) { try { $PublicFolderToExport = $PublicFolderToExport.Folders.Item($pfPath[$i]) } catch { ## If the folder name does not exist, terminate the script. "The public folder path [$($PublicFolderPath)] does not exist." | Out-Default return $null } } Write-Verbose $($PublicFolderToExport.FullFolderPath) ## Create the PST export folder if it doesn't exist. $pstFolder = Split-Path $PstFilePath -Parent if (!(Test-Path $pstFolder)) { try { $null = New-Item -Type Directory -Path $pstFolder -ErrorAction Stop Write-Verbose "Output folder [$pstFolder] created." } catch { Write-Error "Failed to create the folder [$pstFolder]." Write-Error $_.Exception.Message return $null } } ## Initialize the PST store $namespace = $Outlook.GetNameSpace("MAPI") ## Attach the PST to the Outlook session $namespace.AddStore($PstFilePath) $pstOutlookStore = $namespace.Session.Folders.GetLast() Write-Verbose "PST [$PstFilePath] attached as [$($pstOutlookStore.Name)]." ## Start export. Write-Verbose "Start public folder export to [$PstFilePath]." [void]$PublicFolderToExport.CopyTo($pstOutlookStore) Write-Verbose "Start public folder export is finished." ## Detach PST from Outlook $namespace.RemoveStore($pstOutlookStore) Write-Verbose "PST [$PstFilePath] detached." $outlook.Application.quit()
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 this script is basic and can be improved. For one, it does not support exporting subfolders.
Conclusion
Exporting public folders to PST files is more or less a manual process. Using Outlook to export public folder content is convenient but can be cumbersome when exporting multiple public folders.
But with some PowerShell scripting strategy, it can be automated with consistent and repeatable results. Good luck!
5 comments
Hello Cyril Kardashevsky
Server Details:
Windows 2008R2
Exchange 2010
Client Details:
Windows 10
Office 365 Apps
Error Description:
Error appears from line 50 – 52
—————————————————————————————–
**********************
Unable to call a method on an expression that has the NULL.
In C:UsersladminDesktopPublicFolder-Export-MailboxFolder.ps1:52 characters:1
+ $PublicFolderToExport = $Outlook.Session.Folders.Item(‘Project Management …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
It is not possible to call a method for an expression that has the NULL.
In C:UsersladminDesktopPublicFolder-Export-MailboxFolder.ps1:52 characters:1
+ $PublicFolderToExport = $Outlook.Session.Folders.Item(‘Project Management …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
>> TerminatingError(New-Object) : “The COM class factory for the component with CLSID {0006F03A-0000-0000-C000-0000000046} could not be retrieved due to the following error: 80080005 Failed to start server (HRESULT exception: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).”
New-Object : The COM class factory for the component with CLSID {0006F03A-0000-0000-C000-0000000046} could not be retrieved due to the following error
could not be retrieved due to the following error: 80080005 Failed to start server (HRESULT exception:
0x80080005 (CO_E_SERVER_EXEC_FAILURE)).
In C:UsersladminDesktopPublicFolder-Export-MailboxFolder.ps1:7 characters:20
+ $Outlook = New-Object -ComObject Outlook.Application
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [New-Object], COMException
+ FullyQualifiedErrorId : NoCOMClassIdentified,Microsoft.PowerShell.Commands.NewObjectCommand
New-Object : The COM class factory for the component with CLSID {0006F03A-0000-0000-C000-00000046} could not be retrieved due to the following error: 80080005 Starting the server
failed (exception of HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).
In C:UsersladminDesktopPublicFolder-Export-MailboxFolder.ps1:7 characters:20
+ $Outlook = New-Object -ComObject Outlook.Application
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [New-Object], COMException
+ FullyQualifiedErrorId : NoCOMClassIdentified,Microsoft.PowerShell.Commands.NewObjectCommand
It is not possible to call a method for an expression that has the NULL.
In C:UsersladminDesktopPublicFolder-Export-MailboxFolder.ps1:9 characters:9
+ $namespace = $Outlook.GetNameSpace(“MAPI”)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
It is not possible to call a method for an expression that has the NULL.
In C:UsersladminDesktopPublicFolder-Export-MailboxFolder.ps1:9 characters:9
+ $namespace = $Outlook.GetNameSpace(“MAPI”)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
New-Item : An item with the specified name “C:BackupPublicFolder” already exists.
In C:UsersladminDesktopPublicFolder-Export-MailboxFolder.ps1:15 characters:9
+ New-Item -Path ‘C:BackupPublicFolder’ -Name “$($folder.Name …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceExists: (C:BackupPublicFolder:String) [New-Item], IOException
+ FullyQualifiedErrorId : DirectoryExist,Microsoft.PowerShell.Commands.NewItemCommand
New-Item : An item with the specified name “C:BackupPublicFolder” already exists.
In C:UsersladminDesktopPublicFolder-Export-MailboxFolder.ps1:15 characters:9
+ New-Item -Path ‘C:BackupPublicFolder’ -Name “$($folder.Name …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceExists: (C:BackupPublicFolder:String) [New-Item], IOException
+ FullyQualifiedErrorId : DirectoryExist,Microsoft.PowerShell.Commands.NewItemCommand
Remove attached PST in Outlook
—————————————————————————————–
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
+ $PublicFolderToExport = $Outlook.Session.Folders.Item($pfPath[0]).Fol …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
Write-Verbose : Cannot bind argument to parameter ‘Message’ because it is null.
At line:39 char:15
+ Write-Verbose $($PublicFolderToExport.FullFolderPath)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Write-Verbose], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.WriteVerboseCommand
You cannot call a method on a null-valued expression.
At line:63 char:1
+ [void]$PublicFolderToExport.CopyTo($pstOutlookStore)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
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.