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:

Advertisement

8 thoughts on “Bulk Creation of Pages using PowerShell

    • Ryan Dennis

      Hey Chris,
      I did a simple test using the encoded

      &lt;

      and

      &gt;

      tags instead of < and > and it did allow me to include HTML in the PageContent node. Without encoding it, it did not work though. Hope this helps!

      Ryan

  1. Ben Schlaepfer

    Hi Ryan
    This is awesome, I am going to use this to build out my local site.
    My question is how do end users navigate around so many pages in a single library?
    I am looking at managed metadata and CQWP to address this issue but I’d be really interested in knowing what you may have learned aroud this topic.
    Many thanks,
    Ben

  2. Ryan Dennis

    Hey Ben,

    Thanks for the comments, very much appreciated!

    As for navigation, that’s a hard question to answer without seeing the information architecture – typically the navigation elements of the site are designed in a manner which makes navigating through the pages smooth from an end-user standpoint. Also, a lot of times when I’m using PowerShell to bulk-create lots of pages, I’m not doing more than a few per site and i’ll have several sites which build out the hierarchy. It really depends on the project I suppose. You could always use the ootb table of contents web part to build sort of a site map.

    Regards,
    Ryan

  3. skeddy (@skeddy)

    Hi Ryan,

    Could you describe how I would run this via powershell? Do I simply copy & paste the script, run it, and then call it as required?

    Very new to powershell, and this looks like it could save me a lot of publishing time.

    Cheers!

    Rob

    • Ryan Dennis

      Rob,
      Thanks for the comment! As for your question, the simplest way to run this would be to copy/paste the script into a PS window. It should simply return to the next line, but at that point you would’ve loaded the function/cmdlet into memory. From there, you can actually run it just like a native cmdlet. For example, if you start to type the name (New-SPPage) and press tab, it should tab-complete the name of the function. From there you can provide the parameters to give it values for Site Url, Page Title, Page Url, etc. – and when you run it – assuming you have adequate permissions, etc. you should have a new SharePoint Publishing Page.

      Hope this helps!
      Ryan

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s