Friday 7 September 2012

Profile photos not synchronising from SharePoint to Active Directory

Our scenario: I had setup SharePoint to export users profile photos into Active Directory (thumbnailPhoto attribute). Permissions are set correctly (the initial synchronisation removed all of the current photos in Active Directory and even replaced them with sweet nothing).

There were no errors in the FIIM logs or ULS logs, it just didn't appear to be able to synchronise the photos. The photos were formatted correctly, 96x96 pixels and under 10Kb, so within recommendations, but still not joy.

I thought that photos weren't synchronising across the board, but when I expanded some large distribution lists in Outlook, I noticed that there were a few users with photos that had synchronised. I'd read various posts about pictures not synchronising, including problems people were (are) having trouble with images that had CYMK colour profiles. I compared several of the profile pictures I'd found to be working (synchronising) with those that weren't, but couldn't find any conclusive differences.

Rolling up my sleaves, I decided to break out some PowerShell and start looking at the PictureURL property for a cross section of SharePoint profiles, and I found something interesting. Almost all of the profiles I looked at had '%20' in place of the space character (for the PictureURL property).


Closer investigation revealed that only the SharePoint user profiles without '%20' in the pictureURL property had their picture synchronised into Active Directory (a whole 6 of them).

I did a bit of testing (set one of the IT guys profile pictures to the face of a women), which worked! The picture synchronized! So I then wrote some PowerShell that replaced the '%20' with a space for all the offending user profile properties, and voila, pictures are synchronising into Active Directory!

The PowerShell I used?

Open the SharePoint 2010 management shell and get the User Profile Manager...

[void][reflection.assembly]::Loadwithpartialname("Microsoft.Office.Server") | out-null       
$site=new-object Microsoft.SharePoint.SPSite("https://ca:7443") #Central Admin site          
$servercontext=[Microsoft.Office.Server.ServerContext]::GetContext($site)            
$site.Dispose() # clean up            
$upm = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($servercontext)

To view the properties:

$pc = $upm.GetEnumerator()            
foreach($p in $pc){$p["PictureUrl"].Value}

To update the properties:

(I also added the port number in and updated any values that were incorrectly referencing the LThumb image (instead of the MThumb image) as advised here: Photo Management in SharePoint 2010)

$pc = $upm.GetEnumerator()            
foreach($p in $pc)            
{            
    $v = $p["PictureUrl"].Value;            
    if($v -ne $null)            
    {            
        if($v.ToString().Contains("%20"))            
        {            
            Write-Host "Need to change value $v";            
            $nv = $v.ToString().Replace("mysite/", "mysite:80/").Replace("%20"," ").Replace("LThumb","MThumb");            
            Write-Host "Writing New Value: $nv" -foregroundcolor green;            
            $p["PictureUrl"].Value = $nv;            
            $p.Commit();            
        }            
    }            
}

Hope it helps someone else too!