Set Web Part properties in loop
Add web part to the page as instance of custom class, set its properites
Script reads *.webpart file and sets properties for webpart instance in a loop. Only string, bool and int type are set, because values are casted. Other properties are skipped. Web part in example is standard ContentByQueryWebPart and is added to /Pages/default.aspx page.
Add-PSSnapin microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
function TextToBool([string]$text)
{
$result = $false
if($text)
{
switch($text.ToLower())
{
"true" { $result = $true; break }
"1" { $result = $true; break }
"false" { $result = $false; break }
"0" { $result = $false; break }
}
}
return $result
}
function CastPropertyValue([string]$type, [string]$value)
{
if($type -eq "string")
{
return $value
}
elseif($type -eq "bool")
{
return (TextToBool $value)
}
elseif($type -eq "int")
{
return [int]::Parse($value)
}
else
{
return $null
}
}
#settings
$webUrl = "https://yoursitecollection"
$pageRelativeUrl = "/Pages/default.aspx"
$wpTitle = "My Content Query web part"
$LocalWebPartPath = "C:\temp\Content Query.webpart"
$ZoneName = "MainWPZ"
$ZoneIndex = 1
$AssemblyName = "Microsoft.SharePoint.Publishing"
$FullWpTypeName = "Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart"
#code
$pageFullUrl = $webUrl + $pageRelativeUrl
#first you have to check out the file/page, if publishing/versioning is disabled, then you can skip this step
$web = Get-SPWeb -identity $webUrl
$file = $web.GetFile($pageRelativeUrl)
$web.AllowUnsafeUpdates = $true
if ($file.Level -ne [Microsoft.SharePoint.SPFileLevel]::Checkout)
{
write-host " Checking-out page" $pageRelativeUrl
$file.CheckOut()
}
#initialize the webpart-manager and locate it to the page
$webpartmanager = $web.GetLimitedWebPartManager($pageFullUrl, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
#Define context, it's needed for setting properties
if ($null -eq [System.Web.HttpContext]::Current)
{
$sw = New-Object System.IO.StringWriter
$resp = New-Object System.Web.HttpResponse $sw
$req = New-Object System.Web.HttpRequest "", $Web.Url, ""
$htc = New-Object System.Web.HttpContext $req, $resp
#explicitly cast $web to spweb object else sharepoint will
#see it as a PSObject, and AddWebpart wil fail
$htc.Items["HttpHandlerSPWeb"] = $Web -as [Microsoft.SharePoint.SPweb]
[System.Web.HttpContext]::Current = $htc
if ($sw -ne $null)
{
$sw.Dispose()
}
}
#Load your custom assembly
[void][reflection.assembly]::LoadWithPartialName($AssemblyName)
try
{
#Create web part instance
$webpart = new-object $FullWpTypeName
#Load properties from *.webpart file and use them for webpart
$xml = [xml](Get-Content -Path $LocalWebPartPath)
$wpProperties = $xml.Webparts.webpart.data.properties.property
#Continue with setting correct properties, skip wrong
$ErrorActionPreference = "Continue"
foreach($property in $wpProperties)
{
Write-Host $property.Name ": " $property.InnerText
try
{
$prop = $webpart.GetType().GetProperty($property.Name)
$propertyValue = CastPropertyValue $property.type $property.InnerText
if($propertyValue)
{
$prop.SetValue($webpart, $propertyValue, $null)
}
else
{
Write-Host "Property " $property.Name " was not set." -ForegroundColor Red
}
}
catch
{
Write-Error $_
}
}
$ErrorActionPreference = "Stop"
#Overwrite web part title with value from Xml
$webpart.Title = $wpTitle
#the code in the brakets adds the $webpart to the mentioned zone and sets the sorting of the webpart on the first place
$webpartmanager.AddWebPart($webpart, $ZoneName,$ZoneIndex);
$webpartmanager.SaveChanges($webpart)
$web.Update()
Write-Host "Web part '$FullWpTypeName' succesfuly added to " $pageRelativeUrl
}
catch
{
Write-Error $_.exception
}
$file.CheckIn("Checkin",[Microsoft.SharePoint.SPCheckInType]::MajorCheckin)
if($web -ne $null){
$web.Dispose()
}