SharePoint: Adding WebPart on Pages Using PowerShell Script

One of the requirements of our project was to replace the existing web part from our production site which was causing many problems with performance. This web part was available in multiple content pages. So one of the options available to us was to write a PowerShell script to add a new web part to multiple content pages.

The following describes how to add a web part to a SharePoint page using a PowerShell script.

  • To add the web part we will require a web part definition file to be available on the file system so that we can add it to the webpart gallery, import it, and add it using the WebPartManager class.
  • Now, consider we need to add the web part to the MyWPPage.aspx page from the page library of the web MyWeb.
  • We need to get a publishing web instance from the web instance and set the allow unsafe updates to true as follows.
    $webURL = "http://MyWeb.com"
    $web = Get-SPWeb $webURL
    
  • Get the publishing web instance and set the allow unsafe update property to true.
    [Microsoft.SharePoint.Publishing.PublishingWeb]$pubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
    $allowunsafeupdates = $web.AllowUnsafeUpdates
    $web.AllowUnsafeUpdates = $true
    
  • Get the pages library and find the list item as follows.
    $list = $web.Lists[$pagesLibrary]
    foreach ($listItem in $list.Items) {
        if ($listItem.URL.Contains("MyWPPage.aspx")) {
            $myListItem = $listItem
            break
        }
    }
    
  • Get the file from listitem, check that if this page is checked out to another user or the same user and if the same user then publish and then check out the page.
    $page = $web.GetFile($listitem.URL)
    if ($page.CheckOutStatus -ne "None") {
        # Check to ensure the page is checked out by the same user, and if so, check it in
        if ($page.CheckedOutBy.UserLogin -eq $web.CurrentUser.UserLogin) {
            $page.CheckIn("Page checked in automatically by PowerShell script")
            Write-Output "$($page.Title) ($($page.Name)) has been checked in"
        }
    }
    if ($page.CheckOutStatus -eq "None") {
        $page.CheckOut()
        # Get the webpart manager
        $webpartmanager = $web.GetLimitedWebPartManager($page.URL, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
    }
    
  • Now from the local file system, get the file stream and import it using the webpart manager as follows.
    $saveFolder = "C:\webpart\"
    $webpartfile = "MyWebPart.webpart"
    $fileDWP = $saveFolder + $webpartfile
    write-output "DWP File" $fileDWP
    
    # Getting the webpart gallery
    [Microsoft.SharePoint.SPList]$wpList = $web.Site.GetCatalog([Microsoft.SharePoint.SPListTemplateType]::WebPartCatalog)
    $fileStream = ([System.IO.FileInfo](Get-Item $fileDWP)).OpenRead()
    [Microsoft.SharePoint.SPFolder]$wpFolder = $wpList.RootFolder
    [Microsoft.SharePoint.SPFile]$wpFile = $wpFolder.Files.Add($webpartfile, $fileStream, $true)
    Write-host $wpFile
    
    [System.Xml.XmlReader]$xmlReader = [System.Xml.XmlReader]::Create($wpFile.OpenBinaryStream())
    
    # Import the webpart
    $myCustomWP = $webpartmanager.ImportWebPart($xmlReader, [ref]$errorMsg)
    Write-Output "My custom WebPart" $myCustomWP.title
    
    # If this webpart is not available on page then add it
    if (-not $webpartmanager.WebParts.Contains($myCustomWP)) {
        $webpartmanager.AddWebPart($myCustomWP, $wpZoneId, $wpOrder)
    }
    
  • Finally, Check in the page and clean up the instances.
    $page.CheckIn("Page checked in automatically by PowerShell script")
    $page.Publish("Page published, new webpart added")
    $web.AllowUnsafeUpdates = $allowunsafeupdates
    $xmlReader.Close()
    $pubWeb.Close()
    $web.Dispose()
    

Thanks!