I wanted a CSOM script in PowerShell to add a new value to a choice field in SharePoint. Most of the examples I found were in CSOM Managed Code (C#) but could not find anything in PowerShell.
I came up with the embedded code.
The client assemblies are referenced
- SharePoint Assemblies\Microsoft.SharePoint.Client.dll
- SharePoint Assemblies\Microsoft.SharePoint.Client.Runtime.dll
I have created the function Add-ChoiceValueToField to contain the logic to add a value to a choice field.
The Field object has to be cast into FieldChoice to expose the Choices property. In PowerShell the CastTo method can be accessed using the MakeGenericMethod.
[Microsoft.SharePoint.Client.ClientContext].GetMethod("CastTo").MakeGenericMethod([Microsoft.SharePoint.Client.FieldChoice]).Invoke($ctx,$field)
I have used the Load-CSOMProperties function from script Load-CSOMProperties.ps1 to load the existing property “Choices” which an immutable collection. Load-CSOMProperties.ps1 is available from blog post Loading Specific Values Using Lambda Expressions and the SharePoint CSOM API with Windows PowerShell to help with querying object properties like Lambda expressions in C#.
Load-CSOMProperties -object $fieldChoice -propertyNames @("Choices") ;
I have saved the collection in an array object $FieldChoiceValues to which the existing choice values have been added. If the value to be added does not exist, then it is added to the array object $FieldChoiceValues.
Finally the Field Choices property is updated with the array object $FieldChoiceValues
$fieldChoice.Choices = $FieldChoiceValues;
$fieldChoice.Update()
The function can be called as follows
Add-ChoiceValueToField -ctx $ctx -ListTitle "ListTestManually" -FieldName "TypeNum" -ChoiceValue "7"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Param( | |
[Parameter(Mandatory=$true, position=0, ValueFromPipeLineByPropertyName=$true, HelpMessage="Specifies the Web. The type must be a valid URL or GUID")] | |
[String]$WebUrl | |
) | |
Set-Location $PSScriptRoot | |
Add-Type -Path ( ".\SharePoint Assemblies\Microsoft.SharePoint.Client.dll") | |
Add-Type -Path ( ".\SharePoint Assemblies\Microsoft.SharePoint.Client.Runtime.dll") | |
# help to use lamda expressions to query object properties | |
. .\Load-CSOMProperties.ps1 | |
function Add-ChoiceValueToField { | |
[CmdletBinding()] | |
param | |
( | |
[Parameter(Mandatory=$true,Position=0)] | |
[Microsoft.SharePoint.Client.ClientContext]$ctx, | |
[Parameter(Mandatory=$false, position=1, ValueFromPipeLine=$true, ValueFromPipeLineByPropertyName=$true, HelpMessage="TODO")] | |
[Alias("ListName")] | |
[string]$ListTitle, | |
[Parameter(Mandatory=$false, position=2,ValueFromPipeLineByPropertyName=$true, HelpMessage="TODO")] | |
[string]$FieldName, | |
[Parameter(Mandatory=$false, position=3,ValueFromPipeLineByPropertyName=$true, HelpMessage="TODO")] | |
[Alias("Field")] | |
[string]$ChoiceValue | |
) | |
#Retrieve List | |
$List = $ctx.Web.Lists.GetByTitle($ListTitle) | |
$ctx.Load($List) | |
$ctx.ExecuteQuery() | |
#Retrieve field | |
$field = $List.Fields.GetByInternalNameOrTitle($FieldName); | |
$fieldChoice = [Microsoft.SharePoint.Client.ClientContext].GetMethod("CastTo").MakeGenericMethod([Microsoft.SharePoint.Client.FieldChoice]).Invoke($ctx,$field) | |
Load-CSOMProperties -object $fieldChoice -propertyNames @("Choices") ; | |
$ctx.Load( $fieldChoice); | |
$ctx.ExecuteQuery() ; | |
#if not exists then add | |
$bExists = $false | |
$FieldChoiceValues=@(); | |
foreach ($choice in $fieldChoice.Choices) | |
{ | |
$FieldChoiceValues +=$choice | |
if($choice -eq $ChoiceValue) | |
{ | |
$bExists = $true | |
} | |
} | |
#add choices to dropdown list | |
if($bExists -eq $false) | |
{ | |
$FieldChoiceValues += $ChoiceValue | |
$fieldChoice.Choices = $FieldChoiceValues; | |
$fieldChoice.Update() | |
$ctx.ExecuteQuery() ; | |
} | |
} | |
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($WebUrl) | |
# $ctx.Credentials = System.Net.CredentialCache.DefaultCredentials; | |
$web = $ctx.Web | |
$ctx.Load($web) | |
$ctx.ExecuteQuery() | |
Add-ChoiceValueToField -ctx $ctx -ListTitle "ListTestManually" -FieldName "TypeNum" -ChoiceValue "7" |