Fix Publishing Pages which reference bad page layout within a site collection
Introduction
This script will scan all publishing pages in a given site collection and check if the pages in the pages library have a valid url for the page layout. The script runs in a “detect” mode by default and also accepts parameters which allow fixing
the page layout url for pages. If the page is checked out to someone else, you can force undo of the checkout (results in changes on that page being lost). When fixing the page layout url, it will also checkout and approve the pages post fixing if moderation
is enabled. It does not publish the pages.
Having a correct page layout is important when rendering pages in publishing site or when using features such as Variations or Content Deployment because these will fail if the referenced page layout is invalid or pointing to a location which is not valid
in the context of the site.
Scenarios
In a real world, this script will help fix issues wherein
a. Variations create hierarchies fail because the page layout is invalid.
b. Page rendering fails because the page layout is invalid.
Script
The default behavior is “detect” mode. This script has 3 run modes with 3 parameters. The first parameter is mandatory, which is the site collection url.
Parameters explained:
-siteUrl - Site collection url (Mandatory) for e.g http://site
-fixurls - Set to $true (default $false, not mandatory), it will attempt to fix up the link for you to OOB style.
-undoCheckOut - Overrides documents which are checked out to other users. Default ($false), to prevent data loss. When fixing urls, it will not override the checkout of documents unless this is parameter is $true.
To use this script, please do the following.
a. Login to SharePoint Server as a member of the administrators group.
b. Ensure that the account you are going to run this script with is a member of the site collection administrators group in that site.
c. Open SharePoint Management Console & switch to the folder where this script is located.
d. Run as follows:
Example 1: Run in detect only mode to see how many pages it reports as having bad page layouts:
Command: FixPublishingPages -siteUrl http://sitename
Screenshot:
Review Summary:
Examine the output to see if you have bad urls for page layouts.
Example 2: If there are bad urls, re-run the script with –fixurls $True which will fix all those broken Pages. This won’t fix the Checked Out Documents:
Command: \FixPublishingPages -siteUrl http://sitename -fixurls $true (detects broken page layouts and attempts to fix them. Checked out documents are marked as can't fix)
Screenshot:

Review Summary:
Example 3: Third option is with –undoCheckOut $True, which will forcefully undo check out of documents. It will cause any changes made by the user to be lost. So please use caution when using this mode. Once you run the Script with
this Switch enabled, you cannot revert the changes. The script will warn you as follows if you choose this option

Command: \FixPublishingPages -siteUrl http://sitename -fixurls $true -undoCheckOut $true (detects broken page layouts and attempts to fix them. Any checked out files are forcefully undone and fixed)
Screenshot:
Review Summary:
At the end of the run, the script also opens notepad with the results so that any long set of output can be reviewed conveniently.
Here are some code snippets for your references. To get the complete script sample, please click the download button at the beginning of this page.
PowerShell
Edit|Remove
powershell
function ProcessSite($site)
{
# Write-Host "Processing Site: "$site.Title
$websCollection = $site.AllWebs
$global:badUrlCount = 0
$global:pagesCount = 0
$global:fixedUrlCount = 0
# Cycle through all webs and process each web
foreach($web in $websCollection)
{
# Process only PublishingWeb types
if([Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($web))
{
ProcessPublishingWeb($web)
}
$web.Dispose()
}
$site.Dispose()
# Write out some statistics
Write-host
Write-host "Total number of webs processed : "$websCollection.Count
Write-host "Total number of pages processed : "$pagesCount
Write-host "Total number of bad urls : "$badUrlCount
Write-host "Total number of urls fixed : "$fixedUrlCount
Write-host
}
function ProcessSite($site)
{
# Write-Host "Processing Site: "$site.Title
$websCollection = $site.AllWebs
$global:badUrlCount = 0
$global:pagesCount = 0
$global:fixedUrlCount = 0
# Cycle through all webs and process each web
foreach($web in $websCollection)
{
# Process only PublishingWeb types
if([Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($web))
{
ProcessPublishingWeb($web)
}
$web.Dispose()
}
$site.Dispose()
# Write out some statistics
Write-host
Write-host "Total number of webs processed : "$websCollection.Count
Write-host "Total number of pages processed : "$pagesCount
Write-host "Total number of bad urls : "$badUrlCount
Write-host "Total number of urls fixed : "$fixedUrlCount
Write-host
}