From be5dd1bfb2e5f59b9bfc86b75e81d212d59fdc02 Mon Sep 17 00:00:00 2001
From: Josiah Opiyo <122151392+ojopiyo@users.noreply.github.com>
Date: Sat, 20 Dec 2025 12:02:05 +0000
Subject: [PATCH 1/2] Update README.md
The script has been refactored to align with modern SharePoint Online and PnP PowerShell best practices, with a focus on security, maintainability, performance, and operational reliability.
Authentication was modernized by removing hard-coded credentials and implementing interactive sign-in, reducing security risk and enabling MFA compliance. Script reliability and reusability were improved by eliminating global variables and enforcing clear data flow between functions. The overall structure was simplified through well-defined, single-responsibility functions, improving readability and ease of future enhancement.
Performance was optimized by introducing pagination and limiting SharePoint queries to required fields, ensuring scalability across large Site Pages libraries. Error handling was strengthened through consistent try/catch logic, improving troubleshooting and suitability for automation. Output handling was enhanced with automatic directory creation and timestamped exports to support repeatable execution and audit scenarios.
Collectively, these changes ensure the script meets modern security standards, is easier to maintain and extend, scales effectively, and produces reliable, audit-ready reports.
---
.../README.md | 179 +++++++++++++-----
1 file changed, 131 insertions(+), 48 deletions(-)
diff --git a/scripts/spo-export-all-site-pages-details/README.md b/scripts/spo-export-all-site-pages-details/README.md
index b74d56fed..04ffc1a1c 100644
--- a/scripts/spo-export-all-site-pages-details/README.md
+++ b/scripts/spo-export-all-site-pages-details/README.md
@@ -4,7 +4,23 @@
## Summary
-This sample will export the required site pages information to CSV.
+This PowerShell script uses the PnP PowerShell module to connect to a SharePoint Online site and extract metadata from the Site Pages library. It collects key information for each page—such as titles, URLs, authorship, creation and modification dates, layout type, and banner image details—and exports the results to a timestamped CSV file for reporting and analysis purposes.
+
+## Why It Matters / Real-World Scenarios
+
+Organizations often lack visibility into the volume, ownership, and status of modern SharePoint pages. This script enables administrators and site owners to:
+- Perform content audits prior to migrations, restructures, or clean-up initiatives
+- Identify outdated, unused, or orphaned pages
+- Support governance and compliance reviews by providing page ownership and modification history
+- Create an inventory of pages for site redesigns or information architecture planning
+
+## Benefits of the Reported Data
+
+- Improved Governance: Clear visibility into who created and last modified each page
+- Operational Insight: Understand page usage patterns and content lifecycle
+- Risk Reduction: Identify pages with missing ownership or stale content
+- Decision Support: Enables data-driven decisions for site cleanup, archiving, or redesign
+- Audit Readiness: Produces a structured, exportable record of SharePoint page metadata
## Implementation
@@ -12,77 +28,144 @@ This sample will export the required site pages information to CSV.
- Create a new file
- Write a script as below,
- First, we will connect to the site from which site we want to get Site Pages library details.
- - Then we will get Site Pages details and export it to CSV.
+- Then we will get Site Pages details and export it to CSV.
+
+
# [PnP PowerShell](#tab/pnpps)
```powershell
-$siteURL = "https://domain.sharepoint.com/"
-$username = "username@domain.onmicrosoft.com"
-$password = "********"
-$secureStringPwd = $password | ConvertTo-SecureString -AsPlainText -Force
-$creds = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $secureStringPwd
-$dateTime = "_{0:MM_dd_yy}_{0:HH_mm_ss}" -f (Get-Date)
-$basePath = "E:\Contribution\PnP-Scripts\Logs\"
-$csvPath = $basePath + "\SitePages" + $dateTime + ".csv"
-$global:sitePagesCollection = @()
-
-Function Login() {
- [cmdletbinding()]
- param([parameter(Mandatory = $true, ValueFromPipeline = $true)] $creds)
- Write-Host "Connecting to Site '$($siteURL)'" -f Yellow
- Connect-PnPOnline -Url $siteURL -Credential $creds
- Write-Host "Connection Successful" -f Green
+
+# ============================
+# Configuration
+# ============================
+$SiteUrl = "https://domain.sharepoint.com/"
+$BasePath = "E:\Contribution\PnP-Scripts\Logs"
+$DateTime = Get-Date -Format "MM_dd_yy_HH_mm_ss"
+$CsvPath = Join-Path $BasePath "SitePages_$DateTime.csv"
+
+# Ensure log directory exists
+if (-not (Test-Path $BasePath)) {
+ New-Item -ItemType Directory -Path $BasePath | Out-Null
+}
+
+# ============================
+# Connect to SharePoint
+# ============================
+function Connect-ToSharePoint {
+ param (
+ [Parameter(Mandatory)]
+ [string]$Url
+ )
+
+ try {
+ Write-Host "Connecting to $Url..." -ForegroundColor Yellow
+ Connect-PnPOnline -Url $Url -Interactive
+ Write-Host "Connected successfully!" -ForegroundColor Green
+ }
+ catch {
+ throw "Failed to connect to SharePoint: $($_.Exception.Message)"
+ }
}
-Function GetSitePagesDetails {
+# ============================
+# Get Site Pages Metadata
+# ============================
+function Get-SitePagesDetails {
try {
- Write-Host "Getting site pages information..." -ForegroundColor Yellow
- $sitePages = Get-PnPListItem -List "Site Pages"
- ForEach ($Page in $sitePages) {
- $sitePagesInfo = New-Object PSObject -Property ([Ordered] @{
- 'ID' = $Page.ID
- 'Title' = $Page.FieldValues.Title
- 'Description' = $Page.FieldValues.Description
- 'Page Layout Type' = $Page.FieldValues.PageLayoutType
- 'FileRef' = $Page.FieldValues.FileRef
- 'FileLeafRef' = $Page.FieldValues.FileLeafRef
- 'Created' = Get-Date -Date $Page.FieldValues.Created_x0020_Date -Format "dddd MM/dd/yyyy HH:mm"
- 'Modified' = Get-Date -Date $Page.FieldValues.Last_x0020_Modified -Format "dddd MM/dd/yyyy HH:mm"
- 'Modified By' = $Page.FieldValues.Modified_x0020_By
- 'Created By' = $Page.FieldValues.Created_x0020_By
- 'Author' = $Page.FieldValues.Author.Email
- 'Editor' = $Page.FieldValues.Editor.Email
- 'BannerImage Url' = $Page.FieldValues.BannerImageUrl.Url
- 'File_x0020_Type' = $Page.FieldValues.File_x0020_Type
- })
- $global:sitePagesCollection += $sitePagesInfo
+ Write-Host "Retrieving Site Pages..." -ForegroundColor Yellow
+
+ $pages = Get-PnPListItem `
+ -List "Site Pages" `
+ -PageSize 500 `
+ -Fields ID,Title,Description,PageLayoutType,FileRef,FileLeafRef,
+ Created_x0020_Date,Last_x0020_Modified,
+ Modified_x0020_By,Created_x0020_By,
+ Author,Editor,BannerImageUrl,File_x0020_Type
+
+ $results = foreach ($page in $pages) {
+ [PSCustomObject]@{
+ ID = $page.Id
+ Title = $page["Title"]
+ Description = $page["Description"]
+ PageLayoutType = $page["PageLayoutType"]
+ FileRef = $page["FileRef"]
+ FileName = $page["FileLeafRef"]
+ Created = $page["Created_x0020_Date"]
+ Modified = $page["Last_x0020_Modified"]
+ CreatedBy = $page["Author"]?.Email
+ ModifiedBy = $page["Editor"]?.Email
+ BannerImageUrl = $page["BannerImageUrl"]?.Url
+ FileType = $page["File_x0020_Type"]
+ }
}
+
+ return $results
}
catch {
- Write-Host "Error in getting site pages:" $_.Exception.Message -ForegroundColor Red
+ throw "Error retrieving Site Pages: $($_.Exception.Message)"
}
- Write-Host "Exporting to CSV..." -ForegroundColor Yellow
- $global:SitePagesCollection | Export-Csv $csvPath -NoTypeInformation -Append
- Write-Host "Exported to CSV successfully!" -ForegroundColor Green
+}
+
+# ============================
+# Export to CSV
+# ============================
+function Export-ToCsv {
+ param (
+ [Parameter(Mandatory)]
+ [object[]]$Data,
+ [Parameter(Mandatory)]
+ [string]$Path
+ )
+
+ try {
+ Write-Host "Exporting data to CSV..." -ForegroundColor Yellow
+ $Data | Export-Csv -Path $Path -NoTypeInformation
+ Write-Host "Export completed: $Path" -ForegroundColor Green
+ }
+ catch {
+ throw "CSV export failed: $($_.Exception.Message)"
+ }
}
-Function StartProcessing {
- Login($creds);
- GetSitePagesDetails
+# ============================
+# Main Execution
+# ============================
+try {
+ Connect-ToSharePoint -Url $SiteUrl
+ $SitePages = Get-SitePagesDetails
+ Export-ToCsv -Data $SitePages -Path $CsvPath
}
+catch {
+ Write-Host $_ -ForegroundColor Red
+}
+
-StartProcessing
```
[!INCLUDE [More about PnP PowerShell](../../docfx/includes/MORE-PNPPS.md)]
***
+## Output
+
+- **Format**: CSV
+- **Location**: Configurable output directory
+- **File Naming**: Timestamped (prevents overwriting previous reports)
+
+## Notes
+- Requires appropriate permissions to read the Site Pages library
+- Supports modern authentication (MFA-compatible)
+- Designed for single-site execution but easily extendable to multiple sites
## Contributors
| Author(s) |
|-----------|
-| Chandani Prajapati (https://github.com/chandaniprajapati) |
+| [Chandani Prajapati](https://github.com/chandaniprajapati) |
+| [Josiah Opiyo](https://github.com/ojopiyo) |
+
+*Built with a focus on automation, governance, least privilege, and clean Microsoft 365 tenants—helping M365 admins gain visibility and reduce operational risk.*
+
+
[!INCLUDE [DISCLAIMER](../../docfx/includes/DISCLAIMER.md)]
From 4cc000052cf59aa9162d4d00745296371c2bdb23 Mon Sep 17 00:00:00 2001
From: Paul Bullock
Date: Sat, 10 Jan 2026 15:46:32 +0000
Subject: [PATCH 2/2] Small tweaks to keep original as discussed
---
.../README.md | 65 ++++++++++++++++++-
.../assets/sample.json | 8 ++-
2 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/scripts/spo-export-all-site-pages-details/README.md b/scripts/spo-export-all-site-pages-details/README.md
index 04ffc1a1c..9d8090d0d 100644
--- a/scripts/spo-export-all-site-pages-details/README.md
+++ b/scripts/spo-export-all-site-pages-details/README.md
@@ -32,7 +32,7 @@ Organizations often lack visibility into the volume, ownership, and status of mo
-# [PnP PowerShell](#tab/pnpps)
+# [PnP PowerShell V2](#tab/pnpps2)
```powershell
# ============================
@@ -143,6 +143,69 @@ catch {
```
[!INCLUDE [More about PnP PowerShell](../../docfx/includes/MORE-PNPPS.md)]
+
+# [PnP PowerShell](#tab/pnpps)
+```powershell
+$siteURL = "https://domain.sharepoint.com/"
+$username = "username@domain.onmicrosoft.com"
+$password = "********"
+$secureStringPwd = $password | ConvertTo-SecureString -AsPlainText -Force
+$creds = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $secureStringPwd
+$dateTime = "_{0:MM_dd_yy}_{0:HH_mm_ss}" -f (Get-Date)
+$basePath = "E:\Contribution\PnP-Scripts\Logs\"
+$csvPath = $basePath + "\SitePages" + $dateTime + ".csv"
+$global:sitePagesCollection = @()
+
+Function Login() {
+ [cmdletbinding()]
+ param([parameter(Mandatory = $true, ValueFromPipeline = $true)] $creds)
+ Write-Host "Connecting to Site '$($siteURL)'" -f Yellow
+ Connect-PnPOnline -Url $siteURL -Credential $creds
+ Write-Host "Connection Successful" -f Green
+}
+
+Function GetSitePagesDetails {
+ try {
+ Write-Host "Getting site pages information..." -ForegroundColor Yellow
+ $sitePages = Get-PnPListItem -List "Site Pages"
+ ForEach ($Page in $sitePages) {
+ $sitePagesInfo = New-Object PSObject -Property ([Ordered] @{
+ 'ID' = $Page.ID
+ 'Title' = $Page.FieldValues.Title
+ 'Description' = $Page.FieldValues.Description
+ 'Page Layout Type' = $Page.FieldValues.PageLayoutType
+ 'FileRef' = $Page.FieldValues.FileRef
+ 'FileLeafRef' = $Page.FieldValues.FileLeafRef
+ 'Created' = Get-Date -Date $Page.FieldValues.Created_x0020_Date -Format "dddd MM/dd/yyyy HH:mm"
+ 'Modified' = Get-Date -Date $Page.FieldValues.Last_x0020_Modified -Format "dddd MM/dd/yyyy HH:mm"
+ 'Modified By' = $Page.FieldValues.Modified_x0020_By
+ 'Created By' = $Page.FieldValues.Created_x0020_By
+ 'Author' = $Page.FieldValues.Author.Email
+ 'Editor' = $Page.FieldValues.Editor.Email
+ 'BannerImage Url' = $Page.FieldValues.BannerImageUrl.Url
+ 'File_x0020_Type' = $Page.FieldValues.File_x0020_Type
+ })
+ $global:sitePagesCollection += $sitePagesInfo
+ }
+ }
+ catch {
+ Write-Host "Error in getting site pages:" $_.Exception.Message -ForegroundColor Red
+ }
+ Write-Host "Exporting to CSV..." -ForegroundColor Yellow
+ $global:SitePagesCollection | Export-Csv $csvPath -NoTypeInformation -Append
+ Write-Host "Exported to CSV successfully!" -ForegroundColor Green
+
+}
+
+Function StartProcessing {
+ Login($creds);
+ GetSitePagesDetails
+}
+
+StartProcessing
+```
+[!INCLUDE [More about PnP PowerShell](../../docfx/includes/MORE-PNPPS.md)]
+
***
## Output
diff --git a/scripts/spo-export-all-site-pages-details/assets/sample.json b/scripts/spo-export-all-site-pages-details/assets/sample.json
index 14d62e96b..d24dc27c3 100644
--- a/scripts/spo-export-all-site-pages-details/assets/sample.json
+++ b/scripts/spo-export-all-site-pages-details/assets/sample.json
@@ -9,7 +9,7 @@
"This script sample shows how to export all site pages details from Site Pages library."
],
"creationDateTime": "2022-10-17",
- "updateDateTime": "2022-10-17",
+ "updateDateTime": "2026-01-10",
"products": [
"SharePoint"
],
@@ -36,6 +36,12 @@
}
],
"authors": [
+ {
+ "gitHubAccount": "ojopiyo",
+ "company": "",
+ "pictureUrl": "https://github.com/ojopiyo.png",
+ "name": "Josiah Opiyo"
+ },
{
"gitHubAccount": "chandaniprajapati",
"pictureUrl": "https://avatars.githubusercontent.com/u/52065929?v=4",