SharePoint - Delete List and Items Under Retention

Shaun VermaakCOG Lead Engineer
CERTIFIED EXPERT
My name is Shaun Vermaak and I have always been fascinated with technology and how we use it to enhance our lives and business.
Published:
Updated:
Edited by: Andrew Leniart
One of the results of enabling retention policies in SharePoint is that you cannot delete a container, such as a site, list of a folder, without deleting the containing content first.

This script is my attempt to address the issue, without disabling retention policies.

INTRODUCTION


One of the results of enabling retention policies in SharePoint is that you cannot delete a container, such as a site, list of a folder, without deleting the containing content first.


This is particularly annoying when you work with a list that has thousands and hundreds of thousands of items. This issue is aggravated if these items are in folders and subfolders.

For example, if you have a list with a folder and this folder has subfolders with items, if retention policies are enabled you will first need to remove the items from the subfolder, then delete the subfolder, then deleted the main folder, and finally, assuming the list is empty, you will be able to remove the list.

If you write a script to delete these items you might also hit the throttling threshold, further delaying the detection process


The script below is my attempt to address both these issues, one is to delete all items, and the second to be a script  that can be executed multiple times, even with multiple different accounts to delete the content of the list under retention as soon as possible.


The Script


Import-Module SharePointPnPPowerShellOnline

$SiteUrl = "https://dundermifflinpapercompany.sharepoint.com/";

# Can be credentials from file
$UserName = "";
$Password = "";
$List = "DeleteDemo";
$ListCacheFile = "C:\Temp\DeleteDemo.xml";
$CacheTimeoutInMinutes = 30;
 
$Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, (ConvertTo-SecureString $Password -AsPlainText -Force)

Connect-PnPOnline -Url $SiteUrl -Credentials $Cred;

$CacheAge = ((Get-Date) - (Get-Item $ListCacheFile).LastWriteTime).TotalMinutes;

if ((test-path -Path $ListCacheFile) -and ($CacheAge -lt $CacheTimeoutInMinutes))
{
    # Cache exist and have not expired yet
    $items = Import-Clixml -Path $ListCacheFile;
} else {
    # Get items from list
    $items = Get-PnPListItem -List $List -PageSize 5000|Select-Object ID;
    # Save items into cache file
    $items|Export-Clixml -Path $ListCacheFile;
}

# Enumerate through all items randomly and remove them
foreach ($item in ($items.GetEnumerator() | Sort-Object {Get-Random}))
{
    $item;
    Remove-PnPListItem -List $List -Identity $item.Id -force;
}


HOW IT WORKS


The script uses the powerful SharePoint PnP package to interact with SharePoint.

Import-Module SharePointPnPPowerShellOnline


$SiteUrl = "https://dundermifflinpapercompany.sharepoint.com/";


# Can be credentials from file
$UserName = "";
$Password = "";
$List = "DeleteDemo";
$ListCacheFile = "C:\Temp\DeleteDemo.xml";
$CacheTimeoutInMinutes = 30;
 
$Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, (ConvertTo-SecureString $Password -AsPlainText -Force)


Connect-PnPOnline -Url $SiteUrl -Credentials $Cred;

On the first run, a fter connecting to SharePoint, it loads the items into a collection $items and exports it to XML. This exported XML can then be used with any subsequent executions of the script, if the cache period is still valid.

$CacheAge = ((Get-Date) - (Get-Item $ListCacheFile).LastWriteTime).TotalMinutes;


if ((test-path -Path $ListCacheFile) -and ($CacheAge -lt $CacheTimeoutInMinutes))
{
    # Cache exist and have not expired yet
    $items = Import-Clixml -Path $ListCacheFile;
} else {
    # Get items from list
    $items = Get-PnPListItem -List $List -PageSize 5000;
    # Save items into cache file
    $items|Export-Clixml -Path $ListCacheFile;
}

This collection of items, regardless of whether it was loaded from cache or pulled directly from SharePoint, is randomize before attempting any deletions.

# Enumerate through all items randomly and remove them
foreach ($item in ($items.GetEnumerator() | Sort-Object {Get-Random}))
{
    $item;
    Remove-PnPListItem -List $List -Identity $item.Id -force;
}

This randomization is key in allowing multiple instances of the script to run consecutively. If the items were not randomized, the multiple running script would try and delete the same items and the deletion process will take longer than a single execution.

CONCLUSION

 

I hope you found this tutorial useful. You are encouraged to ask questions, report any bugs or make any other comments about it below. 

 

Note: If you need more "Support" about this topic, please consider using the Ask a Question feature of Experts Exchange. I monitor questions asked and would be pleased to provide any additional support required in questions asked in this manner, along with other EE experts...  

 

Please do not forget to press the "Thumbs Up" button if you think this article was helpful and valuable for EE members.

 

It also provides me with positive feedback. Thank you!

0
2,216 Views
Shaun VermaakCOG Lead Engineer
CERTIFIED EXPERT
My name is Shaun Vermaak and I have always been fascinated with technology and how we use it to enhance our lives and business.

Comments (0)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.