Generic Error on Listedit.aspx page after SP1 and Aug 2011 CU


Wow did this issue get under my skin.

At my current client, where their SharePoint 2010 Enterprise Intranet is about as business critical as a SP environment can be – I performed the SP1 and Aug 2011 CU updates. The updates themselves went about as smooth as could be expected, until we noticed that lists and libraries would give the generic error w/ correlation ID when navigating to the List Settings page (/_layouts/listedit.aspx).

This seemed like not too big of a deal on the first site collection we noticed it on – then we realized it was farm-wide.

After doing a lot of log-reading, re-running PSCONFIG.exe to ensure that everything completed from an upgrade perspective; we were in the dark…

This morning I noticed something while browsing through the layouts folder – listedit.aspx (and some other files) was modified on 6/8/2011 at 11:46 AM. Most of the other aspx files were showing a modified date much further in the past.

On a whim I copied listedit.aspx from a known-good farm into my broken farm and VOILA – lists and libraries work again.

This might not help anybody, because I couldn’t find anyone else having this exact issue – but I didn’t want to lose track of the “fix.”

Get a SharePoint Publishing Content Inventory using PowerShell


There may be a time when you want to get an inventory of all publishing content (Sites, Documents, Pages, etc.) for an entire site collection. I needed to do exactly that, so I wrote a handy little PowerShell function that walks through a Publishing Site Collection – counting the webs, pages, images and documents.

Here is the function!

function Get-SPPublishingSiteInventory {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)][string]$SiteUrl
)
    Start-SPAssignment -Global
    $Site = New-Object Microsoft.SharePoint.SPSite($SiteUrl)
	$PubSite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($Site)
	$PubPageCount = 0
	$ImageCount = 0
	$DocCount = 0
	foreach ($Web in $Site.AllWebs) {
        $PubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($Web)
		$Pages = $PubWeb.GetPublishingPages($PubWeb)
		$PageCount = $Pages.Count
		$PubPageCount = $PubPageCount + $PageCount
		$Images = $PubWeb.ImagesLibrary.ItemCount
		$ImageCount = $ImageCount + $Images
		$Documents = $PubWeb.DocumentsLibrary.ItemCount
		$DocCount = $DocCount + $Documents
		$Web.Dispose()		
    }
    $Site.Dispose()
    Write-Host "Number of Sites: "     $site.allwebs.count
    Write-Host "Number of Pages: "     $PubPageCount
	Write-Host "Number of Images: "    $ImageCount
	Write-Host "Number of Documents: " $DocCount
    Stop-SPAssignment -Global
}

Bulk Creation of Pages using PowerShell


I’m working on an internet-facing project for my current client, and one of the largest tasks will be migrating approximately 1,500 pages from static HTML to SharePoint 2010 (.aspx) pages. While I have a migration staff which will do the majority of the heavy lifting, I still wanted to try and find a way to automate some of the work.

Obviously I reached out to the tool I love, PowerShell.

At first I did some searching, and I found a post by Brendan Newell that had a script for creating pages from XML.

This was a great start and contributed most of the code to my function. However, in Brendan’s script he mentions that he had no need to use a different page layout – or define any additional metadata. However, I wanted to do those things – so I adapted Brendan’s outstanding example into one I can use to pre-create pages that my migration staff can then populate with the real data.

Another thing I wanted was the ability to create a single page – so I adapted the function to solve two problems: Creating a single page, and creating multiple pages from XML input.

Using several parameters I’m able to accomplish these things pretty efficiently and effectively – I have 9 parameters total, they are:

  1. SiteUrl – This is simply the site to create the pages in.
  2. PageTitle – If creating a single page
  3. PageUrl – If creating a single page
  4. PageContent – If creating a single page
  5. PageLayout – If creating a single page
  6. Checkin – Switch parameter, checks in the page
  7. Publish – Switch parameter, publishes the page
  8. CreateFromXml – Switch parameter, tells the function to create using the XML portion of the function
  9. XmlInput – Path to the xml file containing the page information

Here is the (very large) function:

