Fix Publishing Pages Page Layout URL error – Value does not fall within the expected range

While accessing publishing pages, you may encounter error –  “Value does
not fall within the expected range” . It happens due to one of the following reasons:
  • If the publishing layout URL of a publishing page contains an incorrect top level site URL.
  • If there is a problem with the Page Layout, or if the Page Layout is corrupted.
  • If a content database was moved or a content deployment job was run.
 
If you encounter this issue due to reason – 1 i.e. “If the publishing layout URL of a publishing page contains an incorrect top level site URL.”, you can fix it by executing following script.
 
It will fetch URL from Page Layout and verify if it is same as top level site URL. If not, it will change it to top level site URL and approve the page.
 
function AutoApprovePage($page)
{
    if($page.ListItem.ListItems.List.EnableModeration)
    {
        #Check to ensure page requires approval, and if so, approve it
        if ($page.ListItem[“Approval Status”] -eq 0)
        {
             write-host ” | Already approved:”, $page.Title -nonewline
        }
        else
        {
            $page.ListItem.File.Approve(“Page approved automatically by PowerShell script”)
             write-host ” | Approving:”, $page.Title -nonewline
        }
    }
    else
    {
         write-host ” | No approval required for: “, $page.Title
    }
}
 
CLEAR
$site = Get-SPSite -Identity “http://br203:50000”
$pubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
Write-host “Processing SPWeb: “$pubWeb.Url
Write-host “Title: “$pubWeb.Title
       
$pagesList = $pubWeb.PagesList
$pageCount = 0
$badUrlCount = 0
$fixUrls = $true
foreach($page in $pagesList.Items)
{
    $curPubPage = [Microsoft.SharePoint.Publishing.PublishingPage]::GetPublishingPage($page)
    $pageLayout = $curPubPage.ListItem.File.Properties[“PublishingPageLayout”]
    $url = $pageLayout.SubString(0, $pageLayout.IndexOf(‘,’))
 
    $pageCount += 1
    if(!$url.StartsWith($site.RootWeb.Url,[System.StringComparison]::OrdinalIgnoreCase))
    {
        Write-Host ” |-Page:”$page.Title
        Write-Host ”   |-Layout:”$url -nonewline
        if($fixUrls)
        {
            #Construct the path to page. First, get the last index of / to getthe page name
            $pos = $url.LastIndexOf(‘/’)
            if($pos -ne -1)
            {
                $pubSPFile = $curPubPage.ListItem.File
                $rootWebUrl = $site.RootWeb.Url
                $pageName = $url.SubString($pos + 1)
                $newPageLayout = $rootWebUrl + “/_catalogs/masterpage/” + $pageName
                $pageLayoutFile = $site.RootWeb.GetFile($newPageLayout)
                if($pageLayoutFile.Exists)
                {
                    $checkedOutToUser =  $pubSPFile.CheckedOutByUser
                    if(($pubSPFile.CheckOutStatus -ne “None”) -and $undoCheckOut)
                    {
                        Write-host ”   |-File is Checked Out to: “$checkedOutToUser.Name”, but will be overridden” -foregroundcolor blue -nonewline
                        $pubSPFile.UndoCheckOut()
                    }
                    if($pubSPFile.CheckOutStatus -eq “None”)
                    {
                        $pubSPFile.CheckOut()
                        # Save the page layout as “url, pagename” (with a single space after url, this is important)
                        $propVal = $newPageLayout + “, ” + $pageName
                        $pubSPFile.Properties[“PublishingPageLayout”] = $propVal
                        $pubSPFile.Update()
                        $pubSPFile.CheckIn(“Fixed page layout url via auto-script.”,[Microsoft.SharePoint.SPCheckinType]::MajorCheckIn);
                        AutoApprovePage($curPubPage)
                        $fixedUrlCount += 1
 
                        Write-Host ”   |-SetUrl:”$newPageLayout -nonewline
                        Write-Host ” (Fixed)” -foregroundcolor Green -nonewline
                    }
                    else
                    {
                        Write-host ”   |-Not fixed. File is Checked Out to: “$checkedOutToUser.Name $checkedOutToUser.Email -foregroundcolor blue -nonewline
                    }
                }
                else
                {
                    Write-Host ”   |-Not fixed. The page layout $pageName does not exist in the root web master page gallery.” -foregroundcolor blue -nonewline
                }
            }
        }
    }
}
 

Recover deleted site collection using powershell

  • Unfortunately, there is no user interface for restoring deleted site collections. Managing deleted site collections requires using PowerShell. SharePoint 2010 Service Pack 1 introduces 3 new PowerShell CmdLets for managing the Recycle Bin for site collections.

    • Get-SPDeletedSite
    • Restore-SPDeletedSite
    • Remove-SPDeletedSite

    The easiest way to get a list of all the deleted site collections is to just call Get-SPDeleteSite without any parameters. In the following example, for brevity, I have formatted the output as a table and filtered the columns displayed. In the second sample, I have added a wildcard filter to the command that can be used to easily filter sites based on relative paths.

    1178_5Once you have identified the site you want to restore, you call the Restore-SPDeletedSite. To restore one or more sites, it is easiest to just pipe the results from Get-SPDeletedSite. By default, the command will ask you to confirm the restore. To eliminate the confirmation, just add “Confirm:$true” to the end of the command.

    1178_6

    Ref: http://mssharepointtips.com/tip.asp?id=1178&page=3

     

Stringbuilder object returning result while using Append function

Problem

For appending content to stringbuilder object we use Append() as

$sb = New-Object -TypeName “System.Text.StringBuilder”;
 $sb.Append(“This is a demo”);
expected the result is
This is a demo
However the result is
                  Capacity                MaxCapacity                    Length
                  ——–                ———–                    ——
                        16                 2147483647                         11
This is a demo
Reason
Several of the methods on StringBuilder like Append IIRC, return the StringBuilder so you can call more StringBuilder methods. However the way PowerShell works is that it outputs all results (return values in the case of .NET method calls).
Solution
In this case, cast the result to [void] to ignore the return value e.g.:
[void]$sb.Append(“This is a demo”)

InvalidData Error

I created a new script containing the line below and clicked Debug.

$spweb = Get-SpWeb http://myweb
Boom…  I was met with this in the Console:
Get-SPWeb : Microsoft SharePoint is not supported with version 4.0.30319.239 of the Microsoft .Net Runtime.
At C:\Users\MyUser\Documents\slk.ps1:2 char:19
+ $spweb = Get-SpWeb <<<<  http://myweb
+ CategoryInfo          : InvalidData: (Microsoft.Share….SPCmdletGetWeb:SPCmdletGetWeb) [Get-SPWeb], PlatformNotSupportedException
+ FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletGetWeb

Hmm, I guess I either need to 1) allow the SharePoint Cmdlets to run under .NET 4, 2) find an older version of PowerGUI, or 3) run PowerGUI under .NET 3.5. I chose option 3.

After some digging, I found the already-existant ScriptEditor.exe.config file inC:\Program Files (x86)\PowerGUI.

I opened it up with NotePad++ and noticed the following line:
<supportedRuntime version=”v4.0″ sku=”.NETFramework,Version=v4.0″ />
And promptly commented it out and saved the file.
<!– <supportedRuntime version=”v4.0″ sku=”.NETFramework,Version=v4.0″ /> –>

Next, I started up PowerGUI and was able to run the same SharePoint cmdlet.