Fix “List cannot be deleted while on hold or retention policy” Error on SharePoint Online

Problem: When trying to delete a document library in SharePoint Online, it gave an error message: “list cannot be deleted while on hold or retention policy.”

list cannot be deleted while on hold or retention policy

Solution:

As the error message says: List cannot be deleted while on hold or retention policy. This error is due to the site being under hold or retention policy. So, to delete the list, you must delete all its files and sub-folders first. Otherwise, you should remove the retention policy under Office 365 compliance center. You can quickly check if the site is under hold by going to:

  • Admin centers >> Security & Compliance >> Search & investigation
  • Click on eDiscovery, check if you have created any case. >> If you see any case, click Open
  • Under Hold, Check if you see any site.  

Deleting files at each folder could be haunting, especially with a deep folder structure. Fortunately, we have PowerShell to relieve the burden.

PowerShell to Clear Document Library’s Content and then Delete

This PowerShell script deletes all files, then sub-folders, and then the given document library in SharePoint Online.

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

#Variables
$SiteURL = "https://crescent.sharepoint.com/Sites/Marketing"
$LibraryName = "Branding Templates"
 
#Function to Delete all files and Sub-folders of a given Folder
Function Empty-SPOFolder([Microsoft.SharePoint.Client.Folder]$Folder)
{
    Try {
        #Get All Files from the Folder
        $Files = $Folder.Files
        $Ctx.Load($Files)
        $Ctx.ExecuteQuery()
  
        #Iterate through each File in the folder
        Foreach($File in $Files)
        {
            #Delete the file
            $Folder.Files.GetByUrl($File.ServerRelativeUrl).Recycle() | Out-Null
            Write-host -f Green "Deleted File '$($File.Name)' from '$($File.ServerRelativeURL)'"
        }
        $Ctx.ExecuteQuery()
  
        #Process all Sub Folders of the given folder
        $SubFolders = $Folder.Folders
        $Ctx.Load($SubFolders)
        $Ctx.ExecuteQuery()
        Foreach($Folder in $SubFolders)
        {
            #Exclude "Forms" and Hidden folders
            If( ($Folder.Name -ne "Forms") -and (-Not($Folder.Name.StartsWith("_"))))
            {
                #Call the function recursively to empty the folder
                Empty-SPOFolder -Folder $Folder
 
                #Delete the folder
                $Ctx.Web.GetFolderById($Folder.UniqueId).Recycle() | Out-Null
                $Ctx.ExecuteQuery()
                Write-host  -f Green "Deleted Folder:"$Folder.ServerRelativeUrl
            }
        }
    }
    Catch {
    write-host -f Red "Error:" $_.Exception.Message
    }
}
 
Try {
    #Get Credentials to connect
    $Cred= Get-Credential
 
    #Setup the context
    $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
    $Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
   
    #Get the Library
    $Library = $Ctx.web.Lists.GetByTitle($LibraryName)
    $RootFolder = $Library.RootFolder
    $Ctx.Load($Library)
    $Ctx.Load($RootFolder)
    $Ctx.executeQuery()

    #Call the function to empty Folder
    Empty-SPOFolder $RootFolder
 
    #Delete the Document Library
    $Library.Recycle() | Out-Null
    $Ctx.ExecuteQuery() 
    Write-host  -f Green "Deleted Document Library Successfully!"
}
Catch {
    write-host -f Red "Error:" $_.Exception.Message
}
Use “File Explorer” view to delete all files and folders from a SharePoint Online Document Library in one shot!

Delete Document Library in Retention Hold using PnP PowerShell

Let’s fix the “list cannot be deleted while on hold or retention policy” error on SharePoint Online by deleting all files and folders first and then the document library using PnP PowerShell. Please note, if a file is checked out, you can’t delete it! It must be checked in to be able to delete. PowerShell to Bulk Check In All Documents in SharePoint Online

#Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/Marketing"
$ListName = "Branding Templates"

#Connect to the Site
Connect-PnPOnline -URL $SiteURL -Credentials (Get-Credential)

#Get the web & document Library
$Web = Get-PnPWeb
$List = Get-PnPList -Identity $ListName

