
Introduction
This time, I was supposed to add a webpart to SharePoint Online page programmatically.
It depends on our requirements, but we could use JavaScript or other Client Object Model libraries to add a web part to SharePoint page. My advice is, even if your requirements guide you to write PowerShell script, try to use Client Object Model instead Server Object Model, whenever possible.
Code
Let’s share the code to add a Content Editor webpart
to a SharePoint page:
function AddWebPartToPage ($ctx, $sitesURL) { | |
$pageRelativeUrl = "/Pages/Home.aspx" | |
$wpZoneID = "Left" | |
$wpZoneOrder= 0 | |
$WebPartXml = [xml] " | |
<WebPart xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://schemas.microsoft.com/WebPart/v2'> | |
<Title>User Properties</Title> | |
<FrameType>None</FrameType> | |
<Description>Allows authors to enter rich text content.</Description> | |
<IsIncluded>true</IsIncluded> | |
<ZoneID>QuickLinks</ZoneID> | |
<PartOrder>0</PartOrder> | |
<FrameState>Normal</FrameState> | |
<Height /> | |
<Width /> | |
<AllowRemove>true</AllowRemove> | |
<AllowZoneChange>true</AllowZoneChange> | |
<AllowMinimize>true</AllowMinimize> | |
<AllowConnect>true</AllowConnect> | |
<AllowEdit>true</AllowEdit> | |
<AllowHide>true</AllowHide> | |
<IsVisible>true</IsVisible> | |
<DetailLink /> | |
<HelpLink /> | |
<HelpMode>Modeless</HelpMode> | |
<Dir>Default</Dir> | |
<PartImageSmall /> | |
<MissingAssembly>Cannot import this Web Part.</MissingAssembly> | |
<PartImageLarge>/_layouts/15/images/mscontl.gif</PartImageLarge> | |
<IsIncludedFilter /> | |
<Assembly>Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly> | |
<TypeName>Microsoft.SharePoint.WebPartPages.ContentEditorWebPart</TypeName> | |
<ContentLink xmlns='http://schemas.microsoft.com/WebPart/v2/ContentEditor'>$sitesURL/Style Library/ContentEditor/CEWP_Home_UserPropertiesWP.html</ContentLink> | |
<Content xmlns='http://schemas.microsoft.com/WebPart/v2/ContentEditor' /> | |
<PartStorage xmlns='http://schemas.microsoft.com/WebPart/v2/ContentEditor' /> | |
</WebPart>" | |
try{ | |
Write-Host "Starting the Process to add the User WebPart to the Home Page" -ForegroundColor Yellow | |
#Adding the reference to the client libraries. Here I'm executing this for a SharePoint Server (and I'm referencing it from the SharePoint ISAPI directory, | |
#but we could execute it from wherever we want, only need to copy the dlls and reference the path from here | |
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll" | |
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll" | |
Write-Host "Getting the page with the webpart we are going to modify" -ForegroundColor Green | |
#Using the params, build the page url | |
$pageUrl = $sitesURL + $pageRelativeUrl | |
Write-Host "Getting the page with the webpart we are going to modify: " $pageUrl -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($pageUrl); | |
$page.CheckOut() | |
$ctx.ExecuteQuery() | |
try{ | |
#Get the webpart manager from the page, to handle the webparts | |
Write-Host "The page is checkout" -ForegroundColor Green | |
$webpartManager = $page.GetLimitedWebPartManager([Microsoft.Sharepoint.Client.WebParts.PersonalizationScope]::Shared); | |
Write-Host $WebPartXml.OuterXml | |
#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); | |
$ctx.ExecuteQuery(); | |
#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 and Publish the Page | |
Write-Host "Checkin and Publish the Page" -ForegroundColor Green | |
$page.CheckIn("Add the User Profile WebPart", [Microsoft.SharePoint.Client.CheckinType]::MajorCheckIn) | |
$page.Publish("Add the User Profile WebPart") | |
$ctx.ExecuteQuery() | |
Write-Host "The webpart has been added" -ForegroundColor Yellow | |
} | |
} | |
catch{ | |
Write-Host "Errors found:`n$_" -ForegroundColor Red | |
} | |
} | |
$tenantAdmin = "admin@josharepoint.onmicrosoft.com" | |
$tenantAdminPassword = "pass" | |
$secureAdminPassword = $(convertto-securestring $tenantAdminPassword -asplaintext -force) | |
$siteURL = "https://josharepoint.sharepoint.com/sites/jq"; | |
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) | |
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($tenantAdmin, $secureAdminPassword) | |
$ctx.Credentials = $credentials | |
###################################### | |
# Set Add WebPart to Page Parameters # | |
###################################### | |
$relUrl = "/sites/jqQAtest" | |
LogSection "Add Manual Correction WebPart to Page" | |
AddWebPartToPage $ctx $relUrl |
Good to know
While I was developing this program, I found a problem with the format of XML. Specifically this problem:
The file you imported is not valid. Verify that the file is a Web Part description file (.webpart or .dwp) and that it contains well-formed XML.
$wp = $webpartManager.ImportWebPart($WebPartXml.OuterXml)
Using PowerShell is really important consider the type of the variables we are using, in my case I was trying to ImportWebPart
using a PowerShell variable called $WebPartXml
, but the real XML object (as string) that ImportWebPart
function expects is $WebPartXml.OuterXml
.
Credits
Lot of thanks to my friend Benja for helping on that!