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?

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!