SharePoint | Удалить историю версий с помощью PnP PowerShell

Я пытаюсь выполнить приведенный ниже сценарий из Дневника 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 можно настраивать и управлять сетевыми настройками и брандмауэром.


2
1 036
1

Ответ:

Решено

Я отвечаю на свой вопрос, потому что наконец нашел решение!

Проблема оказалась более сложной, чем ожидалось, потому что:

  1. Get-PnPProperty не обрабатывает большие файлы (возможно, более 2 ГБ, но, возможно, даже всего 250 МБ). Но это также относится и к другим командам, таким как Get-PnPFileVersion.
  2. Подход 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