If you are interested in the use of these types of PowerShell scripts to explore and audit SharePoint then you may want to attend my “Exploring and Auditing SharePoint Using PowerShell” session at SharePoint Saturday Dayton this Saturday.
There’s a question in the MSDN SharePoint forums about how to update Content Editor Web Parts in hundreds of web part pages. These web parts had URLs that pointed to a server that had been renamed, and to fix the URLs meant updating all of these Content Editor Web Parts.
I had recently written a little script to find all of the Content Editor Web Parts in a farm that had a certain piece of text. It only took a small edit to add some code to find and replace text. I have posted the script here instead of the forums as I plan to return here to clean up the code a bit and add more comments.
As this script will change, and possibly break, your Content Editor Web Parts… what's below is provided with no warranties and is up to you to test to confirm that it is safe!
Steps:
- Paste the following into a NotePad file and save as CEWPsearchandreplace.ps1 (or any name you like)
- Edit these two lines with your before and after text:
$textToFind = "theBeforeText"
$newText = "theAfterText"
- Start the SharePoint 2010 Management Shell and type:
. c:\whereyousavedit\CEWPsearchandreplace.ps1
Note the dot and the space before the C:
Note that you will need appropriate PowerShell and SharePoint permissions to run this script. See here for more info on permissions: http://techtrainingnotes.blogspot.com/2011/08/searching-and-auditing-sharepoint-with.html
Code Notes:
- The code creates three functions:
Get-SPWebPartsForWeb yourURL (for a single site)"
Get-SPWebPartsForSite yourURL (for all sites in a site collection)"
Get-SPWebPartsForApplication yourURL (for all site collections in an app)"
- The code only checks for web part pages in selected libraries: "Site Pages","SitePages","Pages"
You can edit the $librariesToCheck variable to add more locations
- The code also checks the default.aspx page in the site root if $checkrootdefaultaspx = $true
- There are a number of commented out “Write-Host” lines that you can uncomment for debugging purposes.
The code:
"Find and Update Content Editor Web Parts loaded..." "Run using:" " Get-SPWebPartsForWeb yourURL (for a single site)" " Get-SPWebPartsForSite yourURL (for all sites in a site collection)" " Get-SPWebPartsForApplication yourURL (for all site collections in an app)" # Change these two variables $textToFind = "theBeforeText" $newText = "theAfterText" $librariesToCheck = "Site Pages","SitePages","Pages" $checkrootdefaultaspx = $true function Check-Page($page) { # borrow a .NET method GetExtension if ([system.io.path]::GetExtension($page.url).ToLower() -ne ".aspx") { continue #not a webpart page, so back to the foreach } # try and get the WebPartManager for the page $wpm = $null try { $wpm = $page.GetLimitedWebPartManager([System.Web.UI.WebControls.Webparts.PersonalizationScope]::Shared) #" Webparts: " + $wpm.webparts.count } catch { #" Not a web part page" } if ($wpm -ne $null) # then we have a webpart page { Write-Host " Page: " $page.Url # report each web part found foreach ($webpart in $wpm.webparts) { Write-Host " Web part: " $webpart.WebBrowsableObject.ToString().Replace("Microsoft.SharePoint.","") -foregroundcolor blue Write-Host " Title: " $webpart.Title if ( $webpart.WebBrowsableObject.ToString() -eq "Microsoft.SharePoint.WebPartPages.ContentEditorWebPart" ) { # if there's linked content then open and search for the script tag if ($webpart.contentlink.length -gt 0 ) { $file = $w.GetFile($webpart.contentlink) $b = $file.OpenBinary() $encoding=new-object "System.Text.UTF7Encoding" if ($encoding.GetString($b).toLower() -match "<script") { Write-Host " contentlink: HAS <SCRIPT>" $webpart.contentlink -foregroundcolor red } Remove-Variable b } # else report what's in the content elseif ($webpart.content."#cdata-section".tolower() -match "<script") { Write-Host " content: HAS <SCRIPT>" -foregroundcolor red # write-host $webpart.content."#cdata-section" -foregroundcolor green $xmlDoc = New-Object -TypeName xml $xmlElement = $xmlDoc.CreateElement("MyElement"); # THIS IS WHERE THE REPLACE IS DONE. $xmlElement.InnerText = $webpart.Content.InnerText.Replace($textToFind, $newText); $webpart.content = $xmlElement $wpm.savechanges($webpart) } } } } } filter Get-WebPartPages { # this filter accepts a SPWeb and returns SPPages from target libraries # write-host "getting webparts" $w = $_ #Write-Host "" #Write-Host "Web: " $w.ServerRelativeUrl #-foregroundcolor yellow if ($checkrootdefaultaspx) { #Write-Host " Root: default.aspx" foreach ($file in $w.files) { if ($file.url -eq "default.aspx") { $file } } } # Write-Host "now for lists..................." $w.lists.count foreach ($list in $w.Lists) { #Write-Host " List: " $list.title $librariesToCheck $("'" + $list.title + "'") if ( $librariesToCheck -like "*'$($list.title)'*" ) { #Write-Host "File name " -ForegroundColor red foreach ($item in $list.items) { #Write-Host "File name " $item.file.url -ForegroundColor red $page = $item.file $page } } } } function Check-WebParts($w) { Write-Host "" Write-Host "Web: " $w.ServerRelativeUrl -foregroundcolor yellow if ($checkrootdefaultaspx) { Write-Host " Root: " foreach ($file in $w.files) { if ($file.url -eq "default.aspx") { Check-Page($file) } } } foreach ($list in $w.Lists) { Write-Host ("'" + $list.title + "'") if ( $librariesToCheck -contains $list.title ) { write-host $list.title foreach ($item in $list.items) { $page = $item.file Check-Page($page) } } } } Function Get-SPWebPartsForWeb($url) { $web = Get-SPWeb($url) Check-WebParts($web) $web.Dispose() } Function Get-SPWebPartsForSite($url) { $site = Get-SPSite($url) foreach($web in $site.AllWebs) { Check-WebParts($web) $web.Dispose() } $site.Dispose() } Function Get-SPWebPartsForApplication($url) { $app = Get-SPWebApplication($url) foreach ($site in $app.sites) { foreach($web in $site.AllWebs) { Check-WebParts($web) $web.Dispose() } $site.Dispose() } }
.