#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