I have included below a Powershell script I have written to provision a site structure, along with templates, permissions, navigation, themes and master pages all based on an XML input document.
When working in a setup with multiple environments such as development, UAT, staging, production etc it is very useful to be able to provision such a structure in a repeatable manner by the use of such scripts, with the ability to change settings simply by editing an xml document
I have noticed a number of Powershell scripts out there which set the theme with the ApplyTheme method, but this is being replaced by the ThmxTheme.SetThemeUrlForWeb method in 2010. Although I saw exampoles for using this within .NET code, I did not see an example of using it with Powershell, hence why I added it here
You would call the script with a command like
CreateSiteStructure “http://<myserver>” “C:\<myFolderPath>\SiteStructure.XML”
Anyway, here is the script. Hope it is useful to someone on day;
function SetWebTheme($web, $themeName)
{
$themeUrl = “/_catalogs/theme/” + $themeName + “.thmx”
[Microsoft.SharePoint.Utilities.ThmxTheme]::SetThemeUrlForWeb($web, $themeUrl)
$web.Update()
}
function SetWebMasterPages($web, $masterPage, $customMasterPage)
{
if ($customMasterPage.Length -gt 0)
{
$customMasterUrl = “/_catalogs/masterpage/” + $customMasterPage
$web.CustomMasterUrl = $customMasterUrl
}
if ($masterPage.Length -gt 0)
{
$masterUrl = “/_catalogs/masterpage/” + $masterPage
$web.MasterUrl = $masterUrl
}
$web.Update()
}
function CreateSitesFromXML($XMLNode, $parentWebUrl, $web)
{
$parametersOK = “true”
if ($XMLNode.url.Length -eq 0)
{
Write-Host “Invalid url for web”
$parametersOK = “false”
}
$newWebUrl = $parentWebUrl + “/” + $XMLNode.url
$newWebTemplate = “”
if ($XMLNode.template.Length -gt 0){$newWebTemplate = $XMLNode.template}
$newWebName = “”
if ($XMLNode.name.Length -gt 0){$newWebName = $XMLNode.name}
$newWebTheme = “”
if ($XMLNode.theme.Length -gt 0){$newWebTheme = $XMLNode.theme}
$newWebMasterPage = “”
if ($XMLNode.masterPage.Length -gt 0){$newWebMasterPage = $XMLNode.masterPage}
$newWebCustomMasterPage = “”
if ($XMLNode.customMasterPage.Length -gt 0){$newWebCustomMasterPage = $XMLNode.customMasterPage}
$newWebDescription = “”
if ($XMLNode.description.Length -gt 0){$newWebDescription = $XMLNode.description}
$newWebQuickLaunch = $false
if ($XMLNode.quickLaunch -ieq “true”){$newWebQuickLaunch = $true}
$newWebUniquePermissions = $false
if ($XMLNode.uniquePermissions -ieq “true”){$newWebUniquePermissions = $true}
$newWebTopNav = $false
if ($XMLNode.topNav -ieq “true”){$newWebTopNav = $true}
$newWebParentNav = $false
if ($XMLNode.parentNav -ieq “true”){$newWebParentNav = $true}
if ($parametersOK -eq “true”)
{
if ($newWebTopNav -eq $true)
{
if ($newWebTemplate.Length -gt 0)
{
New-SPWeb -Url $newWebUrl -Template $newWebTemplate -Name $newWebName -Description $newWebDescription -AddToTopNav
}
else
{
New-SPWeb -Url $newWebUrl -Name $newWebName -Description $newWebDescription -AddToTopNav
}
}
else
{
if ($newWebTemplate.Length -gt 0)
{
New-SPWeb -Url $newWebUrl -Template $newWebTemplate -Name $newWebName -Description $newWebDescription
}
else
{
New-SPWeb -Url $newWebUrl -Name $newWebName -Description $newWebDescription
}
}
$newWeb = Get-SPWeb $newWebUrl
$newWeb.QuickLaunchEnabled = $newWebQuickLaunch
$newWeb.Navigation.UseShared = $newWebParentNav
$newWeb.Update()
# Set Master Pages
if ($newWebMasterPage.Length -gt 0 -or $newWebCustomMasterPage.Length -gt 0)
{
SetWebMasterPages $newWeb $newWebMasterPage $newWebCustomMasterPage
}
# Set theme
if ($newWebTheme.Length -gt 0)
{
SetWebTheme $newWeb $newWebTheme
}
# Set individual permissions
if ($newWebUniquePermissions -eq $true)
{
$newWeb.BreakRoleInheritance($false)
if ($XMLNode.permissions.ChildNodes.Count -gt 0)
{
foreach ($permissionNode in $XMLNode.permissions.ChildNodes)
{
$accountType = $permissionNode.accountType
$accountName = $permissionNode.accountName
$permissionMask = $permissionNode.permissionMask
$account = $null
if ($accountType -eq “SPGroup”)
{
if ($newWeb.SiteGroups[$accountName])
{
$account = $newWeb.SiteGroups[$accountName]
}
else
{
$account = $newWeb.Site.RootWeb.SiteGroups.Add($accountName,$web.CurrentUser,$web.CurrentUser,”")
$newWeb.Site.RootWeb.Dispose()
}
}
else
{
$account = $newWeb.EnsureUser($accountName)
}
$roleAssignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
$roleDefinition = $newWeb.RoleDefinitions[$permissionMask]
$roleAssignment.RoleDefinitionBindings.Add($roleDefinition);
$newWeb.RoleAssignments.Add($roleAssignment)
}
}
}
$newWeb.Dispose()
# Process child nodes
if ($XMLNode.sites.ChildNodes.Count -gt 0)
{
foreach ($childNode in $XMLNode.sites.ChildNodes)
{
CreateSitesFromXML $childNode $newWebUrl $web
}
}
}
}
function CreateSiteStructure()
{
Param (
[parameter(Mandatory=$true)][string]$StartSite,
[parameter(Mandatory=$true)][string]$XMLLocation
)
#Get XML file containing groups and associated users
$sitesXML = [xml] (Get-Content ($XMLLocation))
$site = Get-SPSite $StartSite
$web = $site.RootWeb
#Loop through top level nodes
$sitesXML.rootNode.sites.site | ForEach-Object {
CreateSitesFromXML $_ $web.url $web
}
$web.Dispose()
$site.Dispose()
}