Friday, November 29, 2013

PowerShell script for fixing urls inside Content editor and Image viewer web parts in Sharepoint

Sometimes it may be needed to fix urls added by content editors in web parts (in this article we will consider ContentEditorWebPart and ImageWebPart, but you can extend the script for your own needs as you will need), e.g. when content was created on the test environment and then migrated to production. The following PowerShell script will do it automatically:

   1:  
   2: function Fix-String($val)
   3: {
   4:     return $val.Replace($oldUrl, $newUrl)
   5: }
   6:  
   7: function Should-Fix-String($val)
   8: {
   9:     if (-not $val -or -not $val.Contains($oldUrl))
  10:     {
  11:         return $false
  12:     }
  13:     return $true
  14: }
  15:  
  16: function Fix-Page-Field($item, $fieldName)
  17: {
  18:     Write-Host "Check field $fieldName" -foregroundcolor green
  19:     $val = $item[$fieldName]
  20:     if (-not $val)
  21:     {
  22:         Write-Host "Field value is empty" -foregroundcolor green
  23:         return
  24:     }
  25:  
  26:     $src = ""
  27:     if ($val.GetType().Name -eq "ImageFieldValue")
  28:     {
  29:         $src = $val.ImageUrl
  30:     }
  31:     else
  32:     {
  33:         $src = $val
  34:     }
  35:  
  36:     $shouldFix = Should-Fix-String $src
  37:     if (-not $shouldFix)
  38:     {
  39:         Write-Host "Field value doesn't have links which should be fixed" -foregroundcolor green
  40:         return
  41:     }
  42:  
  43:     $src = Fix-String $src
  44:     if ($val.GetType().Name -eq "ImageFieldValue")
  45:     {
  46:         $val.ImageUrl = $src
  47:         $item[$fieldName] = $val
  48:     }
  49:     else
  50:     {
  51:         $item[$fieldName] = $src
  52:     }
  53:     Write-Host "Field value was sucessfully fixed" -foregroundcolor green
  54: }
  55:  
  56: function Fix-Web-Part($wp, $webPartManager)
  57: {
  58:     Write-Host "Check links in web part" $wp.Title -foregroundcolor green
  59:     $src = ""
  60:     if ($wp.GetType().Name -eq "ContentEditorWebPart")
  61:     {
  62:         $src = $wp.Content.InnerText
  63:     }
  64:     elseif ($wp.GetType().Name -eq "ImageWebPart")
  65:     {
  66:         $src = $wp.ImageLink
  67:     }
  68:     else
  69:     {
  70:         Write-Host "Web part type" $wp.GetType().Name "is not supported" -foregroundcolor yellow
  71:     }
  72:  
  73:     $shouldFix = Should-Fix-String $src
  74:     if (-not $shouldFix)
  75:     {
  76:         Write-Host "Web part content doesn't have links which should be fixed" -foregroundcolor green
  77:         return
  78:     }
  79:  
  80:     $src = Fix-String $src
  81:     if ($wp.GetType().Name -eq "ContentEditorWebPart")
  82:     {
  83:         $content = $wp.Content
  84:         $content.InnerText = $src
  85:         $wp.Content = $content
  86:         $webPartManager.SaveChanges($wp)
  87:     }
  88:     elseif ($wp.GetType().Name -eq "ImageWebPart")
  89:     {
  90:         $wp.ImageLink = $src
  91:         $webPartManager.SaveChanges($wp)
  92:     }
  93:     Write-Host "Web part content was successfully fixed" -foregroundcolor green
  94: }
  95:  
  96: function Fix-Page($item)
  97: {
  98:     $file = $item.File
  99:     Write-Host "Check links on page" $file.Url -foregroundcolor green
 100:  
 101:     $shouldBePublished = $false
 102:     if ($file.Level -eq [Microsoft.SharePoint.SPFileLevel]::Published)
 103:     {
 104:         $shouldBePublished = $true
 105:     }
 106:  
 107:     if ($file.CheckOutType -ne [Microsoft.SharePoint.SPFile+SPCheckOutType]::None)
 108:     {
 109:        Write-Host "Undo checkout for page" $file.Url -foregroundcolor yellow
 110:        $file.UndoCheckOut()
 111:     }
 112:     $file.CheckOut()
 113:  
 114:     # check field value first
 115:     Fix-Page-Field $item "PublishingPageContent"
 116:  
 117:     # then content inside web parts
 118:     $webPartManager = $file.Web.GetLimitedWebPartManager($file.Url,
 119: [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
 120:     $webParts = @()
 121:     foreach ($wp in $webPartManager.WebParts)
 122:     {
 123:         Write-Host "Found web part" $wp.GetType().Name
 124:         if ($wp.GetType().Name -eq "ContentEditorWebPart" -or
 125: $wp.GetType().Name -eq "ImageWebPart")
 126:         {
 127:             $webParts += $wp
 128:         }
 129:     }
 130:  
 131:     if ($webParts.Count -eq 0)
 132:     {
 133:         return
 134:     }
 135:  
 136:     $webParts | ForEach-Object { Fix-Web-Part $_ $webPartManager }
 137:  
 138:     Write-Host "Update and checkin page" $file.Url -foregroundcolor green
 139:     $item.Update()
 140:     $file.Update()
 141:     $file.CheckIn("Change links.")
 142:     if ($shouldBePublished)
 143:     {
 144:         Write-Host "Publish page" $file.Url -foregroundcolor green
 145:         $file.Publish("Change links.")
 146:         if ($file.DocumentLibrary.EnableModeration)
 147:         {
 148:             $file.Approve("System Approve - change links.")
 149:         }
 150:     }
 151: }
 152:  
 153: function Fix-Links-On-Web($w)
 154: {
 155:     Write-Host "Check links on web" $w.Url -foregroundcolor green
 156:     $pw = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($w)
 157:     $pagesList = $pw.PagesList
 158:     $pagesList.Items | ForEach-Object { Fix-Page $_ }
 159: }
 160:  
 161: function Fix-Links-On-Site($s)
 162: {
 163:     Write-Host "Check links on site" $s.Url -foregroundcolor green
 164:     $s.AllWebs | ForEach-Object { Fix-Links-On-Web $_ }
 165: }
 166:  
 167: Start-Transcript -Path "output.log" -Append -Force -Confirm:$false
 168: $oldUrl = "/example1.com/"
 169: $newUrl = "/example2.com/"
 170: $webApp = Get-SPWebApplication "http://example.com"
 171: $webApp.Sites | ForEach-Object { Fix-Links-On-Site $_ }
 172: Stop-Transcript

Script enumerates through all site collections, sites, pages and web parts, finds all ContentEditorWebPart and ImageWebPart on the pages and then changes old url (stored in $oldUrl variable) on new url ($newUrl). Also it fixes links inside standard PublishingPageContent field of the publishing pages.

As I wrote you can easily extend it for changing web parts of other types. Hope that it will helpful.

2 comments:

  1. can you post a plaintext copy of this script? site formatting breaks it when you copy/paste.

    ReplyDelete
  2. wyefye,
    paste it to VS, then replace using regexp "\d: " to empty string

    ReplyDelete