A client recently had a case where a migration of tens of thousands of documents into a document library failed, and they wanted to delete everything and start over. It turns out there is no easy ‘Delete Everything’ button or API call in SharePoint. Instead, I came up with this gem to fairly quickly check in any ‘orphan’ files, delete a few thousand items in batches of 1000, and then delete all folders:
param($url,$libraryName)
$w = get-spweb $url
$l = $w.Lists[$libraryName]
$format = "<Method><SetList Scope=`"Request`">$($l.ID)</SetList><SetVar Name=`"ID`">{0}</SetVar><SetVar Name=`"Cmd`">Delete</SetVar><SetVar Name=`"owsfileref`">{1}</SetVar></Method>"
function DeleteAllFiles($folder)
{
$count = $folder.Files.Count - 1
if($count -gt -1){
Write-Host "Deleting $count files..."
for($i = $count; $i -gt -1; $i--){
$f = $folder.Files[$i];
if($f.CheckOutStatus -ne [Microsoft.SharePoint.SPFile+SPCheckOutStatus]::None){
$f.CheckIn("Checkin by admin");
}
$f.Delete()
}
}
}
function BuildBatchDeleteCommand($items)
{
$sb = new-object System.Text.StringBuilder
$sb.Append("<?xml version=`"1.0`" encoding=`"UTF-8`"?><Batch>")
$items | %{
$item = $_
$sb.AppendFormat($format,$item.ID.ToString(),$item.File.ServerRelativeUrl.ToString())
}
$sb.Append("</Batch>")
return $sb.ToString()
}
$count = $l.CheckedOutFiles.Count -1;
Write-Host "Taking over $count items that have never been checked in."
for($i = $count; $i -gt -1; $i--){
$f = $l.CheckedOutFiles[$i];
$f.TakeOverCheckOut()
Write-Host $f.Url
}
Write-Host "Deleting $($l.Items.Count) items"
while($l.Items.Count -gt 0){
$q = new-object "Microsoft.SharePoint.SPQuery"
$q.ViewFields="<FieldRef Name=`"ID`" />"
$q.ViewAttributes = "Scope=`"Recursive`""
$q.RowLimit=1000
$items = $l.GetItems($q)
$cmd = BuildBatchDeleteCommand($items)
Write-Host "Deleting $($items.Count) items..."
$result = $w.ProcessBatchData($cmd)
if ($result.Contains("ErrorText")){ break; }
Write-Host "Deleted. $($l.Items.Count) items left..."
}
Write-Host "Deleting $count folders..."
$l.Folders | %{$_.Url.ToString()} | sort -descending | %{
$folder = $_
$folder
$f = $w.GetFolder($folder)
$f.Files.Count
$f.Delete()
}
No comments:
Post a Comment