The answer appears to be that this is not possible:
https://docs.microsoft.com/en-us/answers/questions/581947/unable-to-update-scripteditor-webpart-csom-powersh.html?childToView=582966#comment-582966
Testing by a Microsoft employee respondent confirms my findings. This may be possible with the snap-in, though I am not running PowerShell on the SharePoint server, so this does not appear to be an option for me.
I think the next best option is to delete and create the web part each time I want to refresh it. This seems heavy handed to me, hopefully MSFT solves this in future iterations.
Note: Content Editor display the data poorly and is not a good choice
for my case.
Here is my extremely verbose solution:
Function replaceScriptEditor(){
param
(
[Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.ClientRuntimeContext] $ctx,
[Parameter(Mandatory=$true)] [string] $pageRelativeUrl,
[Parameter(Mandatory=$true)] [string] $contentTitle,
[Parameter(Mandatory=$true)] [string] $content,
[Parameter(Mandatory=$true)] [int] $wpZoneOrder
)
$wpZoneID = "Main"
$WebPartXml = [xml] "
<webParts>
<webPart xmlns='http://schemas.microsoft.com/WebPart/v3'>
<metaData>
<type name='Microsoft.SharePoint.WebPartPages.ScriptEditorWebPart, Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' />
<importErrorMessage>Cannot import this Web Part.</importErrorMessage>
</metaData>
<data>
<properties>
<property name='ExportMode' type='exportmode'>All</property>
<property name='HelpUrl' type='string' />
<property name='Hidden' type='bool'>False</property>
<property name='Description' type='string'>Allows authors to insert HTML snippets or scripts.</property>
<property name='Content' type='string'>$content</property>
<property name='CatalogIconImageUrl' type='string' />
<property name='Title' type='string'>$contentTitle</property>
<property name='AllowHide' type='bool'>True</property>
<property name='AllowMinimize' type='bool'>True</property>
<property name='AllowZoneChange' type='bool'>True</property>
<property name='TitleUrl' type='string' />
<property name='ChromeType' type='chrometype'>None</property>
<property name='AllowConnect' type='bool'>True</property>
<property name='Width' type='unit' />
<property name='Height' type='unit' />
<property name='HelpMode' type='helpmode'>Navigate</property>
<property name='AllowEdit' type='bool'>True</property>
<property name='TitleIconImageUrl' type='string' />
<property name='Direction' type='direction'>NotSet</property>
<property name='AllowClose' type='bool'>True</property>
<property name='ChromeState' type='chromestate'>Normal</property>
</properties>
</data>
</webPart>
</webParts>"
try{
Write-Host "Getting the page with the webpart we are going to modify" -ForegroundColor Green
#Using the params, build the page url
Write-Host "Getting the page with the webpart we are going to modify: " $pageRelativeUrl -ForegroundColor Green
#Getting the page using the GetFileByServerRelativeURL and do the Checkout
#After that, we need to call the executeQuery to do the actions in the site
$page = $ctx.Web.GetFileByServerRelativeUrl($pageRelativeUrl)
$page.CheckOut()
$ctx.ExecuteQuery()
Write-Host "The page is checked out" -ForegroundColor Green
try{
#Get the webpart manager from the page, to handle the webparts
$webpartManager = $page.GetLimitedWebPartManager([Microsoft.Sharepoint.Client.WebParts.PersonalizationScope]::Shared);
#Load and execute the query to get the data in the webparts
Write-Host "Getting the webparts from the page" -ForegroundColor Green
$ctx.load($webpartManager.webparts)
$ctx.ExecuteQuery();
#Remove the existing Script Editor WebPart
foreach($webPartDefinition in $webpartManager.webparts){
$ctx.Load($webPartDefinition.WebPart.Properties)
#send the request containing all operations to the server
try{
$ctx.executeQuery()
}
catch{
write-host "Error: $($_.Exception.Message)" -foregroundcolor red
}
#Only change the webpart with a certain title
if ($webPartDefinition.WebPart.Properties.FieldValues.Title -eq $contentTitle)
{
try {
Write-Host "Deleting existing webpart." -ForegroundColor Green
$webPartDefinition.DeleteWebPart()
$ctx.executeQuery()
} catch {
Write-Output $Error
}
}
}
#Import the webpart
$wp = $webpartManager.ImportWebPart($WebPartXml.OuterXml)
#Add the webpart to the page
Write-Host "Add the webpart to the Page" -ForegroundColor Green
$webPartToAdd = $webpartManager.AddWebPart($wp.WebPart, $wpZoneID, $wpZoneOrder)
$ctx.Load($webPartToAdd);
$ctx.ExecuteQuery()
}
catch{
Write-Host "Errors found:`n$_" -ForegroundColor Red
}
finally{
#CheckIn the Page
Write-Host "Checkin the Page" -ForegroundColor Green
$page.CheckIn("Add the User Profile WebPart", [Microsoft.SharePoint.Client.CheckinType]::MajorCheckIn)
$ctx.ExecuteQuery()
Write-Host "The webpart has been added" -ForegroundColor Yellow
}
}
catch{
Write-Host "Errors found:`n$_" -ForegroundColor Red
}
}
$statusReport = "<![CDATA[$($htmlData]]>"
$tenantAdmin = "me@domain.com"
$tenantAdminPassword = "5ecureP@ss!"
$secureAdminPassword = $(convertto-securestring $tenantAdminPassword -asplaintext -force)
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteURL)
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($tenantAdmin, $secureAdminPassword)
$ctx.Credentials = $credentials
$contentTitle = 'Data_Health'
[int]$index = 1 #position on page, lower number = higher on page
$relUrl = "/teams/myTeam/Team_Home/Lists/My_List/Gantt_View.aspx"
Write-Output "$(Get-Date -Format yyyy-MM-dd.hh:mm:ss): Updating '$contentTitle' WebPart on site '$relUrl'."
replaceScriptEditor -ctx $ctx -pageRelativeUrl $relUrl -contentTitle $contentTitle -content $statusReport -wpZoneOrder $index