Configure SharePoint managed metadata columns using PowerShell CSOM

I received the request from a colleague to create a script that will configure all managed metadata columns in SharePoint Online to allow people to fill in values.
My colleague first tried this using PnP but was unable to configure the necessary property of a managed metadata column.
It is possible to set this property using the client object model (CSOM) in PowerShell.
You will need the SharePoint Online Client Components SDK which you can download at https://www.microsoft.com/en-us/download/confirmation.aspx?id=42038

We first verified that we were able to change this property by using the below script:

$url = "https://<TenantName>.sharepoint.com"
$userName = "admin@<TenantName>.onmicrosoft.com"
$password = Read-Host "Please enter the password for $($userName)" -AsSecureString

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

$SPOCredentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($userName, $password)

$context = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$context.Credentials = $SPOcredentials
$web = $context.Web
$context.Load($web)
$list = $web.lists.GetByTitle("Documenten")
$context.Load($list)
$field = $list.fields.getbytitle("Zoekwoorden")

$context.load($field)
$context.ExecuteQuery()

$taxField = [Microsoft.SharePoint.Client.ClientContext].GetMethod("CastTo").MakeGenericMethod([Microsoft.SharePoint.Client.Taxonomy.TaxonomyField]).Invoke($context, $field)

$taxfield.open = $true
$taxfield.update()

$context.executequery()

Once we retrieved the correct field we had to cast this to a taxonomyField to be able to set the property “Open”.
The next step was to build a script around this that allows us to configure all managed metadata columns on the rootsite and all subsites.
This script has been upload to GitHub: https://github.com/peetersm12/ConfigureManagedMetadaColumnCSOM

The script will loop through all subsites to find the specified column on all the lists and libraries available.
You can first use a “preview” action to find all lists and libraries which have a column with the name you are looking to update.
Then you can update these columns so that users are allowed to fill in values.
Note that you can use this script for all updates for a specific column, just change the part where you  find the above code.

Using the script

Open the .ps1 file and copy the whole content of the file to preload the functions in the SharePoint Online Management Shell as administrator.

Next run 1 of the following commands:

To first list all lists/libraries which currently has the specified column title
set-mmcolumn -Action “Preview”

To update all lists and libraries which has the specified column title
set-mmcolumn -Action “Update”

Running the preview

Run the following command:

set-mmcolumn -Action "Preview"

and answer the following questions 1 by 1

The script will start and the output will be shown on screen, you can also verify the transcript although this isn’t color coded but search for “Found:”

We can see that our column has been found for the library “Documenten” and users are currently not allowed to fill in values.
Next run the script to update these columns.

Running the update

Run the following command:

set-mmcolumn -Action "Update"

and enter the following questions 1 by 1

The script will start and the output will be shown on screen, you can also verify the transcript although this isn’t color coded but search for “Found:”


We can see that our column has been found for the library “Documenten” and the value has been updated from False to true.
Run the preview again to see if all “green lines” are now set to true

PowerShell script to loop through each SharePoint Online site

This PowerShell script will let you loop through each SharePoint Online site to perform a specific action. I’ve been asked a couple of times to write a script to for example create a new document library in each site, add a web part or grant permissions. I always start with the below script so I only need to write the desired action and don’t need to worry about doing this for each site. Please let me know if you have used my script, for what purpose and if there are any questions.

Running the script

We will first start by opening the SharePoint Online Management Shell as administrator which can be downloaded at https://www.microsoft.com/en-us/download/details.aspx?id=35588.

 

 

 

 

You will only need to add the action below the start and above the comment section and it will run for each site. Just copy and paste the full script.

function Update-SPOWeb ($web){
#Get Web information and subsites
$context = New-Object Microsoft.SharePoint.Client.ClientContext($web)
$context.Credentials = $SPOCredentials
$web = $context.Web
$context.Load($web)
$context.Load($web.Webs)

#send the request containing all operations to the server
try{
$context.executeQuery()

#check any subweb if present
if ($web.Webs.Count -ne 0){
foreach ($subweb in $web.Webs){
Update-SPOWeb($subweb.url)
}
}

##########################
###                    ###
###    start action    ###
###                    ###
##########################

write-host $web.title

##########################
###                    ###
###    stop action     ###
###                    ###
##########################

}
catch{
write-host "Error: $($_.Exception.Message)" -foregroundcolor green
}
}