#Function to delete all Files and sub-folders from a Folder
Function Empty-PnPFolder([Microsoft.SharePoint.Client.Folder]$Folder)
{
    #Get the site relative path of the Folder
    If($Folder.Context.web.ServerRelativeURL -eq "/")
    {
        $FolderSiteRelativeURL = $Folder.ServerRelativeUrl
    }
    Else
    {        
        $FolderSiteRelativeURL = $Folder.ServerRelativeUrl.Replace($Folder.Context.web.ServerRelativeURL,[string]::Empty)
    }

    #Get All files in the folder
    $Files = Get-PnPFolderItem -FolderSiteRelativeUrl $FolderSiteRelativeURL -ItemType File
    
    #Delete all files in the Folder
    ForEach ($File in $Files)
    {
        #Delete File
        Remove-PnPFile -ServerRelativeUrl $File.ServerRelativeURL -Force -Recycle
        Write-Host -f Green ("Deleted File: '{0}' at '{1}'" -f $File.Name, $File.ServerRelativeURL)        
    }

    #Process all Sub-Folders
    $SubFolders = Get-PnPFolderItem -FolderSiteRelativeUrl $FolderSiteRelativeURL -ItemType Folder
    Foreach($SubFolder in $SubFolders)
    {
        #Exclude "Forms" and Hidden folders
        If( ($SubFolder.Name -ne "Forms") -and (-Not($SubFolder.Name.StartsWith("_"))))
        {
            #Call the function recursively
            Empty-PnPFolder -Folder $SubFolder

            #Delete the folder
            $ParentFolderURL = $FolderSiteRelativeURL.TrimStart("/")
            Remove-PnPFolder -Name $SubFolder.Name -Folder $ParentFolderURL -Force -Recycle
            Write-Host -f Green ("Deleted Folder: '{0}' at '{1}'" -f $SubFolder.Name, $SubFolder.ServerRelativeURL)
        }
    }
}

#Get the Root Folder of the Document Library and call the function to empty folder contents recursively
Empty-PnPFolder -Folder $List.RootFolder

#Now delete the document library
Remove-PnPList -Identity $ListName -Recycle -Force
Write-host -f Green "Document Library Deleted Successfully!"

If you just want to clear the document library without deleting the library, comment line#50 – Remove-PnPList. Here is another post on deleting all files and folders from a document library: SharePoint Online: How to Delete All Files in a Document Library using PowerShell?

PnP PowerShell to Empty a SharePoint Online Document Library

The above script just works fine with smaller libraries of < 5000 files. But on larger libraries, it gets “Get-PnPFolderItem : The attempted operation is prohibited because it exceeds the list view threshold.” error, as the Get-PnPFolderItem can’t handle large lists and libraries. So, here is the alternate script to empty a document library by deleting all files and folders in it faster with the PnP Batch method:

#Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/Inventory"
$ListName = "Branding Templates"
 
Try {
    #Connect to PnP Online
    Connect-PnPOnline -Url $SiteURL -Interactive
    $List =  Get-PnPList $ListName
    $ItemCount =  $List.ItemCount
    If($ItemCount -eq 0) { Write-host "Document Library is Already Empty!" -f Yellow; Break}
 
    #Get All Items from the Library
    $global:counter = 0
    $ListItems = Get-PnPListItem -List $ListName -PageSize 500 -Fields ID -ScriptBlock { Param($items) $global:counter += $items.Count; Write-Progress -PercentComplete `
            ($global:Counter / $ItemCount * 100) -Activity "Getting Items from List" -Status "Getting Items $global:Counter of $($ItemCount)"}
    Write-Progress -Activity "Completed Getting Items from Library $($List.Title)" -Completed
 
    #Sort List Items based on Server Relative URL - Descending
    $SortedItems = $ListItems | Select-Object @{Name="ServerRelativeURL";Expression={$_.FieldValues.FileRef}}, ID | Sort-Object -Descending -Property ServerRelativeURL
     
    #Delete List Items in the Batch
    $Batch = New-PnPBatch
    ForEach ($Item in $SortedItems)
    {
        Remove-PnPListItem -List $ListName -Identity $Item.ID -Recycle -Batch $Batch
        #Write-host "Deleted Item:"$Item.ServerRelativeURL
    }
    Invoke-PnPBatch -Batch $Batch -Details
 
    Write-host -f Green "All Items in the Library deleted Successfully!"
 }
Catch {
    write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}

Salaudeen Rajack

Salaudeen Rajack - SharePoint Expert with Two decades of SharePoint Experience. Love to Share my knowledge and experience with the SharePoint community, through real-time articles!

2 thoughts on “Fix “List cannot be deleted while on hold or retention policy” Error on SharePoint Online

Leave a Reply

Your email address will not be published.