Friday, 15 November 2013

Add Custom Web Parts to a page and Connect them using PowerShell


These days I am working heavily on SharePoint CSOM and BCS (Business Connectivity Services). I have created a sandbox package with multiple custom business data and html form data web parts.

The reason why I am writing this blog is to share with you some of the cool stuffs I did with PowerShell in the project.

I have written many automation scripts to create web part page, add web parts to this page and then connect to them on a single click using PowerShell.

First thing first…

1.       Create a web part page using PowerShell:

Function CreateWebPartPage
{
param($title,$name,$pageLayout)
Write-Host "***************Creating Web part page: "$title -ForegroundColor Yellow
if([Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($web)){
$pubWeb =[Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
$name+=".aspx";
$layout = $pubWeb.GetAvailablePageLayouts() | Where { $_.Name -eq $pageLayout}
$newPage = $pubWeb.AddPublishingPage($name, $layout);
$newPage.Title=$title;
$newPage.Update()
Write-Host "***************Page is created successfully" -ForegroundColor Yellow
}
Else{
Write-Host "***************Not a publishing web" -ForegroundColor Yellow
}}
$Url = $(Read-Host -Prompt "Enter site url:")
$web = Get-SPWeb $Url
CreateWebPartPage "Test Page" "Test" "BlankWebPartPage.aspx"
$web.Dispose();


2.       Add web part to this page:

$Url = $(Read-Host -Prompt "Enter site url:")
$web = Get-SPWeb $Url
$web.AllowUnsafeUpdates=$true
function Add-WebPartToPage($pageUrl, $webpartzone,$index,$fileName)
{
$webPartGallery = $web.Lists["Web Part Gallery"]
Write-Host "Searching webpart $fileName in web part gallery" -ForegroundColor Yellow
if($webPartGallery -eq $null)
{
Write-Host("Unable to retrieve Webpartgallery");
}
$webpart = $null;
$webpart=$webPartGallery.Items | ? { $_.Title -eq $fileName}
if($webpart -eq $null) {
Write-Host("Unable to retrieve webpart: $fileName") -ForegroundColor Red
}
else {
Write-Host("----------Adding Webpart--------")-ForegroundColor Yellow
$webpartmanager=$web.GetLimitedWebPartManager($pageUrl, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
$errorMsg = "";
$xmlReader = New-Object System.Xml.XmlTextReader($webpart.File.OpenBinaryStream());
$webpart = $webpartmanager.ImportWebPart($xmlReader,[ref]"Error")
$webpartmanager.AddWebPart($webpart, $webpartzone, $index);
Write-Host("Webpart is added successfully") -ForegroundColor Green ;
}
}
$SiteURL =$Url
#---------------Test Page----------------------------
$PageName="Test.aspx"
$page=$web.lists["Pages"].Items | ? {$_.Name -eq $PageName}
$page.File.CheckOut();
Add-WebPartToPage "$SiteURL/Pages/$PageName" "Header" 0 "My Custom WebPart"
$page.File.CheckIn("Added Web part to a page");
$page.File.Approve("Added Web part to a page");


3.       Connect web parts in a page: In this script I have shown how we can connect

a.       Query String filter Web Part with Business Data List Web Part

b.      Query String filter Web Part with Business Data Item Web Part

c.       Business data List Web Part with Business Data Item Builder Web Part

 

function Connect-QueryStringFilterWP-To-BCSListWP($pageUrl,$fileName,$providerWP,$consumerArrayValue,$providerArrayValue,$consumerConnectionId)
{
$webPartGallery = $web.Lists["Web Part Gallery"]
$webpartmanager=$web.GetLimitedWebPartManager($pageUrl, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
Write-Host "Searching Consumer webpart $fileName in web part gallery" -ForegroundColor Yellow
if($webPartGallery -eq $null)
{
Write-Host("Unable to retrieve Webpartgallery");
}
$webPartConsumer = $webpartmanager.WebParts | Where {$_.Title -eq $fileName}
Write-Host "Searching Consumer webpart $providerWP in web part gallery" -ForegroundColor Yellow
$webPartProvider = $webpartmanager.WebParts | Where {$_.Title -eq $providerWP}
$conWP = $webpartmanager.GetConsumerConnectionPoints($webPartConsumer)
$provWP = $webpartmanager.GetProviderConnectionPoints($webPartProvider)
$conWP=$conWP[$consumerConnectionId]
$provWP=$provWP["ITransformableFilterValues"]
$trans = New-Object Microsoft.SharePoint.WebPartPages.TransformableFilterValuesToParametersTransformer
$consumerArray=@($consumerArrayValue)
$providerArray=@($providerArrayValue)
$trans.ProviderFieldNames=$providerArray
$trans.ConsumerFieldNames=$consumerArray
$newCon = $webpartmanager.SPConnectWebParts($webPartProvider,$provWP,$webPartConsumer,$conWP,$trans)
$webpartmanager.SPWebPartConnections.Add($newCon);
$webpartmanager.Dispose()
Write-Host "Webparts are connected successfully" -ForegroundColor Green
}
function Connect-QueryStringFilterWP-To-BCSListItemWP($pageUrl,$fileName,$providerWP,$consumerConnectionId)
{
$webPartGallery = $web.Lists["Web Part Gallery"]
$webpartmanager=$web.GetLimitedWebPartManager($pageUrl, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
Write-Host "Searching Consumer webpart $fileName in web part gallery" -ForegroundColor Yellow
if($webPartGallery -eq $null)
{
Write-Host("Unable to retrieve Webpartgallery");
}
$webPartConsumer = $webpartmanager.WebParts | Where {$_.Title -eq $fileName}
Write-Host "Searching Consumer webpart $providerWP in web part gallery" -ForegroundColor Yellow
$webPartProvider = $webpartmanager.WebParts | Where {$_.Title -eq $providerWP}
$conWP = $webpartmanager.GetConsumerConnectionPoints($webPartConsumer)
$provWP = $webpartmanager.GetProviderConnectionPoints($webPartProvider)
$conWP=$conWP[$consumerConnectionId]
$provWP=$provWP["ITransformableFilterValues"]
$trans = New-Object Microsoft.SharePoint.Portal.WebControls.TransformableFilterValuesToEntityInstanceTransformer
$newCon = $webpartmanager.SPConnectWebParts($webPartProvider,$provWP,$webPartConsumer,$conWP,$trans)
$webpartmanager.SPWebPartConnections.Add($newCon);
$webpartmanager.Dispose()
Write-Host "Webparts are connected successfully" -ForegroundColor Green
}
function Connect-BCSWebParts($pageUrl,$fileName,$providerWP){
$webPartGallery = $web.Lists["Web Part Gallery"]
$webpartmanager=$web.GetLimitedWebPartManager($pageUrl, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
Write-Host "Searching Consumer webpart $fileName in web part gallery" -ForegroundColor Yellow
if($webPartGallery -eq $null)
{
Write-Host("Unable to retrieve Webpartgallery");
}
$webPartConsumer = $webpartmanager.WebParts | Where {$_.Title -eq $fileName}
Write-Host "Searching Consumer webpart $providerWP in web part gallery" -ForegroundColor Yellow
$webPartProvider = $webpartmanager.WebParts | Where {$_.Title -eq $providerWP}
$conWP = $webpartmanager.GetConsumerConnectionPoints($webPartConsumer)[0]
$provWP = $webpartmanager.GetProviderConnectionPoints($webPartProvider)[0]
$newCon = $webpartmanager.SPConnectWebParts($webPartProvider,$provWP,$webPartConsumer,$conWP)
$webpartmanager.SPWebPartConnections.Add($newCon);
$webpartmanager.Dispose()
Write-Host "Webparts are connected successfully" -ForegroundColor Green
}
function setupPageConnections ($pageName) {
Write-Host "Connecting webparts for page: $pageName" -ForegroundColor Yellow
$page=$web.lists[$LibName].Items | ? {$_.Name -eq $PageName}
$page.File.CheckOut();
setupWebPartsConnections $pageName
$page.File.CheckIn("Webparts are connected");
$page.File.Approve("Webparts are connected");
}
function setupWebPartsConnections ($pageName) {
Connect-BCSWebParts "$SiteURL/$LibName/$PageName" "{Custom Webpart Title}" "Business Data Item Builder" #{Custom Webpart Title} with title of custom web part
Connect-QueryStringFilterWP-To-BCSListWP "$SiteURL/$LibName/$PageName" "My Custom WebPart" "{Query String Filter WebPart tilte}" "{Custom Webpart filter Name}" "QueryString" "BDWP Query Values"
Connect-QueryStringFilterWP-To-BCSListItemWP "$SiteURL/$LibName/$PageName" "{Custom Webpart Title}" "{Query String Filter WebPart tilte}" "BDWP Item"
}
$Url = $(Read-Host -Prompt "Enter site url:")
$web = Get-SPWeb $Url
$web.AllowUnsafeUpdates=$true
$LibName = "Pages";
$SiteURL =$Url
setupPageConnections "Test.aspx"
$web.Update();
$web.AllowUnsafeUpdates=$false
$web.Dispose()


Have Fun!

Isha Jain

4 comments:

  1. Thank you so much. Your article provide the most accessible answer and exemples that I found on the topic "How to connect sharepoint webpart view and webpart filter using powershell". Especially to correct the bug 'The provider connection point "default value" son "g_guid" and the transformer are not using the same connection interface'.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Thanks for sharing! I was inspired by your post to create one myself :-)

    Connect SharePoint Web Parts programatically with PowerShell

    ReplyDelete