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:
- Get all the pages that have the StatusIndicatorWebPart added on it
- For each page, get all the instances of the StatusIndicatorWebPart
- For each found instance of the WebPart, get the properties
- Update
hasIssues
property's value according to the value ofcolor
property- If
color
isred
thenhasIssues
is set totrue
- Otherwise
hasIssues
is set tofalse
- If
- 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