GitHub Icon Image
GitHub

Delete orphaned temporary site pages

Summary

Locate, take ownership of, and delete temporary orphaned pages from /SitePages library.

Warning

Please be aware this script contains a command that will remove or delete an artifact, ensure you test and understand the implications of running the script.

  • PnP PowerShell
  • CLI for Microsoft 365 using PowerShell

$SiteURL = "https://{tenant}.sharepoint.com/sites/{site}"
$ListName = "Site Pages"

Disconnect-PnPOnline
#use a login with Site Collection Administrator or Owner permissions
Connect-PnPOnline -Url $SiteURL -Interactive
$context = Get-PnPContext

$list = Get-PnPList -Identity $ListName

$context.Load($list)
Invoke-PnPQuery

$checkedOutFiles = $list.GetCheckedOutFiles()
$context.Load($checkedOutFiles)
Invoke-PnPQuery

$filesProcessed = @()

foreach($checkedOutFile in $CheckedOutFiles) {
    $fileServerRelativeUrl = [string]::Concat($list.ParentWebUrl, $checkedOutFile.ServerRelativePath.DecodedUrl.Replace($list.ParentWebUrl, ""))

    #8 random characters seem to be used for temporary page names.  Be careful - if a valid page was created with valid 8 character name, that page would be deleted as well.  TODO: figure out a way to avoid valid pages?
    $tempPageSampleUrlForThisSite = $list.RootFolder.ServerRelativeUrl + "/zz5yfe8u.aspx"

    if ($fileServerRelativeUrl.Length -ne $tempPageSampleUrlForThisSite.Length) {
        Write-Host "Skipping $fileServerRelativeUrl" -ForegroundColor Green
    } else {
        $checkedOutFile.TakeOverCheckOut()
        Invoke-PnPQuery

        $file = $checkedOutFile.Context.Web.GetFileByServerRelativeUrl($fileServerRelativeUrl)

        $context.Load($file)
        Invoke-PnPQuery

        $filesProcessed += [PSCustomObject]@{
            ServerRelativeUrl = $fileServerRelativeUrl
            Exists = $file.Exists
            UIVersionLabel = $file.UIVersionLabel
        }

        $file.DeleteObject()
        $context.ExecuteQuery()
        Write-host "." -NoNewline
    }
}


$nowString = [System.DateTime]::Now.ToString("yyyyMMdd_hhmm")
$path = "$env:USERPROFILE\Desktop\PS1\Get-FilesWithNoCheckin_$nowString.csv"
$filesProcessed | select ServerRelativeUrl, Exists, UIVersionLabel | Export-Csv $path -NoTypeInformation

Check out the PnP PowerShell to learn more at: https://aka.ms/pnp/powershell

The way you login into PnP PowerShell has changed please read PnP Management Shell EntraID app is deleted : what should I do ?


$SiteURL = "https://{tenant}.sharepoint.com/sites/{site}"
$listName = "Site Pages"

$m365Status = m365 status
if ($m365Status -match "Logged Out") {
  Write-Host "Logging in the User!"
  m365 login --authType browser
}

$filesProcessed = @()

$pages = m365 spo page list -u $SiteURL | ForEach-Object { $_.replace("Id", "_Id") } | ConvertFrom-Json
$list =  m365 spo list get -u $SiteURL -t $listName | ConvertFrom-Json
$checkedOutPages = $pages | ? CheckOutType -eq 0

foreach ($page in $checkedOutPages){
 $fileServerRelativeUrl = [string]::Concat($list.ParentWebUrl, $page.ServerRelativePath.DecodedUrl.Replace($list.ParentWebUrl, ""))

    #8 random characters seem to be used for temporary page names.  Be careful - if a valid page was created with valid 8 character name, that page would be deleted as well.  TODO: figure out a way to avoid valid pages?
    $tempPageSampleUrlForThisSite = $list.RootFolder.ServerRelativeUrl  + "/zz5yfe8u.aspx"

    if ($fileServerRelativeUrl.Length -ne $tempPageSampleUrlForThisSite.Length) {
        Write-Host "Skipping $fileServerRelativeUrl" -ForegroundColor Green
    } else {
        if(!$page.IsPageCheckedOutToCurrentUser){
        #take over check out
            m365 spo file checkin  --webUrl $SiteUrl --fileUrl $page.ServerRelativeUrl
            m365 spo file checkout  --webUrl $SiteUrl --fileUrl $page.ServerRelativeUrl
       }

 $filesProcessed += [PSCustomObject]@{
            ServerRelativeUrl = $page.ServerRelativeUrl
            Exists = $page.Exists
            UIVersionLabel = $page.UIVersionLabel
        }
  m365 spo page remove -u $SiteURL -n $page.Name --confirm
 }
}

$nowString = [System.DateTime]::Now.ToString("yyyyMMdd_hhmm")
$path = "$env:USERPROFILE\Desktop\PS1\Get-FilesWithNoCheckin_$nowString.csv"
$filesProcessed | select ServerRelativeUrl, Exists, UIVersionLabel | Export-Csv $path -NoTypeInformation

## Disconnect the context  
m365 logout  

Check out the CLI for Microsoft 365 to learn more at: https://aka.ms/cli-m365

Important changes coming to the way you login into CLI for Microsoft 365 (effective 9th September 2024) see Changes in PnP Management Shell registration in Microsoft 365

Contributors

Author(s)
Brian P. McCullough
Reshmee Auckloo

Disclaimer

THESE SAMPLES ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

Back to top Script Samples
Generated by DocFX with Material UI