#Script: WebImport.ps1
#Source: https://codemonkeysoftware.atlassian.net
#notes: Run this script in Administrator mode.
# This script will import content packages gerneated by WebExport.ps1
# Example invocation: http://portal.com "My Portal.xml" C:\ContentExport
param
(
[string]$destinationSiteUrl = $(Read-Host -Prompt "Please enter the URL of the destination site eg; http://myserver"),
[string]$importManifest = $(Read-Host -Prompt "Please enter the content set name (The content manifest xml file) eg; MySet.xml"),
[string]$importFolder = "C:\ContentExport"
)
$contentSetName = $importManifest
#region IO Functions
function Get-ScriptDirectory
{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
Split-Path $Invocation.MyCommand.Path
}
function Set-Directory($location)
{
#[Environment]::CurrentDirectory = Get-ScriptDirectory
[IO.Directory]::SetCurrentDirectory((Convert-Path($location)))
}
#endregion
#region SharePoint Snappin Setup
$snapin="Microsoft.SharePoint.PowerShell"
if (get-pssnapin $snapin -ea "silentlycontinue") {
write-host -f Green "PSsnapin $snapin is loaded"
}
else {
if (get-pssnapin $snapin -registered -ea "silentlycontinue") {
write-host -f Green "PSsnapin $snapin is registered"
Add-PSSnapin $snapin
write-host -f Green "PSsnapin $snapin is loaded"
}
else {
write-host -f Red "PSSnapin $snapin not found"
}
}
#endregion
#region Host Feedback Helpers
function WriteSuccess($msg, $msg2)
{
Write-Host -ForegroundColor Green $msg $msg2
}
function WriteFailure($msg, $msg2)
{
Write-Host -ForegroundColor Red "ERROR: " $msg $msg2
}
function WriteInfo($msg, $msg2)
{
Write-Host " -" $msg $msg2
}
function WriteWarning($msg, $msg2)
{
Write-Warning (" -" + $msg + " " + $msg2)
}
function WriteInfoNoLine($msg, $msg2)
{
Write-Host " -" $msg $msg2 -NoNewline
}
#endregion
#region Xml Content Manifest
function LoadConfiguration($configFile)
{
if(![IO.File]::Exists($configFile))
{
throw "Could not find configuration file: $configFile. Script Terminated."
}
WriteInfo "Found configuration file: $configFile"
try
{
$config = [xml] (get-content -Path $configFile)
WriteSuccess "Content Manifest Loaded Successfully $configFile"
return $config.Content
}
catch
{
WriteFailure "Manifest file found but could not be loaded. May not be valid XML"
throw
}
}
#endregion
#region Data Clean Up
# When content in imported into a new environment the Term Store ID is kept on the
#taxonomy fields. This causes a problem as the new term store has a different id.
#These functions clean up the taxonomy list which has bad entries following an import
#and modify all the items and resets the correct values.
function CleanTaxonomyList($site)
{
Write-Host "Cleaning /Lists/TaxonomyHiddenList"
$web = $site.RootWeb
$taxlist = $web.GetList("Lists/TaxonomyHiddenList")
for($count = $taxlist.Items.Count - 1; $count -ge 0; $count--)
{
$item = $taxlist.Items[$count]
if([string]::IsNullOrEmpty($item.Title))
{
$item.Delete()
if($?)
{
#Write-Host "Deleted Item with bad title"
}
else
{
Write-Host -ForegroundColor Red "Failed to deleted Item with bad title"
}
}
}
}
#This function will reset the term store id if it is wrong, and will fix the WssId.
#If the correct term cannot be located, the default one will be used.
function ResetTaxonomyDefaults($site, [Microsoft.SharePoint.Publishing.PublishingWeb] $web)
{
$txs = New-Object "Microsoft.SharePoint.Taxonomy.TaxonomySession" -ArgumentList $site
$pages = $web.GetPublishingPages()
foreach($page in $pages)
{
Write-Host -ForegroundColor Cyan "Checking publishing page " $page.Title
if($page.ListItem.File.CheckOutStatus -ne "None")
{
$page.CheckIn("Checked in by data clean process");
}
$page.CheckOut();
foreach ($field in $page.ListItem.Fields)
{
if($field.GetType().Name -eq "TaxonomyField")
{
$taxField = [Microsoft.SharePoint.Taxonomy.TaxonomyField] $field
#Write-Host "Found field to update:" $taxField.Title
$currentValue = $page.ListItem.Properties[$taxField.InternalName]
#Write-Host "Current Value is" $currentValue
$templateField = $page.ListItem.ParentList.ParentWeb.Site.RootWeb.Fields[$field.Id]
$defaultValue = $templateField.DefaultValue
$termStore = $txs.TermStores[$templateField.SspId]
$termSet = $termStore.GetTermSet($templateField.TermSetId)
if($taxField.SspId -ne $templateField.SspId)
{
# Write-Host "TaxField SspId is not correct, updating"
$taxField.SspId = $templateField.SspId
$taxField.Update()
}
if($taxField.TermSetId -ne $templateField.TermSetId)
{
# Write-Host "TaxField TermSetId is not correct, updating"
$taxField.TermSetId = $templateField.TermSetId
$taxField.Update()
}
$fieldValue = $templateField.GetFieldValue($currentValue)
if(($fieldValue.GetType().Name -eq "TaxonomyFieldValue") -and ($fieldValue -eq $null -or [string]::IsNullOrEmpty($fieldValue.TermGuid)))
{
$fieldValue = $templateField.GetFieldValue($defaultValue)
}
if(($fieldValue.GetType().Name -ne "TaxonomyFieldValue") -and ($fieldValue[0] -eq $null -or [string]::IsNullOrEmpty($fieldValue[0].TermGuid)))
{
$fieldValue = $templateField.GetFieldValue($defaultValue)
}
if($fieldValue.GetType().Name -eq "TaxonomyFieldValue")
{
try
{
$term = $termSet.GetTerm($fieldValue.TermGuid)
}
catch
{
Write-Host -red ("Failed to update field {0} for page {1} in web {2}" -f $taxField.InternalName, $page.Title, $web.Url)
}
}
else
{
try
{
$term = $termSet.GetTerm($fieldValue[0].TermGuid)
}
catch
{
Write-Host -red ("Failed to update field {0} for page {1} in web {2}" -f $taxField.InternalName, $page.Title, $web.Url)
}
}
$taxField.SetFieldValue($page.ListItem, $term)
}
}
$page.ListItem.Update()
$page.CheckIn("Data clean process")
}
}
function CleanSiteCollection ($siteColUrl)
{
[Microsoft.SharePoint.SPSite] $site = get-spsite -Limit ALL | where-object {$_.Url -ieq $siteColUrl}
CleanTaxonomyList $site
$site | Get-SPWeb -limit all | ForEach-Object {
#Check to see if site is a publishing site
if ([Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($_))
{
Write-Host "Cleaning pages in `"$($_.Title)`" site."
#Get the Publishing Web and pages within it
$publishingWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($_)
ResetTaxonomyDefaults $site $publishingWeb
}
$_.Dispose()
}
$site.Dispose()
}
#endregion
function Import($siteColUrl, $manifest, $importFolder)
{
$siteCol = get-spsite -Limit ALL | where-object {$_.Url -ieq $siteColUrl}
if($siteCol -eq $null)
{
throw "Unable to locate " + $siteColUrl
}
$manifest = LoadConfiguration ($importFolder + "\" + $manifest)
$importFiles = $manifest.ContentFile
foreach($node in $importFiles)
{
$filename = ($importFolder + "\" + $node.InnerText)
$url = $node.Url
$fullUrl = ($siteCol.Url + $url)
$web = $siteCol | Get-SPWeb -Limit ALL | Where-Object {$_.ServerRelativeUrl -ieq $url}
if($web -eq $null)
{
WriteInfo "Creating new web at url $url"
try
{
$template = Get-SPWebTemplate ($node.WebTemplate + "#" + $node.Configuration)
if($template -eq $null)
{
throw "Template " + ($node.WebTemplate + "#" + $node.Configuration) + " does not exist in this farm"
}
$web = New-SPWeb -Template $template -Url $fullUrl -Name $node.Title -Description $node.Description
}
catch
{
WriteFailure "Failed to import content at location $url - " $_
continue
}
WriteInfo "New web created at url $url"
}
try
{
$web | Import-SPWeb -Path $filename -Force -ActivateSolutions:$false -IncludeUserSecurity:$true -UpdateVersions:Overwrite
WriteSuccess "Imported $filename to " $web.Url
}
catch
{
WriteFailure "Error importing file $filename to web $web for site $siteCol" $_
}
finally
{
$web.Dispose()
}
}
}
Import $destinationSiteUrl $contentSetName $importFolder
CleanSiteCollection $destinationSiteUrl |