Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
collapsetrue
#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

Usage

Code Block
languagepowershell
 .\WebImport.ps1 http://destinationportal "Your Manifest.xml" c:\contentexport  #reads the manfiest from the contentexport folder and imports the files to the destination site collection

...