function New-SPPage{
<#
.Synopsis
	The New-SPPage function creates one or more Publishing Pages in a SharePoint Publishing Site.
.Description
	The New-SPPage function uses the PublishingSite and PublishingWeb objects to call the Add() method for provisioning of SharePoint Publishing Pages.
.Example
	C:\PS>New-SPPage -SiteUrl http://intranet `
	-PageTitle "My Page" `
	-PageUrl MyPage.aspx `
	-PageContent "This is my text." `
	-PageLayout "Article Page" `
	-CheckIn -Publish	
	This example creates a single page in the http://intranet site.
.Example
	C:\PS>New-SPPage -CreateFromXml -XmlInput "C:\Pages.xml" -Checkin -Publish
	This example creates pages based on an xml file with the following schema:
<?xml version="1.0" encoding="utf-8"?>
<Pages>
  <Page>
    	<PageTitle>Page 1</PageTitle>
        <PageUrl>Page1.aspx</PageUrl>
        <PageContent>
        This is some text.
        This is another line of text.
        </PageContent>
        <PageLayout>Article Page</PageLayout>
  </Page> 
</Pages>
.Notes
	Name: New-SPPage
	Author: Ryan Dennis
	Last Edit: 7/25/2011
	Keywords: New-SPPage
.Link
	http://www.sharepointryan.com
 	http://twitter.com/SharePointRyan
.Inputs
	None
.Outputs
	None
#Requires -Version 2.0
#>
[CmdletBinding()]
	Param(
    [Parameter(Mandatory=$true)]
	[string]$SiteUrl,
    [Parameter(Mandatory=$false)]
	[string]$PageTitle,
    [Parameter(Mandatory=$false)]
	[string]$PageUrl,
	[Parameter(Mandatory=$false)]
	[string]$PageContent,
	[Parameter(Mandatory=$false)]
	[string]$PageLayout,
	[Parameter(Mandatory=$false)]
	[switch]$CheckIn,
	[Parameter(Mandatory=$false)]
	[switch]$Publish,
	[Parameter(Mandatory=$false)]
	[switch]$CreateFromXml,
	[Parameter(Mandatory=$false)]
	[string]$XmlInput
    )
#Region CreateFromXml
if ($CreateFromXml) {
# Read in list of pages from XML
[xml]$pagesXML = Get-Content $($XmlInput)
if ($pagesXML -eq $null) { return }
# Get publishing web
$site = New-Object Microsoft.SharePoint.SPSite($SiteUrl)
$psite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($site)
$web = $site.OpenWeb()
$pWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
# Loop through each page node to extract filename
$pagesXML.Pages.Page | ForEach-Object {
    $PageTitle = [string]$_.PageTitle
	$PageUrl = [string]$_.PageUrl
	$PageLayout = [string]$_.PageLayout
	$PageContent = [string]$_.PageContent
	$ctype = $psite.ContentTypes[$PageLayout]
	$layouts = $psite.GetPageLayouts($ctype, $true)
	$layout = $layouts[0]
    Write-Host "Creating $($PageTitle)"

    # Create blank page
    $pages = $pWeb.GetPublishingPages($pWeb)
	$page = $pages.Add($PageUrl, $Layout)
	#$newPage = $pWeb.AddPublishingPage($PageUrl,$PageLayout)
    $page.Update()

    # Update the filename to the one specified in the XML
    $item = $page.ListItem
	$item["Title"] = $PageTitle;
	$item["Page Content"] = $PageContent;
	$item.Update()
    # Check-in and publish page
    if ($CheckIn){$item.File.CheckIn("")}
    if ($Publish){$item.File.Publish("");}
} #End ForEach Loop
# Dispose of the web
$web.Dispose()
} #End CreateFromXml
#EndRegion CreateFromXml
#Region CreateSinglePage
else {
Start-SPAssignment -Global
$site = New-Object Microsoft.SharePoint.SPSite($SiteUrl)
$psite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($site)
$ctype = $psite.ContentTypes[$PageLayout]
$layouts = $psite.GetPageLayouts($ctype, $true)
$layout = $layouts[0]
$web = $site.OpenWeb(); #Site.Rootweb
$pweb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
$pages = $pweb.GetPublishingPages($pweb)
$page = $pages.Add($PageUrl, $layout)
$item = $page.ListItem
Write-Host "Creating $($PageTitle)"
$item["Title"] = $PageTitle;
$item["Page Content"] = $PageContent;
$item.Update() 
if ($CheckIn){$item.File.CheckIn("")}
if ($Publish){$item.File.Publish("")}
$site.Dispose()
$web.Dispose()
Stop-SPAssignment -Global
} #End single page from else
} #End function

