Oct 21, 2020

Update all your existing SPFx WebPart instances with PnP PowerShell

Hi Microsoft 365 devs !

Have you ever had the need to update the configuration of all WebParts already in place on your tenant? We will see that in some scenarios, that can be very handy and even mandatory some times...

What am I up to ?

Imagine you, or your customer, has a tenant with a significant number of sites, or pages that use a custom WebPart you developed. When the moment comes to ship a new version with new cool capabilities of your WebPart, you will probably need to add some WebPart properties, or review the format or semantics of the existing properties'values...

Imagine another scenario in which your WebPart properties rely on some external dependencies you don't control... If those dependencies happen to change, you will be forced to adapt and fix the code of your WebPart. If it has already been deployed and added to hundreds of pages, you will have to update the configuration of those hundreds of WebPart instances.

How to address that ?

The first and "obvious" solution would be to go manually update each of the WebPart on each and every pages. Well... First of all, I am a developer and lazy :D I would go that way ONLY if I have no other choices... Are there any ? YES, I'll get to it in a minute ;) Moreover, going to each page manually assumes that you know exactly where are all the WebPart instances...

One other solution could be that you handle that transition directly in the code of your WebPart... Personally, I'm not really in favor of this approach because it will make the code less clean, more complex then harder to maintain. You will have to handle many possible scenarios, and so on so forth... I'd prefer not to go that way...

So let's take the first approach, manually updating the properties of all WebPart instances and let's try to automate it!

Automation on SharePoint Online ? Let me check I have PnP PowerShell installed ! :D

Indeed, it's probably what every SharePoint Online administrator will think about. Let's use PnP PowerShell! To be fair, what I am going to describe here can probably easily be performed with the CLI for Microsoft 365 too! In this case, I did it with PnP PowerShell since this post is inspired by a real life situation I faced during my work assignment with my Valo friends and all the scripts are done using PnP PowerShell.

Our case study

To keep things simple, let's imagine the following use case: The WebPart StatusIndicatorWebPart we developed had a property called color that accepts the values red or green. We want to keep that property as is. Imagine now we now add a new property called hasIssues and we want that new property to be set according to the existing value of the color property. When the color is red, we want the hasIssues to be set to true, otherwise it will be set to false.

Okay got it ! Let's script our automated update process

Wait wait! Before scripting we need to know what precise steps we want to automate... Let's write it down:

  1. Get all the pages that have the StatusIndicatorWebPart added on it
  2. For each page, get all the instances of the StatusIndicatorWebPart
  3. For each found instance of the WebPart, get the properties
  4. Update hasIssues property's value according to the value of color property
    1. If color is red then hasIssues is set to true
    2. Otherwise hasIssues is set to false
  5. Save and publish the page with the changes

Okay... First challenge, how to get all the pages that has the WebPart on it? The solution is actually quite simple but I did not come at once to it. My colleague at Valo Jouni Poikolainen quickly gave me the solution. (Thank you mate for your efficiency! ;)): Let's use a search query filtering on the Id of the WebPart and file extension as aspx (for the pages) (The ID you can find in the manifest file of your SPFx solution).

So let's go with a search query alike FileExtension:aspx 67521df6-c396-48ac-9c4b-f76d6a595427

Okay, now we're ready to script

Using PnP PowerShell, here are our steps tranlated into script using PnP PowerShell

let's first connect to our tenant

####################################################
# Parameters
$site = "https://contoso.sharepoint.com/sites/site"
$creds = "contoso_admin"
# Let's put the WebPart ID into a variable for further use
$webPartId = "67521df6-c396-48ac-9c4b-f76d6a595427"

Connect-PnPOnline $site -Credentials $creds

1. Get all the pages that have the StatusIndicatorWebPart added on it

# Search all the pages containing the WebPart
$searchResults = Submit-PnPSearchQuery -Query "FileExtension:aspx $webPartId"
# Keep the needed information in a dedicated array
$pages = $searchResults.ResultRows | ForEach-Object { 
    @{ 
        Web = $_["SPWebUrl"];
        Url = $_["OriginalPath"];
    }
}

2. For each page, get all the instances of the StatusIndicatorWebPart

# For each page
	$pages | ForEach-Object {
		$page = $_
		

		If ($null -eq $page.Url) { Return }

		# Get the name of the page (last part of the URL)
		$pageUrl = $page.Url
        Write-Host "Updating WebPart instances on page $pageUrl"
		$pageName = $page.Url.Split("/")[-1]
        $connection = Connect-PnPOnline $page.Web -Credentials $credentials -ReturnConnection

        $clientSideComponents = Get-PnPClientSideComponent -Page $pageName -Web $page.Web -Connection $connection
		Write-Host "Found $($clientSideComponents.Count) components on the page."
		
		# Get the StatusIndicatorWebPart instances
		$wpInstances = $clientSideComponents | Where-Object { $_.WebPartId -eq $webPartId }

3. For each found instance of the WebPart, get the properties

	$wpInstances | ForEach-Object {
    $wpInstance = $_
    # Store the properties of the current instance as a object parsed from JSON
    $wpProps = $wpInstance.PropertiesJson | ConvertFrom-Json

4. Update hasIssues property's value according to the value of color property

Cheers

Yannick

Other posts