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:
- SiteUrl – This is simply the site to create the pages in.
- PageTitle – If creating a single page
- PageUrl – If creating a single page
- PageContent – If creating a single page
- PageLayout – If creating a single page
- Checkin – Switch parameter, checks in the page
- Publish – Switch parameter, publishes the page
- CreateFromXml – Switch parameter, tells the function to create using the XML portion of the function
- 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> <strong>This should be bold text!<strong> </PageContent> <PageLayout>Article Page</PageLayout> </Page> </Pages>
Note | The second page has encoded HTML using the strong tag for the following result:
Can you include HTML in the PageContent XML node?
Hey Chris,
I did a simple test using the encoded
and
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
Updated the post to show encoded HTML in the PageContent XML node!
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
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
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
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