function Update-SPOWebs{
#variables that will be asked during the script
$adminUrl = Read-Host "Please enter the Office365 Admin URL (e.g. https://spfire-admin.sharepoint.com)"
$webUrl = Read-Host "Please enter the start url (e.g. https://spfire.sharepoint.com/sites/rootsite"
$userName = Read-Host "Please enter the Office365 admin account (e.g. mpadmin@spfire.onmicrosoft.com)"
$password = Read-Host "Please enter the password for $($userName)" -AsSecureString

# set SharePoint Online and Office 365 credentials
$SPOCredentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($userName, $password)
$credentials = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $password

#connect to to Office 365
try{
Connect-SPOService -Url $adminUrl -Credential $credentials
write-host "Info: Connected succesfully to Office 365" -foregroundcolor green
}
catch{
write-host "Error: $($_.Exception.Message)" -foregroundcolor red
Break delete-SPOSites
} 
Update-SPOWeb($webUrl)
}
Update-SPOWebs

 

image

Press enter

image

Fill in the required information and press enter

image

In this case it has only listed the names for each site but you do whatever you need.

Editing Web Part properties with PowerShell CSOM in SharePoint

This PowerShell script can help when you need to change a Web Part property in SharePoint for multiple sites. We have used my script to create around 300 sites using a custom template. Certain sites were already in production when we found an issue with a certain Web Part. In stead of changing this manually I have created a script to loop through all sites and change a certain Web Part property. The script that I’ve created does the following:

  1. Loop through all subwebs from a given start point
  2. Get the specific .aspx page
  3. Get the correct Web Part
  4. Change the property

The below example will change the property of a specific Web Part on the default /SitePages/Home.aspx

Running the script

We will first start by opening the SharePoint Online Management Shell as administrator which can be downloaded at https://www.microsoft.com/en-us/download/details.aspx?id=35588.

You will need to change the first variables in the Change-WebPart function to match your Office 365 tenant and copy this bit to PowerShell.

function Change-WebPart {
	#variables that needs to be set before starting the script
	$siteURL = "https://spfire.sharepoint.com"
	$userName = "mpadmin@spfire.onmicrosoft.com"
	$webURL = "https://spfire.sharepoint.com"
	$relativePageUrl = "/SitePages/Home.aspx"
  
	# Let the user fill in their password in the PowerShell window
	$password = Read-Host "Please enter the password for $($userName)" -AsSecureString</pre>
	# set SharePoint Online credentials
	$SPOCredentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($userName, $password)

	# Creating client context object
	$context = New-Object Microsoft.SharePoint.Client.ClientContext($webURL)
	$context.credentials = $SPOCredentials

	#get Page file
	$page = $context.web.getFileByServerRelativeUrl($relativePageUrl)
	$context.load($page)

	#send the request containing all operations to the server
	try{
		$context.executeQuery()
	}
	catch{
		write-host "Error: $($_.Exception.Message)" -foregroundcolor red
	}

	#use the WebPartManger to load the webparts on a certain page
	$webPartManager = $page.GetLimitedWebPartManager([System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
	$context.load($webPartManager.webparts)

	#send the request containing all operations to the server
	try{
		$context.executeQuery()
	}
	catch{
		write-host "Error: $($_.Exception.Message)" -foregroundcolor red
	}

	#loop through all WebParts to get the correct one and change its property
	foreach($webPartDefinition in $webpartmanager.webparts){
		$context.Load($webPartDefinition.WebPart.Properties)

		#send the request containing all operations to the server
		try{
			$context.executeQuery()
		}
		catch{
			write-host "Error: $($_.Exception.Message)" -foregroundcolor red
		}

		#Only change the webpart with a certain title
		if ($webPartDefinition.WebPart.Properties.FieldValues.Title -eq "Documents")
		{
			$webPartDefinition.webpart.properties["Title"] = "My Documents"
			$webPartDefinition.SaveWebPartChanges()
		}
	}
}
Change-WebPart

image

First enter your password and press enter (I didn’t add output on this script so trust me that I didn’t had any errors 🙂 )

The above script has changed

image

To

image

This script is not very useful when changing only 1 web part but image you need to change a certain web part on 200 project sites because of a template update or mistake. This way you can update all your project sites matching the changes you have made in the template regarding web parts.