Here is an example XML file:

<?xml version="1.0" encoding="utf-8"?>
<Pages>
  <Page>
    <PageTitle>Page 1</PageTitle>
	<PageUrl>PageOne.aspx</PageUrl>
	<PageContent>
	This is some text.
	This is another line of text.
	</PageContent>
	<PageLayout>Article Page</PageLayout>
  </Page>
  <Page>
    <PageTitle>Page 2</PageTitle>
	<PageUrl>PageTwo.aspx</PageUrl>
	<PageContent>
	&lt;strong&gt;This should be bold text!&lt;strong&gt;
	</PageContent>
	<PageLayout>Article Page</PageLayout>
  </Page>
</Pages>

Note | The second page has encoded HTML using the strong tag for the following result:

Use PowerShell to Create SharePoint Lists and Libraries


This post goes hand in hand with my recent post on retrieving available List and Library templates – although in this PowerShell Function I’m calling the Add method of an SPWeb Object to create lists and libraries.

Most of the ‘code’ in this function comes from the 5 parameters I’m using, but the actual function boils down to the following lines:

Start-SPAssignment -Global
$SPWeb = Get-SPWeb -Identity $Web
$listTemplate = $SPWeb.ListTemplates[$Template]
$SPWeb.Lists.Add($ListUrl,$Description,$listTemplate)
$list = $SPWeb.Lists[$ListUrl]
$list.Title = $ListTitle
$list.Update()
$SPWeb.Dispose()
Stop-SPAssignment -Global

Essentially I’m just grabbing an SPWeb object from the $Web parameter, I’m then grabbing a ListTemplate from the $ListTemplate parameter, I then call the Add() method to provision the list or library. Once that’s done, I change the Title to the value given in the $ListTitle parameter, hopefully leaving the URL a nice friendly name with no spaces. I then use the Update() and Dispose() methods to update and clean-up, and finally I close out the SPAssignment.

Here’s the complete function:

function New-SPList {
<#
.Synopsis
	Use New-SPList to create a new SharePoint List or Library.
.Description
	This advanced PowerShell function uses the Add method of a SPWeb object to create new lists and libraries in a SharePoint Web
	specified in the -Web parameter.
.Example
	C:\PS>New-SPList -Web http://intranet -ListTitle "My Documents" -ListUrl "MyDocuments" -Description "This is my library" -Template "Document Library"
	This example creates a standard Document Library in the http://intranet site.
.Example
	C:\PS>New-SPList -Web http://intranet -ListTitle "My Announcements" -ListUrl "MyAnnouncements" -Description "These are company-wide announcements." -Template "Announcements"
	This example creates an Announcements list in the http://intranet site.
.Notes
	You must use the 'friendly' name for the type of list or library.  To retrieve the available Library Templates, use Get-SPListTemplates.
.Link
	http://www.iccblogs.com/blogs/rdennis
 		http://twitter.com/SharePointRyan
.Inputs
	None
.Outputs
	None
#>    
	[CmdletBinding()]
	Param(
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
	[string]$Web,
    [Parameter(Mandatory=$true)]
	[string]$ListTitle,
    [Parameter(Mandatory=$true)]
	[string]$ListUrl,
	[Parameter(Mandatory=$false)]
	[string]$Description,
	[Parameter(Mandatory=$true)]
	[string]$Template
    )
Start-SPAssignment -Global
$SPWeb = Get-SPWeb -Identity $Web
$listTemplate = $SPWeb.ListTemplates[$Template]
$SPWeb.Lists.Add($ListUrl,$Description,$listTemplate)
$list = $SPWeb.Lists[$ListUrl]
$list.Title = $ListTitle
$list.Update()
$SPWeb.Dispose()
Stop-SPAssignment -Global
}