Tuesday, March 25, 2014

SharePoint Online Site Column Group Copy in PowerShell

This is Part 2 of the “Elise” scripting process, where I hope to copy the entire contents of one SharePoint Online site to another.

 

I had some site columns I developed in one way or another on my SharePoint Online site within Office 365.  They were all nestled together in a custom group name, conveniently called “Wef Custom”.  This was the most import part of the whole shebang. My thought was to use PowerShell and the SharePoint Client-Side Object Model (CSOM) to copy these custom site columns from one instance to another.

 

elise - site columns

 

Lucky for me, this was an easy task because:

  • Site Columns have a property called SchemaXML, which is basically the XML definition of the field specifics.
  • The Context.Web.Fields object has a method to “AddFieldAsXml”.

Naturally, Managed Metadata columns aren’t wired in.  I attempted to parse through the XML definitions to override the SPPID, WSSID, etc. attributes based on values derived from the destination system. I failed.  Wiring up manually to a Term Set took me about 25 seconds.

Here’s the script:

#######################

#

# Migrate Site Columns by Custom Group Name

#

# "Elise", a series of scripts to migrate O365 SharePoint Online Assets across O365 instances

#

# Copyright 2014, John Wefler, Rightpoint Consulting, LLC.

#

#######################



# Change the following to reflect your environments



# 1) Source Site

$sUrl = "https://wefnetOrig.sharepoint.com/"

$sAdmin = "[email protected]"

$sPwd = "xxxxxxxxxxx"



# 2) Destination Site

$dUrl = "https://wefnetDest.sharepoint.com/"

$dAdmin = "[email protected]"

$dPwd = "xxxxxxxxxxx"



# 3) What Site Column Group do you want to synchronize?

$sGroupName = "Wef Custom"



## Stop here

$lcid = "1033"



$sSecurePwd = ConvertTo-SecureString $sPwd -AsPlainText -Force

$dSecurePwd = ConvertTo-SecureString $dPwd -AsPlainText -Force



# these aren't required for the script to run, but help to develop

Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"

Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

# doh

Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll"



# connect/authenticate to SharePoint Online and get ClientContext object.. 

$sCtx = New-Object Microsoft.SharePoint.Client.ClientContext($sUrl)

$sCredentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($sAdmin, $sSecurePwd)

$sCtx.Credentials = $sCredentials



$dCtx = New-Object Microsoft.SharePoint.Client.ClientContext($dUrl)

$dCredentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($dAdmin, $dSecurePwd)

$dCtx.Credentials = $dCredentials



$continue = 0



if (!$dCtx.ServerObjectIsNull.Value)

{

    Write-Host "Connected to DESTINATION SharePoint Online site: " $dCtx.Url "" -ForegroundColor Green



    $continue = 1

}

 

if (!$sCtx.ServerObjectIsNull.Value -and $continue -eq 1) 

{ 

    Write-Host "Connected to the SOURCE SharePoint Online site: " $sCtx.Url "" -ForegroundColor Green

    $sSite = $sCtx.Web

    $sCols = $sSite.AvailableFields

    $sCtx.Load($sCols)

    $sCtx.ExecuteQuery()



    Write-Host "Found" $sCols.Count "Site Columns" -ForegroundColor Cyan



    foreach($sCol in $sCols)

    {

        if($sCol.Group -eq $sGroupName)

        {

            Write-Host ".........Column found:" $sCol.StaticName "" -ForegroundColor Cyan

            

            #convert to XML object for future manipulation of nodes

            [xml]$sColXML = $sCol.SchemaXml



            $newCol = $sColXML.OuterXml.ToString()



            $options = [Microsoft.SharePoint.Client.AddFieldOptions]::AddFieldToDefaultView



            $dField = $dCtx.Web.Fields.AddFieldAsXml($newCol, $true, $options)

            

            $dCtx.Load($dCtx.Web)

            $dCtx.ExecuteQuery()

        }

    }

}



$dCtx.Dispose()

$sCtx.Dispose()

And here’s the output:

elise-run2

Note the failure with the “Band” Managed Metadata field. It’s only disconnected from proper Term Set.