Я пытаюсь выполнить приведенный ниже сценарий из Дневника SharePoint.
И у меня это работает... частично. У меня есть удаления версий, но как только скрипт сканирует большой файл, в терминале появляются ошибки. Наиболее распространенное из них:
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 файлов, они тяжелые (несколько ГБ) и это именно те, которые мы хотим удалить и которые скрипт игнорирует.
Я провожу день и ночь за чтением всей возможной документации, но безуспешно. Я, мягко говоря, немного в отчаянии^^
Заранее большое спасибо за помощь ;)
#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
}
Я пробовал множество скриптов, найденных в Интернете и с помощью
Я попробовал пробную версию инструмента DMS Shuttle, и она сработала просто великолепно. Но это не бесплатно, и за очистку ТБ данных придется платить^^.
ОБНОВЛЯТЬ
Мои исследования (спасибо @mclayton) показывают, что файлы размером более 2 ГБ игнорируются.
Поэтому я попробовал этот подход для конкретного файла:
# 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()
И это сработало мгновенно! Больше не надо :
Операция недопустима из-за текущего состояния объекта.
Но как теперь воспроизвести это действие со всеми файлами в библиотеке сайта?
🤔 А знаете ли вы, что...
С PowerShell можно настраивать и управлять сетевыми настройками и брандмауэром.
Я отвечаю на свой вопрос, потому что наконец нашел решение!
Проблема оказалась более сложной, чем ожидалось, потому что:
Get-PnPProperty
не обрабатывает большие файлы (возможно, более 2 ГБ, но, возможно, даже всего 250 МБ). Но это также относится и к другим командам, таким как Get-PnPFileVersion
.Get-PnPContext
правильный, но его пришлось применить к целой библиотеке документов, а такие команды, как Get-PnPList
или Get-PnPListItem
, не извлекали все файлы (опять же, вероятно, потому, что они были слишком тяжелыми или было слишком много версий данного файла).Итак, хитрость заключалась в том, чтобы использовать Get-PnPFileInFolder
рекурсивно и, самое главное, не загружать свойства версии (или любые другие свойства) до тех пор, пока файл не будет обработан.
Таким образом мы получаем то, что хотим: удаляются все версии всех файлов в библиотеке SharePoint, даже для больших файлов или файлов с множеством версий. Запуск скрипта занимает немного времени, так как будут проверены все файлы (кроме тех, что находятся в системных папках), но он работает как шарм (проверено на нескольких библиотеках).
Небольшой бонус: в конце выполнения скрипт генерирует csv-файл, в котором суммируются все выполненные операции.
Измените параметры $siteUrl
, $libraryName
, $csvFilePath
в соответствии с вашим окружением и вуаля!
Со своей стороны, мне удалось восстановить более 550 ГБ дискового пространства, доступного в SharePoint, не тратя денег на программное решение;)
Да, и последний момент: если вы не хотите делать это снова, не забудьте отключить контроль версий (если вы, конечно, им не пользуетесь). Скрипты Дневник SharePoint, особенно сценарий 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