Introduction: When SharePoint Retention Becomes a Storage Problem
I recently ran into a SharePoint storage problem that took me a little while to get to the bottom of.
We had deleted a significant amount of data from a SharePoint site and the recycle bins had been emptied, but the storage usage wasn’t dropping the way I expected.
That immediately made me start looking at where the storage was actually going.
That’s when I found the Preservation Hold Library (PHL).
If you’ve never dealt with it before, the Preservation Hold Library is a hidden SharePoint system library that Microsoft 365 uses to retain content when retention policies or other compliance requirements apply.
And it can get surprisingly large.
In our case, the PHL had grown to around 800 GB on a site using approximately 1.2 TB of storage.
That explained why deleting files from the normal SharePoint libraries wasn’t having the effect I expected. A large amount of the data wasn’t actually disappearing. SharePoint was retaining it because of the retention configuration.
This article walks through how I found the problem, how I measured the Preservation Hold Library, how I worked out why the data was being retained, and the PowerShell approach I used to deal with it.
This is not theory. This is a field-tested solution for IT professionals responsible for SharePoint storage, compliance, and Microsoft 365 governance.
What Is the Preservation Hold Library (PHL)?
The Preservation Hold Library is a hidden system library created automatically when:
- A retention policy applies to a SharePoint site
- A retention label with “retain” behavior is used
- Legal hold or eDiscovery retention is enforced
When users delete files under retention, SharePoint does not actually remove them. Instead:
- The content is copied into the Preservation Hold Library
- The file is retained until the retention period expires
- The user believes the file is gone, but storage continues to be consumed
This design ensures compliance – but it comes with a cost.
Why Can the Preservation Hold Library Become So Large?
The PHL can become surprisingly large on busy SharePoint sites.
Everyday collaboration can create a significant amount of retained data because users constantly:
- Create files
- Modify files
- Replace documents
- Delete documents
- Move files
- Upload new versions
When retention applies, some of that activity can result in content being preserved.
The problem becomes particularly noticeable when a site has been subject to retention for a long period or has experienced a large amount of file churn.
Other situations that can contribute include:
- Large migration projects
- Temporary project data
- Retention policies applied broadly across a tenant
- Retention policies being changed or removed
- Large amounts of document versioning
- Sites that have been heavily used for years
The result can be a SharePoint site where users have apparently cleaned everything up, while a large amount of retained data remains behind the scenes.
Important Warning: This Is a Permanent Action
Before going any further, this must be crystal clear:
Important – Deleting content from the Preservation Hold Library permanently removes retained data and bypasses the recycle bin.
You should only proceed if:
- The retention policy has been removed or expired
- Legal, compliance, and records teams have approved the deletion
- You understand the regulatory implications for your organization
In regulated industries (finance, health, government), this step should be documented and approved formally.
Why Microsoft Doesn’t Provide a “Clean Up” Button
A common question I get is:
“Why isn’t there a Microsoft-supported way to clean this up?”
The answer is risk.
Microsoft deliberately avoids providing UI-based deletion tools for retained data because:
- Retention is often tied to legal obligations
- Accidental deletion could invalidate legal holds
- Automation could conflict with eDiscovery processes
That leaves experienced IT admins with PowerShell as the only viable option.
The Approach: Using PnP.PowerShell
The PnP.PowerShell module provides the necessary control to:
- Access hidden SharePoint system libraries
- Enumerate large numbers of list items
- Permanently delete items without recycling
This script is designed to:
- Process items in batches
- Provide clear warnings
- Require explicit confirmation
- Permanently delete items (Recycle Bin bypassed)
First Step: Confirm the PHL Is Actually Using the Storage
Before deleting anything, prove that the Preservation Hold Library is the problem.
This is an important diagnostic step because SharePoint storage can also be consumed by:
- Document versions
- Recycle bins
- Teams files
- Site Assets
- Large media files
- Other SharePoint libraries
- Archived project data
Don’t assume the PHL is responsible just because the site has a retention policy.
Check the site’s storage
Start in the SharePoint admin centre and review the storage used by the affected site.
Record the current storage figure.
For example:
Site storage: 1.20 TB
You can then compare this with the size of the Preservation Hold Library.
Measure the Preservation Hold Library
Connect to the affected SharePoint site using PnP.PowerShell and run:
Get-PnPFolderStorageMetric -List "PreservationHoldLibrary"
This provides storage information for the library.
For example, you might discover:
Site storage: 1.20 TB
Preservation Hold Library: 800 GB
At that point you have a much stronger indication that retention data is contributing significantly to the storage problem.
If your investigation resulted in hundreds of gigabytes or terabytes being identified, put those figures in the article. Real numbers demonstrate the scale of the problem far better than simply saying the library had “grown out of control.”
Viewing the Preservation Hold Library
The Preservation Hold Library is hidden from normal SharePoint navigation.
If you have appropriate administrative permissions, you can access it directly using:
https://tenant.sharepoint.com/sites/SiteName/PreservationHoldLibrary
Replace tenant and SiteName with the appropriate values for your environment.
This is useful for confirming that the library exists and understanding the type and volume of content being retained.
You should still treat this as a system compliance location, not as a normal document library.
Find Out Why the Content Is Being Retained
Finding a large PHL is only half the investigation.
The next question is:
What retention policy or hold is causing this content to be retained?
Before removing anything, check Microsoft Purview for policies and holds affecting the SharePoint site.
Look for:
- Retention policies
- Retention labels
- eDiscovery holds
- Other compliance controls affecting the site
A site may be affected by more than one retention mechanism, so don’t assume that removing a single policy automatically makes all retained content eligible for deletion.
This is also where you need to involve your compliance, records or legal teams where appropriate.
The Safer Option: Let Microsoft 365 Handle the Cleanup
If the retention requirement has ended, the preferred approach is normally to remove the site from the applicable retention scope and allow Microsoft 365’s retention processing to handle the expired content.
This is considerably safer than immediately trying to delete the contents of the Preservation Hold Library yourself.
It is also important to set expectations.
The storage will not necessarily drop immediately.
Retention processing happens in the background, and Microsoft documents that cleanup can take time after content becomes eligible.
That means removing a retention policy today does not necessarily mean that hundreds of gigabytes of storage will disappear tomorrow.
If the content is legitimately no longer required, allow the Microsoft 365 retention process to complete before considering more aggressive administrative action.
When Manual Cleanup May Be Considered
There are situations where an administrator may need to investigate the PHL further after the retention requirement has ended.
For example:
- The applicable retention policy has been removed
- The site is no longer subject to a hold
- Compliance has confirmed that the content can be removed
- The normal retention processing period has passed
- Storage remains unexpectedly high
- You have documented approval for the proposed action
At this point, PowerShell can be useful for inspecting and administering SharePoint content.
However, this is where it is important to understand the distinction between what PowerShell can technically attempt and what Microsoft recommends as the normal retention workflow.
The Preservation Hold Library is a compliance mechanism. It should not be treated as an ordinary SharePoint library that can simply be emptied whenever storage gets high.
Connecting to SharePoint with Current PnP.PowerShell
There is another important consideration before running any PowerShell against SharePoint.
If you find older PnP.PowerShell examples online, you will often see:
Connect-PnPOnline -Url $SiteUrl -Interactive
On current versions of PnP.PowerShell, interactive authentication requires an Entra ID application registration unless you have configured a default client ID.
This means that simply copying an old script and running it can result in an authentication error before the script even reaches SharePoint.
Install PnP.PowerShell
If required:
Install-Module PnP.PowerShell -Scope CurrentUser
Register an Entra application
PnP.PowerShell provides a command for registering an application for interactive login:
Register-PnPEntraIDAppForInteractiveLogin `
-ApplicationName "PnP SharePoint Admin" `
-Tenant "tenant.onmicrosoft.com"
Alternatively, you can register the application yourself through Microsoft Entra ID and configure the required SharePoint permissions according to your organization’s security requirements.
Once you have the application/client ID, connect using:
Connect-PnPOnline `
-Url $SiteUrl `
-Interactive `
-ClientId "YOUR-ENTRA-APP-CLIENT-ID"
Replace YOUR-ENTRA-APP-CLIENT-ID with the client ID of your Entra application.
Test this connection before attempting any cleanup.
If authentication does not work, there is no point troubleshooting the deletion script.
Inspect the Library with PowerShell
Once connected, start by measuring the library:
$LibraryName = "PreservationHoldLibrary"
Get-PnPFolderStorageMetric -List $LibraryName
You can also enumerate the library’s contents:
Get-PnPListItem `
-List $LibraryName `
-PageSize 500 `
-ScriptBlock {
param($items)
$items.Context.ExecuteQuery()
} |
Select-Object Id, FileSystemObjectType
The important detail here is how -PageSize works.
-PageSize 500 means that PnP retrieves the underlying SharePoint results in pages of up to 500 items. It does not mean that Get-PnPListItem returns only 500 items and then stops.
The -ScriptBlock allows processing to occur as each page is retrieved.
This approach is much more appropriate when dealing with a library containing a large number of items because you avoid repeatedly requesting the entire library just to process another batch.
PowerShell Script: Process the Preservation Hold Library
If your organization has explicitly approved direct administrative cleanup, the following script provides a controlled way to process the library.
It:
- Connects using the current PnP authentication method
- Measures the PHL before starting
- Requires explicit confirmation
- Processes SharePoint results in pages
- Permanently deletes items rather than recycling them
- Counts successful and failed operations
- Reports progress while it runs
$SiteUrl = "https://tenant.sharepoint.com/sites/SiteName"
$ClientId = "YOUR-ENTRA-APP-CLIENT-ID"
$LibraryName = "PreservationHoldLibrary"
$PageSize = 500
Connect-PnPOnline `
-Url $SiteUrl `
-Interactive `
-ClientId $ClientId `
-ErrorAction Stop
Write-Host "Connected to $SiteUrl" -ForegroundColor Green
# Display current storage metrics
Write-Host "`nCurrent Preservation Hold Library storage:" -ForegroundColor Cyan
$metric = Get-PnPFolderStorageMetric -List $LibraryName
$metric | Format-List
Write-Host ""
Write-Host "WARNING: This is a destructive operation." -ForegroundColor Red
Write-Host "Only continue if all retention, legal and compliance requirements have been cleared." -ForegroundColor Yellow
$confirm = Read-Host "Type DELETE to continue"
if ($confirm -ne "DELETE") {
Write-Host "Operation cancelled." -ForegroundColor Yellow
Disconnect-PnPOnline
exit
}
$deleted = 0
$failed = 0
Get-PnPListItem `
-List $LibraryName `
-PageSize $PageSize `
-ScriptBlock {
param($items)
$items.Context.ExecuteQuery()
} |
ForEach-Object {
try {
Remove-PnPListItem `
-List $LibraryName `
-Identity $_.Id `
-Force `
-Recycle:$false `
-ErrorAction Stop
$deleted++
if (($deleted % 100) -eq 0) {
Write-Host "Processed $deleted items..." -ForegroundColor Gray
}
}
catch {
$failed++
Write-Host `
"Failed to delete item $($_.Id): $($_.Exception.Message)" `
-ForegroundColor Red
}
}
Write-Host ""
Write-Host "Processing complete." -ForegroundColor Green
Write-Host "Deleted: $deleted"
Write-Host "Failed: $failed"
Disconnect-PnPOnline
What the script is doing
The script deliberately processes the library as a stream of paged results rather than repeatedly querying the entire library.
The important part is:
Get-PnPListItem `
-List $LibraryName `
-PageSize $PageSize `
-ScriptBlock {
param($items)
$items.Context.ExecuteQuery()
}
Each returned item is then passed to:
Remove-PnPListItem `
-List $LibraryName `
-Identity $_.Id `
-Force `
-Recycle:$false
The -Recycle:$false parameter requests permanent deletion instead of sending the item to the SharePoint recycle bin.
However, this does not override Microsoft’s retention protections.
If SharePoint determines that content must still be retained, deletion can fail.
That is why the compliance and retention investigation must happen before this script is considered.
How to Run the Script
Save the script as:
Clear-PreservationHoldLibrary.ps1
Open PowerShell using an account with the appropriate SharePoint permissions.
Then run:
.\Clear-PreservationHoldLibrary.ps1
The script will connect to the SharePoint site, display the current PHL storage metrics and ask you to type:
DELETE
before processing the library.
Do not automate that confirmation away in a production environment unless your change-control process specifically requires it.
Monitor the Cleanup
Large SharePoint libraries can contain thousands or even hundreds of thousands of items.
If you encounter throttling or transient failures:
- Reduce the page size
- Consider running the operation during quieter periods
- Monitor the number of failed operations
- Investigate repeated failures rather than simply rerunning the script blindly
For example, you can reduce:
$PageSize = 500
to:
$PageSize = 200
The page size controls how results are retrieved. It is not a guarantee that exactly that number of files will be deleted in each operation.
Verify the Result
Don’t finish the job when the PowerShell window says “Processing complete.”
Measure the environment again.
Check:
- SharePoint site storage
- Preservation Hold Library storage
- Item count
- Recycle bin contents where applicable
- Any remaining retention or hold configuration
For example:
Get-PnPFolderStorageMetric -List "Preservation Hold Library"
Record the result.
Also remember that SharePoint storage reporting can take time to catch up with changes.
Keep before-and-after measurements so you can demonstrate exactly what changed.
Always Document the Change
Treat the removal of retained content with the same level of care you would apply to deleting backups or other critical business data.
Record:
- The affected SharePoint site
- The original storage consumption
- PHL storage consumption
- The retention policy or hold that caused the retention
- The reason the content was eligible for removal
- Compliance/records approval
- Date and time of the change
- Number of items processed
- Number of failed deletions
- Storage consumption after cleanup
This gives you an audit trail if the decision is questioned later.
When You Should NOT Use This Script
Do not attempt direct cleanup if:
- A retention policy still applies
- Retention labels are still protecting the content
- An eDiscovery or legal hold is active
- Litigation or regulatory requirements are ongoing
- You are unsure why the content exists
- Compliance or records teams have not approved the action
- You have not confirmed that the PHL is actually responsible for the storage problem
The Preservation Hold Library is a compliance mechanism, not a second recycle bin.
Compliance First, Cleanup Second
The Preservation Hold Library is one of those SharePoint features that works exactly as Microsoft designed it, but can still catch IT teams completely off guard.
The important lesson is that a SharePoint storage problem should be diagnosed before it is treated.
First, identify where the storage is being consumed.
Then determine whether the Preservation Hold Library is responsible.
Next, establish which retention policy, label or hold is causing the content to be retained.
If the retention requirement has ended, the safest approach is generally to allow Microsoft’s normal retention processing to perform the cleanup.
Only after the retention state has been properly investigated and the appropriate approvals obtained should you consider direct administrative intervention.
In my case, the investigation showed that 800GB of storage was tied up in the Preservation Hold Library. After the appropriate retention requirements were cleared and the cleanup process was completed, 800GB of storage was recovered.
Those numbers tell the real story.
SharePoint retention is doing its job. The challenge for administrators is understanding what it is retaining, where that data is stored, and when it is legitimately safe for that data to disappear.
Compliance first. Cleanup second.
The post How to Safely Clear the SharePoint Preservation Hold Library to Reclaim Storage Space appeared first on SuperTechman.
SuperTechman
Money Under 30
BusinessBlogs Hub
PC 'n' Mobile
EasypokerAPPs Blog
Tax Management NZ Blog