User Voices
(Loading...)
Our blog on SharePoint add-ons and solutions development
« SharePoint 2010 List View AJAX Options and Filter Web Parts | Main | Print-Friendly SharePoint Calendar / List Views & User Profiles Web Parts »
Sunday
Oct102010

Sync User Profiles' Picture URL with Active Directory images (thumbnailPhoto / jpegPhoto)

As you know, the SharePoint 2010 User Profile synchronization features sync up all your people data as stored in Active Directory (or other LDAP service) — except your profile pictures, if your AD uses the jpegPhoto or thumbnailPhoto properties for those.

The main reason for this is quite simply that the PictureURL property is a URL field (storing only the HTTP address pointing to a picture file), whereas AD stores the entire image itself as a "binary large object" (blob). So any synchronization will involve downloading the pictures stored in AD, putting them somewhere HTTP-accessible, and then setting the PictureURL user profile property to the address of this copied image file.

So with no out-of-box support for synchronizing user profile pictures from Active Directory to SharePoint (SP to AD apparently works), one PeopleZen user was looking for a solution and approached us about this issue. Upon our research we stumbled across:

  • one technique — but this requires Forefront Synchronization Service Manager and the process required 11 full-screen captures.
  • but no direct solution from "Russmax" of MSFT
  • and a pretty-looking that lets you import the pictures profile by profile manually, with a few clicks required for each import. Looks good, but seems to require some interactive efforts to operate.

We wanted a sync-all, batch solution — you launch it and it just runs — so we wrote a free tool to help you with this, greatly assisted (thanks again, Robert! :) by a User Profiles Web Part user who had a vested interest in such a tool.

We packaged this up with PeopleZen but you won't even need a license to keep using this free sync tool indefinitely. If you need the source code for more sophisticated customizations, simply contact us and we'll send it to you.

Even though you won't need to license PeopleZen, you'll need to deploy it as the tool itself is packaged up with the PeopleZen solution package for now (simply because we wanted it included in our WSP build processes for publishing updated software versions).

After deployment, the tool is available in the following directory on your main SharePoint server:

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\roxority_PeopleZen\adpic2010

Note: this is a command-line application that will attempt to actively perform its job immediately upon launching it, there is no prompt, it's an old-school admin tool. You have been warned. So before you do launch PicImportADtoSP2010, review and customize the PicImportADtoSP2010.config XML file which provides the following settings for customization:

Conn

The LDAP connection string, change this to your AD server. The $USERNAME$ placeholder can be used but in the default value LDAP://OU=Departments,DC=global,DC=local it is not.

ConnUser, ConnPass, ConnAuth

Empty by default — not necessary to change these unless authentication is strictly required for simply fetching the thumbnailPhoto / jpegPhoto property data. ConnAuth stays at None except when ConnUser and ConnPass need to be set (in which case, the are valid for ConnAuth).

ImportPath

A fully qualified URL pointing to your SharePoint server. Either pointing to an existing Picture or Document Library (unescape the URL ie. Shared Documents rather than Shared%20Documents etc.) or a _layouts path that will copy the thumbnailPhotos directly to the file system instead of a SharePoint library.

If using a _layouts or _layouts/images URL, best to use your own folder and create that manually in the file system yourself prior to running the tool. For example we used http://testsystem/_layouts/images/people and have created our own folder C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\IMAGES\people\ for that.

This approach is the fastest for image loading and storage (no permission checks or cross-server sync round-trips). Also for now the recommended one, as in our case with libraries, the files were stored but could never be properly displayed in the browser (known issue). Unless you have a multi-server farm environment of more than say 5 servers or dynamically growing all the time, we would recommend using the file system-based approach.

ConnProp

Defaults to thumbnailPhoto but some directory services use jpegPhoto so this can be customized here.

ImportExt

Defaults to .jpg. We add this to the filename so don't clear this — if you're sure all pictures are pngs of course feel free to change to .png. Hopefully all pictures in AD are in one and the same format, and if so, it's most likely .jpg.

SSPBackwardCompatible, SSPIgnorePrivacy

Customizing these is usually neither necessary nor recommended. Possible values are True and False. Can be experimented with only if you get the error message "Could not obtain UserProfileManager object", otherwise there is absolutely no reason to customize these.

SSPProp

Defaults to PictureURL. Name of the SharePoint user profiles property to store the picture URL. PictureURL is the one officially used by the out-of-box UI pages but you can (and maybe should!) use a different, throw-away, custom property (this would need to be defined manually in the User Profiles Service Application of course) for testing the sync tool.

SSPNameProp

Defaults to AccountName. Denotes the user profile property (in SharePoint User Profiles Web Application) containing the user name that is used both to replace $USERNAME$ in the LDAP connection string, and for the output image URL / file name. AccountName is usually a user name with domain\prefix, other related properties that might work better are UserName (without a domain\ prefix) or possibly even PreferredName (often first name and last name, sometimes last name, comma, first name... depends on your setup). Primarily you want to use a value that works with your LDAP URL.

ConnSearch

You can clear this if the user name placeholder is already included in your LDAP path specified in ConnProp (see above). If it isn't, this property defines the LDAP query to obtain the Active Directory user profile. Defaults to (&(SAMAccountName=$USERNAME$))

Keep in mind:

