Finding CEWP’s with script in your SharePoint sites

One of the most annoying things I regularly encounter is undocumented environments. Nothing freaks me out more than this.

For instance, last week, I stumbled onto a search results page which didn’t work anymore. Seems that once upon a time, someone added a content editor webpart with some javascript on there. That javascript called a webservice and this failed.

If I didn’t have the reflex of putting that page in edit mode, I would never have guessed this. This lead me to the creation of the following… a PowerShell script which identifies all pages, forms and views for a webapplication which has:

  • a CEWP with the <script> tag
  • a CEWP with a contentlink that points to a textfile wich has the <script> tag

This way, I don’t have to go fish for these things if people are too damn lazy to create some documentation.

<#
.SYNOPSIS
   Returns a list of pages for a specific webapplication which contain CEWP's with script.
	
.DESCRIPTION
   Returns a list of pages for a specific webapplication which contain CEWP's with script.
	
.NOTES
   File Name: Get-CEWPWithScript.ps1
   Version  : 1.0
	
.PARAMETER WebApplication
   Specifies the URL of the Web Application.
	
.EXAMPLE
   PS > .\Get-CEWPWithScript.ps1 -WebApplication http://intranet.westeros.local

   Description
   -----------
   Returns all Content Editor Web Parts which contains Javascript on the http://intranet.westeros.local webapplication
#>
[CmdletBinding()]
param(
   [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$false,HelpMessage="Specifies the URL of the Web Application.")] 
   [string]$WebApplication
)

function Get-CEWP([string]$url)
{
   $manager = $web.GetLimitedWebPartManager($url, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
   $webParts = $manager.WebParts
   if ($webParts.Count -ne 0)
   {
      foreach ($webPart in $webParts)
      {
         if ($webPart.GetType() -eq [Microsoft.SharePoint.WebPartPages.ContentEditorWebPart])
         {
            if ($webPart.ContentLink.Length -gt 0)
            {
               # Check file in ContentLink for script tags
               $file = $web.GetFile($webPart.ContentLink)
               $data = $file.OpenBinary()
               $encode = New-Object System.Text.ASCIIEncoding
               $contents = $encode.GetString($data)
               if ($contents.ToLower().Contains("<script>"))
               {
                   Write-Output "$($web.Url)/$url (CONTENTLINK)"
               }
               break
            }

            if ($webPart.Content.InnerText.Contains("<script>"))
            {
               Write-Output "$($web.Url)/$url (HTML)"
            }
         }
      }
   }
}

# Load the SharePoint PowerShell snapin if needed
if ((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
{
   Write-Host "Loading the SharePoint PowerShell snapin..."
   Add-PSSnapin Microsoft.SharePoint.PowerShell
}	
	
$SPWebApp = Get-SPWebApplication $WebApplication -EA SilentlyContinue
if ($SPWebApp -eq $null)
{
   Write-Error "$WebApplication is not a valid SharePoint Web application. Aborting execution!"
}
else
{
   Write-Host -ForegroundColor Green "Please wait... gathering data."
   $sites = $SPWebApp.Sites
   foreach ($site in $sites)
   {
      try
      {
         $webs = $site.AllWebs
         foreach ($web in $webs)
         {
            try
            {
               # For publishingwebs, check all publishingpages
               if ([Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($web))
               {
                  $pubweb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
                  $pages = $pubweb.GetPublishingPages()
                  foreach($page in $pages)
                  {
                     Get-CEWP -url $page.Url
                  }
               }
                    
               # Libraries and lists have views and forms which can contain webparts... let's get them also
               $lists = $web.GetListsOfType("DocumentLibrary") | ? {$_.IsCatalog -eq $false}
               foreach ($list in $lists)
               {
                  # Check the views
                  $views = $list.Views
                  foreach ($view in $views)
                  {
                     Get-CEWP -url $view.Url
                  }
                        
                  # Check the forms
                  $forms = $list.Forms
                  foreach ($form in $forms)
                  {
                     Get-CEWP -url $form.Url
                  }
               }
            }
            catch {}
            finally { $web.Dispose() }		
         }
      }
      catch {}
      finally { $site.Dispose() }
   }
}

By Bart

Bart is a certified SharePoint consultant / architect at CTG Belgium NV with a broad professional experience in IT, a background in software development with a specialisation in Microsoft products and technologies and a solid knowledge and experience in Microsoft SharePoint Products and Technologies. He started as a COBOL developer on a mainframe environment and grew into software development for Windows platforms. Participated in projects varying from migrations of existing applications to development of Web applications and Windows applications. Became fascinated by the SharePoint 2007 platform and strongly believed in the added business value of this platform. Is since then fully committed to SharePoint and focuses on SharePoint implementations, migrations, integrations, design and coaching. Stays on top of new developments within the SharePoint technology stack and related technologies.