Bei einer Datenmigration wurd in meinem Unternehmen tausende Dateien auf eine falsche SharePoint-Site migriert. Das waren so viele Dokumente in einem einzigen Ordner, dass man ihn weder Teilen, noch verschieben oder löschen konnte.
Bei jedem Vorgang erschien der Fehler "The attempted operation is prohibited because it exceeds the list view threshold."
Die Lösung für dieses Problem war diese Daten erneut auf eine dediziert für diese Daten erstellte SharePoint-Site zu migrieren und die bestehenden Dateien einzeln aus dem problematischen Ordner zu löschen. Das für 200.000 Dateien zu machen ist eine pure Qual.
Aus dem Grund schrieb ich mithilfe des PnP PowerShell Moduls ein kleines Skript:
# Das PnP PowerShell Modul muss vor der Benutzung installiert sein: # Install-Module -Name PnP.PowerShell #Parameters #Make sure not to write a '/' at the end! $SiteURL = "https://Company.sharepoint.com/teams/SiteOrGroupName" $ListName = "Freigegebene Dokumente/General/Ordner1" if($SiteURL -match "/teams/"){ $pos = $SiteURL.IndexOf("/teams/") $mainURL = $SiteURL.Substring(0, $pos) } if($SiteURL -match "/sites/"){ $pos = $SiteURL.IndexOf("/sites/") $mainURL = $SiteURL.Substring(0, $pos) } #Connect to Site Connect-PnPOnline -Url $SiteURL -Interactive #Get the List $List = Get-PnPList -Identity $ListName #Get all Files from List - with progress bar $global:counter = 0; $Files = Get-PnPListItem -List $List -PageSize 500 -Fields FileLeafRef -ScriptBlock { Param($items) $global:counter += $items.Count; Write-Progress -PercentComplete ($global:Counter / ($List.ItemCount) * 100) -Activity "Getting Files from List:" -Status "Processing Items $global:Counter to $($List.ItemCount)";} | Where {$_.FileSystemObjectType -eq "File"} Write-Progress -Activity "Getting Files from List:" -Status "Ready" -Completed $folder = ($SiteURL -replace "$mainURL",'') + '/' + $ListName + '/' $slashCount = ($folder.ToCharArray() | Where-Object {$_ -eq '/'} | Measure-Object).Count $slashCount #Grab only those files in the defined folder $toDelete = ($Files | Where {$_.FieldValues.FileRef -like "$folder*"} | Where {(($_.FieldValues.FileRef.ToCharArray() | Where-Object {$_ -eq '/'} | Measure-Object).Count) -eq $slashCount}).FieldValues.FileRef # Uncomment here, if you want to delete recursively #$toDelete = ($Files | Where {$_.FieldValues.FileRef -like "$folder*"}).FieldValues.FileRef if($toDelete -ne $NULL){ $i = 1 foreach($file in $toDelete){ cls $gesamt = $toDelete.Count $pending = $gesamt - $i $hoursLeft = $pending / 14400 $timeLeft = "{0:N3}" -f $hoursLeft Write-Host "`n" Write-Host " #####################################" Write-Host " # #" Write-Host " # This tool removes all files #" Write-Host " # of the SharePoint folder #" Write-Host " # defined in the source code. #" Write-Host " # #" Write-Host " #####################################`n" Write-Host " Folder: $folder`n" Write-Host " File $i of $gesamt removed.`n" Write-Host " $pending files pending." Write-Host " $timeLeft hours left.`n`n`n" Remove-PnPFile -ServerRelativeUrl "$file" -Force $i++ Start-Sleep -Milliseconds 250 } }else{ foreach ($second in (10..0)) { cls Write-Host " WARNING! " -BackgroundColor Red Write-Host " No suitable folder defined. " -BackgroundColor Red Write-Host " Script will be closed in: $second " -BackgroundColor Red Start-Sleep -Seconds 1 } } Disconnect-PnPOnline
Eine Codezeile habe ich auskommentiert. Diese kann benutzt werden um auch alle Daten in den Unterordnern zu löschen.
Vorsicht bei der Benutzung. Am Besten testest du es zunächst auf einer SharePoint-Site mit Testdaten.
Keine Kommentare:
Kommentar veröffentlichen