Broken Images After My Site URL Change in SharePoint 2007

When you setup a My Site picture, the URL to the image is stored in your profile under the Picture property.  You can either upload an image into your My Site, or you can type in the URL to an image.  Since the property, by default, has the replicable property set in the SSP, the Profile Synchronization timer job pushes the image URL down to the Site Collections’s User Information list.  The problem is that it does this using the default zone Alternate Access Mapping of the My Site web application as an absolute URL.  You can see the super secret User Information list by adding /_catalogs/users to the end of a Site collection URL.

This works out really well, as long as the default zone URL to the My Site web application doesn’t change.  Once you change your My Site URL, you’ll start seeing broken images anywhere an image should be displayed in a sync’ed up Site Collection.  Something like the following :

image

The profile sync will not push down profile information for a user unless their profile changes, which likely won’t happen for a long period of time for most users.  For users that still have active profiles, you can do the following to force the Profile Synchronization timer job to push the current information down to the site collections:

StsAdm.exe –o Sync –DeleteOldDatabases 0

The timer job runs hourly, so you could wait for the job to run, or run the following to have the job run within the next 5 minutes :

StsAdm.exe –o Sync –SyncTiming M:5

If you make this change, I would recommend setting it back to hourly after the job completes :

StsAdm.exe –o Sync –SyncTiming H:1

What about those users that were added to content, then had their profile flagged as inactive?  Well, those user’s images would still show up as broken links.  The only way to update these is via the object model. 

Here’s some PowerShell script to update those entries.  Save the script as FixUserInfoPicUrl.ps1.  Run the script on a box in the SharePoint farm with no parameters to get a tab delimited list of User Info entries that have a Picture URL specified.  You can then set the old and new url entries in the script file, pass in $true as the parameter to fix up the URLs.  As always, test and validate this type of change somewhere before running it in a production environment.

Ex.  Build a report of users with a picture URL  :  FixUserInfoPicUrl.ps1

Update URLs  :  FixUserInfoPicUrl.ps1 $true

    1: param([bool]$fix)
    2:  
    3:  
    4: #Load DLLs
    5: [System.Reflection.Assembly]::Load("Microsoft.SharePoint, version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null
    6:  
    7: $contentservice = [Microsoft.SharePoint.Administration.SPWebService]::ContentService.WebApplications
    8: $webapp = new-object Microsoft.SharePoint.Administration.SPWebApplication
    9:  
   10:  
   11: write-output "Site Collection URL`tUser`tPicture URL"
   12:  
   13: foreach($webapp in $contentservice)
   14: {
   15:     foreach($spsite in $webapp.sites)
   16:     {        
   17:         $list = $spsite.RootWeb.SiteUserInfoList
   18:  
   19:         $query = new-object Microsoft.SharePoint.SPQuery
   20:         $query.Query = "<Where><BeginsWith><FieldRef Name='Picture'/><Value Type='URL'>https://oldurl</Value></BeginsWith></Where>"
   21:  
   22:  
   23:         foreach($item in $list.GetItems($query))
   24:         {
   25:             write-output (($spsite.Url) + "`t" + ($item.Title) + "`t" + ($item["Picture"]))
   26:  
   27:             if($fix)
   28:             {
   29:                 $item["Picture"] = $item["Picture"].ToString().Replace("https://oldurl", "https://newurl")
   30:                 $item.Update()
   31:             }
   32:         }
   33:     
   34:         $spsite.Dispose()
   35:     }
   36: }
   37:  
   38:  
   39: Write-Output("`r`n`r`nProcessing Complete`r`n`r`n")