Of course, the tool needs to be run on the primary SharePoint server (in a multi-server environment, the one hosting Central Administration) and with sufficient privilegues (the highest you have, after all you're attempting to write to the SharePoint User Profiles Service Application).

Also note: once the tool manages to enumerate SharePoint's user profiles, it will attempt every individual profile rather than fail completely at the first problem. So even if there is only one tiny problem (in the above configuration, our code or your environment), this may look like "millions of errors messages" even though it's just always the same issue occurring time and again.

Reader Comments (10)

Hi nice tool, but I can't run it:

Could not obtain UserProfileManager object:

Microsoft.Office.Server.UserProfiles.UserProfileApplicationNotAvailableException
: No User Profile Application available to service the request. Contact your far
m administrator.
at Microsoft.Office.Server.Administration.UserProfileApplicationProxy.get_App
licationProperties()
at Microsoft.Office.Server.Administration.UserProfileApplicationProxy.CheckAd
ministrationAccess(UserProfileApplicationAdminRights rights, Boolean requireAllR
ights)
at Microsoft.Office.Server.Administration.UserProfileApplicationProxy.CheckAd
ministrationAccess(UserProfileApplicationAdminRights rights)
at Microsoft.Office.Server.UserProfiles.ProfileManagerBase.CanManagePeople(Us
erProfileApplicationProxy userProfileApplicationProxy)
at Microsoft.Office.Server.UserProfiles.ProfileManagerBase.get_IsProfileAdmin
()
at Microsoft.Office.Server.UserProfiles.UserProfileManager..ctor(SPServiceCon
text serviceContext, Boolean IgnoreUserPrivacy, Boolean backwardCompatible)
at Microsoft.Office.Server.UserProfiles.UserProfileManager..ctor(ServerContex
t serverContext, Boolean IgnoreUserPrivacy, Boolean backwardCompatible)
at roxority_PeopleZen_PictureImport.Program.Main(String[] args)

Done.

What to do with that ?

December 3, 2010 at 17:44 | Unregistered Commentermak

Did you run it on the primary farm server / the farm server hosting Central Admin, as a member of the Farm Administrators group (inspect this group via Central Admin)?

Generally this issue does not occur if the code is run server-side with the right privileges in a farm where a default User Profiles Service Application is defined and functioning.

December 3, 2010 at 21:52 | Registered CommenterROXORITY

Hi,

Thanks for the reference to my blog post. Just would like you and the readers to know that there is a new related tool that helps automatic synchronizing user profile images between AD and SP. You can read more about it here:

Creating a timer job for Active Directory - SharePoint profile user image synchronization
http://pholpar.wordpress.com/2010/11/17/creating-a-timer-job-for-active-directory-sharepoint-profile-user-image-synchronization/

Peter

January 6, 2011 at 4:05 | Unregistered CommenterPeter Holpar

Thanks Peter, looks promising for those able and willing to code! =)

January 6, 2011 at 19:45 | Registered CommenterROXORITY

Hi - will this tool do exactly the same as if the user imported the picture from My Site, so that the pictires are stores in the three standard Sharepoint 2010 resolutions 144x144, 96x96, and 32x32 pixels?

Does the tool expect that the pictures in AD's thumbnailPhoto are in 144x144 pixels, or is that not important?

Peter Almer Frederiksen :-)

April 14, 2011 at 16:11 | Unregistered CommenterPeter Almer Frederiksen

The tool performs a simple file transfer and does not care about or modify picture dimensions. I wasn't even aware that these are "standard dimensions". But assuming your source pictures are already in a square format CSS shrinking should just suffice to meet these dimensions. Otherwise... some more custom coding will be required.

April 15, 2011 at 1:51 | Registered CommenterROXORITY

Why dont you just use the OOB PowerShell cmdlet Update-SPProfilePhotoStore?

Update-SPProfilePhotoStore -MySiteHostLocation http://my -CreateThumbnailsForImportedPhotos $true

If you dont have the thumbnails parameter, i think it was added in OCT or FEB Cumulative Update.

May 17, 2011 at 19:14 | Unregistered CommenterAnders Rask

I am attempting to configure this web part, and am receiving what I believe are two different errors with the XML:

=== ...\AliciaN ===
Could not obtain SearchResult object:

System.DirectoryServices.DirectoryServicesCOMException (0x8007202B): A referral was returned from the server.
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_AdsObject()
at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
at System.DirectoryServices.DirectorySearcher.FindOne()
at roxority_PeopleZen_PictoreImport.Program.Main(String[] args)

Could not obtain PropertyValueCollection object:

System.DirectoryServices.DirectoryServicesCOMException (0x8007202B): A referral was returned from the server.
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_AdsObject()
at System.DirectoryServices.PropertyValueCollection.PopuldateList()
at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName)
at System.DirectoryServices.PropertyCollection.get_Item(String propertyName)
at Roxority_PeopleZen_PictureImport.Program.Main(String[] args)

Any ideas as to what is causing my issue? I have over 300 users and these same errors repeated for each attempt.
Thanks in advance!

Chris

December 24, 2011 at 13:16 | Unregistered CommenterChris

Hi Chris,

is this occuring in the Web Part or in the User Profile Picture sync tool? In *any* case: whenever you get a DirectoryServicesCOMException, the issue is with your AD connection parameters or your AD configuration and needs to be troubleshooted with your resident AD guru/admin. Our AD connectors work fine across 100s of production environments when the configurations are right, but we focus on SharePoint much more so than on AD and each AD is highly uniquely individually different, one configuration might work in one AD environment but not in another. With enough fiddling on the AD connection parameters or AD configuration, I'm sure you'll successfully connect eventually.

December 29, 2011 at 11:39 | Registered CommenterROXORITY

You should look at http://blogs.technet.com/b/nishants/archive/2012/02/21/how-to-sync-picture-from-sharepoint-to-active-directory-and-hence-to-outlook-and-lync.aspx

February 23, 2012 at 19:42 | Unregistered CommenterKF
Member Account Required
You must have a member account on this website in order to post comments. Log in to your account to enable posting.