Forum Discussion

Amrah_Chughtai's avatar
Amrah_Chughtai
Copper Contributor
May 31, 2021

Total Size of Preservation Hold Libraries

Hello All,

 

I am wondering if someone can help with a PowerShell script to retrieve the size of Preservation hold libraries in all the SharePoint Sites and OneDrive.  I need to calculate the total space being used by items in Preservation Hold Libraries in our tenant.   Thanks so much for the help in advance.

7 Replies

  • ANieto's avatar
    ANieto
    Copper Contributor

    Hi guys,

    I work as a M365 engineer and I have that script that can help to you:

     

    # Requiere: PnP.PowerShell
    Import-Module PnP.PowerShell
    function Generate-VersionHistoryReport {
        param(
            [Parameter(Mandatory = $true)]
            [string]$SiteURL,
            [Parameter(Mandatory = $true)]
            [string]$ReportOutput
        )
        try {
            Write-Host "Conectando a: $SiteURL" -ForegroundColor Cyan
            Connect-PnPOnline -Url $SiteURL -UseWebLogin
            Write-Host "Procesando Site: $SiteURL" -ForegroundColor Yellow
            $AllRows = @()
            # Hidden library: Preservation Hold Library
            $List = Get-PnPList | Where-Object { $_.Title -eq "Preservation Hold Library" }
            if ($null -eq $List) {
                Write-Host "`tNo se encontrĂ³ Preservation Hold Library en este sitio" -ForegroundColor DarkYellow
            }
            else {
                Write-Host "`tProcesando biblioteca oculta: $($List.Title)" -ForegroundColor Green
                $ListItems = Get-PnPListItem -List $List.Id -PageSize 2000 -Fields "FileRef","FileLeafRef","FSObjType"
                foreach ($Item in $ListItems) {
                    if ($Item["FSObjType"] -ne 0) {
                        continue
                    }
                    try {
                        $File = Get-PnPProperty -ClientObject $Item -Property File
                        $Versions = Get-PnPProperty -ClientObject $File -Property Versions
                        if ($null -ne $Versions -and $Versions.Count -ge 1) {
                            $VersionSize = 0
                            foreach ($Version in $Versions) {
                                $VersionSize += [int64]$Version.Size
                            }
                            $AllRows += [PSCustomObject]@{
                                Site             = $SiteURL
                                Library          = $List.Title
                                'File Name'      = $File.Name
                                'Version Count'  = $Versions.Count
                                'Version Size-KB'= [math]::Round(($VersionSize / 1024), 2)
                                URL              = $SiteURL.TrimEnd('/') + $File.ServerRelativeUrl
                            }
                        }
                    }
                    catch {
                        Write-Host "`t`tError procesando archivo: $($Item['FileRef'])" -ForegroundColor Red
                        Write-Host "`t`t$($_.Exception.Message)" -ForegroundColor Red
                    }
                }
            }
            if ($AllRows.Count -gt 0) {
                $AllRows | Export-Csv -Path $ReportOutput -Append -NoTypeInformation -Encoding UTF8
            }
            # Subsitios
            $SubWebs = Get-PnPSubWeb -Recurse
            foreach ($SubWeb in $SubWebs) {
                Generate-VersionHistoryReport -SiteURL $SubWeb.Url -ReportOutput $ReportOutput
            }
        }
        catch {
            Write-Host "Error generando Version History Report en $SiteURL" -ForegroundColor Red
            Write-Host $_.Exception.Message -ForegroundColor Red
        }
    }
    # ParĂ¡metros
    $SiteURL      = "https://YOURTENANT.sharepoint.com/sites/YOURSITE"
    $ReportOutput = "D:\VersionHistoryRpt-preservationhold.csv"
    if (Test-Path $ReportOutput) {
        Remove-Item $ReportOutput -Force
    }
    Generate-VersionHistoryReport -SiteURL $SiteURL -ReportOutput $ReportOutput

     

    Notice in the connect-pnp..... -UseWebLogin  it wont work if you have PnP module updated.

    You should change by -Interactive and use an AppRegistration for login with PS

  • Technut's avatar
    Technut
    Copper Contributor

    Amrah_Chughtai This may be a bit late but here's something I wrote that should point you in the correct direction.

     

    The below PowerShell script requires modules for SharePoint Online Powershell and SharePoint PnP to be available on the machine. 

     

    Known issues:

    • The script does not process sub-sites, this can probably be easily fixed.
    • The "Measure-PNPList" cmdlet fails if the number of items in the preservation hold library exceeds the list view limit. The limit can be changed on the target sites, not sure if it can be done using PowerShell.

    Hope this helps and perhaps someone else will improve and share a new version of the script đŸ™‚

     

    $Out = @()
    
    $sites = Get-SPOSite -Limit ALL
    $Sites = $Sites | Sort-Object StorageUsageCurrent -Descending
    
    foreach ($Site in $Sites){
    
    Connect-PnPOnline -Url $site.Url -Interactive
    
    $SiteSize = $Site.StorageUsageCurrent
    $PHLib = Get-PnPList -Identity PreservationHoldLibrary
    
    if($PHLib){
    $PHSize = ($PHLib | Measure-PnPList).TotalFileSize
    $PHSize = $PHSize / 1024 / 1024
    }
    else {continue}
    
    if(!$PHSize){continue}
    
    $item = New-Object PSObject
    $item | Add-Member -type NoteProperty -Name 'Url' -Value $site.Url
    $item | Add-Member -type NoteProperty -Name 'SiteSizeMB' -Value $SiteSize
    $item | Add-Member -type NoteProperty -Name 'PreservationSizeMB' -Value ([math]::Round($PHSize))
    $item | Add-Member -type NoteProperty -Name 'PreservationPercentage' -Value ([math]::Round((($PHSize/$SiteSize)*100)))
    
    $item
    
    $out +=$item
    }

     

      • Barbarur's avatar
        Barbarur
        Brass Contributor
        You can use this sample script using PnP: https://github.com/Barbarur/NovaPointPowerShell/tree/main/Solutions
        The Preservation Hold Library is a list/library therefore is on the same page to get list and libraries.

        Alternative, you can use this Free and open-source app to get a report of the Preservation Hold Library: https://github.com/Barbarur/NovaPoint
    • DesShiels's avatar
      DesShiels
      Copper Contributor

      Technut 

       

      Thanks for this. I've tried it but am new to PnP. Installed  and registered Pnp and SPO modules in Powershell.

       

      I saved your script as a ps1 file.

      But when I run the script it appears to just finish with no output. I tried to run it line by line or section by section and all I can basically see/verify is

      "$sites = Get-SPOSite -Limit All" does indeed get the list of sites.

      That's about all I can see/verify.

       

      I do have another general question.... We have around 9,000 SharePoint sites in our organisation (I know!!! Shock!) This script won't prompt me to log into each and every site will it? I am assuming it'll just prompt me once and then run through each site hopefully....

       

      Any guidance would really be appreciated.

       

       

      • Anonymous_Tech's avatar
        Anonymous_Tech
        Copper Contributor

        DesShiels 

         

        a bit late to this but you only have to do it once on one random site before you go through the loop

        $connection = connect-pnponline -url $url -Interactive -ReturnConnection
         
        This stores the current o365 authentication session in $connection, you can then use that connection to authenticate to sharepoint when you reiterate each site
         
        connect-pnponline -url $url -interactive -ClientId $connection.clientid -Connection $connection