我正在尝试从 SharePoint Diary 执行下面的脚本。
它对我有用......部分。我确实有版本删除,但是一旦脚本扫描大文件,我就会在终端中收到错误。最常见的是:
Scanning File: file.psd
Get-PnPProperty: C:\Users\Thibault\SharePoint_ClearLibraryVersionHistory.ps1:19
Line |
19 | … $Versions = Get-PnPProperty -ClientObject $File -Property Versions
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Operation is not valid due to the current state of the object.
确实,它的文档库中有许多 psd 和 psb 文件,它们很重(几 GB),而这些正是我们要删除但脚本忽略的文件。
我日以继夜地阅读所有可能的文档,但没有成功。至少可以说我有点绝望^^
提前非常感谢您的帮助;)
#Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/IC"
$LibraryName = "Energy"
Try {
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Interactive
#Get the Library
$Library = Get-PnPList -Identity $LibraryName
$global:counter=0
#Get All Items from the List - Get 'Files
$ListItems = Get-PnPListItem -List $Library -Fields FileLeafRef,FileRef -PageSize 2000 -ScriptBlock { Param($items) $global:counter += $items.Count; Write-Progress `
-PercentComplete ($global:Counter / ($Library.ItemCount) * 100) -Activity "Getting Files of '$($Library.Title)'" `
-Status "Processing Files $global:Counter of $($Library.ItemCount)";} | Where {($_.FileSystemObjectType -eq "File")}
Write-Progress -Activity "Completed Retrieving Files!" -Completed
#Loop through each file
$global:counter=1
ForEach ($Item in $ListItems)
{
#Get File and File Versions
$Versions = Get-PnPFileVersion -Url $Item.FieldValues.FileRef
Write-host -f Yellow "Scanning File ($global:counter of $($Library.ItemCount)) : $($Item.FieldValues.FileRef)"
If($Versions.Count -gt 0)
{
#Delete all versions
$Versions.DeleteAll()
Invoke-PnPQuery
Write-Host -f Green "`tDeleted All Previous Versions of the File!" #"$Item.FieldValues.FileRef
}
$global:counter++
}
}
Catch {
write-host -f Red "Error Cleaning up Version History!" $_.Exception.Message
}
我尝试了在网络上和 ChatGPT 上找到的许多脚本,但返回的错误始终相同。
我尝试了 DMS Shuttle 工具的试用版,它的效果非常好。但它不是免费的,你必须付费才能清理 TB 的数据^^。
更新
我的研究(感谢@mclayton)表明大于 2 GB 的文件将被忽略。
所以我对特定文件尝试了这种方法:
# Define Parameters
$site1 = "https://contoso.sharepoint.com/sites/MySite"
$relativePath = "/sites/MySite/Documents partages/Livraisons/subfolder/FRONT/_subfolder 2023/img.psb"
# Connect to SharePoint Online site
Connect-PnPOnline -Url $site1 -Interactive
$context = Get-PnPContext
$file = $context.Web.GetFileByServerRelativeUrl($relativePath)
# load file object without versions property
$context.Load($file)
$context.ExecuteQuery()
#delete all versions
$file.Versions.DeleteAll()
$context.ExecuteQuery()
而且它立即生效了!没有了:
由于对象的当前状态,操作无效。
但是我们现在如何在站点库中的所有文件上重现此操作?
我正在回答我自己的问题,因为我终于找到了解决方案!
问题比预期更棘手,因为:
Get-PnPProperty
不能处理大文件(可能超过 2GB,但甚至可能只有 250MB)。但这也适用于其他命令,例如 Get-PnPFileVersion
。Get-PnPContext
方法是正确的,但它必须应用于整个文档库,并且诸如Get-PnPList
或Get-PnPListItem
之类的命令没有检索所有文件(同样,可能是因为它们太重或给定文件的版本太多)。因此,技巧是递归地使用
Get-PnPFileInFolder
,最重要的是,在处理文件之前不要加载版本属性(或任何其他属性)。
通过这种方式,我们得到了我们想要的:SharePoint库中所有文件的所有版本都被删除,即使是大文件或具有多个版本的文件。该脚本确实需要一点时间来运行,因为所有文件都将被扫描(系统文件夹中的文件除外),但它的工作原理就像一个魅力(在多个库上进行了测试)。
一点好处:在执行结束时,脚本会生成一个 csv 文件,总结所有执行的操作。
根据您的环境修改参数
$siteUrl
、$libraryName
、$csvFilePath
,瞧!
就我而言,我能够恢复 SharePoint 中超过 550GB 的可用存储空间,而无需在软件解决方案上花费任何金钱;)
哦,最后一点:如果您不想再这样做,请记住禁用版本控制(当然,如果您不使用它)。 SharePoint Diary 脚本,尤其是名为 PnP PowerShell 以禁用列表上的版本控制 的脚本,可以完美运行。
脚本(希望有帮助):
# Define Parameters
$siteUrl = "https://mycompagny.sharepoint.com/sites/Marketing"
$libraryName = "Documents"
$csvFilePath = "C:\Users\USERNAME\VersionCleanupReport.csv"
# Initialize array to store operation details
$operationDetails = @()
# Connect to SharePoint Online site
Connect-PnPOnline -Url $siteUrl -Interactive
# Get all files in the document library
$files = Get-PnPFolder -ListRootFolder $libraryName | Get-PnPFileInFolder -Recurse -ExcludeSystemFolders
# Iterate through each file
foreach ($file in $files) {
# Attempt to delete all versions of the file
try {
Write-Host -ForegroundColor Yellow "Scanning file: $($file.ServerRelativeUrl)"
# Get the file object without loading version properties
$context = Get-PnPContext
$fileObject = $context.Web.GetFileByServerRelativeUrl($file.ServerRelativeUrl)
$context.Load($fileObject)
$context.ExecuteQuery()
# Check if the file has versions
$versions = $fileObject.Versions
$context.Load($versions)
$context.ExecuteQuery()
$versionsCount = $versions.Count
if ($versionsCount -gt 0) {
# Delete all versions of the file
$fileObject.Versions.DeleteAll()
$context.ExecuteQuery()
Write-Host -ForegroundColor Green "Deleted $versionsCount versions of file: $($file.ServerRelativeUrl)"
# Add operation details to the array
$operationDetails += [PSCustomObject]@{
"File" = $file.ServerRelativeUrl
"Operation" = "Deleted all versions"
"Timestamp" = Get-Date
}
} else {
Write-Host -ForegroundColor DarkGray "No versions to delete for file: $($file.ServerRelativeUrl)"
}
} catch {
Write-Host -ForegroundColor Red "Error processing file: $($file.ServerRelativeUrl) - $_"
# Add error details to the array
$operationDetails += [PSCustomObject]@{
"File" = $file.ServerRelativeUrl
"Operation" = "Error"
"ErrorMessage" = $_.Exception.Message
"Timestamp" = Get-Date
}
}
}
# Export operation details to CSV file
$operationDetails | Export-Csv -Path $csvFilePath -NoTypeInformation -Encoding UTF8
# Disconnect from SharePoint Online site
Disconnect-PnPOnline