Update 3/6/2014
This script is no longer needed! ShareGate 4.5 was released and now copies these items natively- no workaround needed!
Hats off to the Share-Gate development team for this update!
The content below should be considered Archive/reference:
If you’re a user of Share-Gate, you may have run into an issue transferring SharePoint lists with Multiple choice fields.
The migrations work, so long as all the data in your list fits into the list of choices you have. But what if at one point the list of choices changed, and you now have data in your list that isn’t in the choice list?
The scenario is like this.
Say you have a choice field with “region”
It started out with North, South, East and West.
So you have data in the list that has those values in it.
Then someone says, “Hey lets restructure – going forward we want people to choose from: East, Central an West”
See what happened there?
The data that’s already in there could be North South East or West, but NEW data can only be West Central or East. This causes issues when the list is migrated.
The solution is to temporarily allow “Fill-in Choices:”
Ideally, you would change the value “Allow ‘Fill-in’ choices:” above from “no” to “yes” before the migration, then set it back to no after the migration at the new location.
The trouble is, a given web can have quite a few lists, and each list can have quite a few fields. Going through all of this manually, twice is not fun? What is fun you ask? I’m glad you ask – Running two PowerShell scripts…
I wrote this little PowerShell script…
Here’s what it does –
It enumerates though all the lists in your SP Web.
Then it checks each list to see if has any “Choice Fields” that are set to not allow fill-in choices.
Then it.. sets the Value to yes for “Allow Fill in Values”
How much would you pay for a timesaving script like this???
But wait! There’s more!
While it’s doing all this, its also generating a 2nd powershell script – filled with commands to turn these values back off.
$SourceURL = "https://yoururl.com/sitecollection/web"
$DestinationURL = $SourceURL #Feel free to replace this with the destination, or leave it the same for testing purposes
$web = get-spweb $SourceURL
$actionweb = get-spweb $SourceURL
#build a "get back" script"
$script = ""
$script = '$web = get-spweb ' + $DestinationURL
foreach ($list in $web.lists)
{
# get the list of fields with choices that are set to false (Assuming they exist)
$fields = $list.fields | where {$_.type -eq "choice" -and $_.FillInChoice -eq $false}
if ($fields -ne $null)
{
write-host "Title: $($list.title) ($($fields.count))" -foregroundcolor green
foreach ($field in $fields)
{
$f = $actionweb.lists[$list.title].fields[$field.title]
$f.FillInChoice = $true
$f.update()
$line = '$field = $web.lists["' + $list.title + '"].fields["' + $field.title + '"]; $field.FillInChoice = $false; $field.Update()'
write-host $line "#" $field.id
if ($field.id -eq $null)
{
write-host "NULL FIELD! $($field.id)" -foregroundcolor yellow
$field
write-host "--------------------------------" -foregroundcolor yellow
}
$script = $script + "`r`n" + $line
}#end foreach
}#end if
}#end foreach
$script | out-file -filepath "Reset_$($DestinationURL)_FillInChoices_$(get-date -format 'yyyyMMdd_HHmmss').ps1"
Note in the above script – I needed two near identical $web objects – the reason for this is that as I went through the list in code, and did my .update() statements, it would invalidate the state of the $web object
Another upside is that the source and destination can be on different farms – just move the generated PS1 file to the destination and run it there.
If there’s a downside, it’s that this really only works for SP 2010 and SP 2013 On premise.
Great article Jack!
Please note that Sharegate 4.5 will contain the functionality to automatically enable “Allow Fill-In Choices” during a migration.