16 June 2007

Updating and Enumerating User Profiles in MOSS

Recently, we came across a situation in our environment in which we needed to enumerate all profiles in MOSS 2007 and add a few new profile properties. One of the properties that needed to be updated is the picture url. All of our employees pictures are located in a separate database and an image handler has already been created to serve out the images. So, we wanted to leverage this to place user pictures into the directory (and turn off the user's ability to modify them).

This project is a service that will run on my MOSS server a pre-determined intervals. I will eventually add it to SharePoint as a timer job to be done just after the user profile import has completed.

So, here's the code that made it work:

Imports Microsoft.SharePoint Imports Microsoft.Office.Server.UserProfiles Imports Microsoft.Office.Server
Module UserProfileUpdaterService
Sub Main()
Dim currentSite As New SPSite("http://mymossserver/") Dim context As ServerContext = ServerContext.GetContext(currentSite) Dim profileManager As New UserProfileManager(context)
For Each profile As UserProfile In profileManager
' Get profile properties Dim FirstNameProp As UserProfileValueCollection = profile.Item("FirstName") Dim LastNameProp As UserProfileValueCollection = profile.Item("LastName") Dim ImageProp As UserProfileValueCollection = profile.Item("PictureURL")
' Get string values from the properties Dim FirstName As String = FirstNameProp.Item(0) Dim LastName As String = LastNameProp.Item(0) Dim PictureURL As String = ImageProp.Item(0)
' Set a new picture URL PictureURL = String.Format("http://imageserver/GetEmployeeImage.ashx?" & _ "e={0}",GetEmployeeID(FirstName,LastName))
' Set the image property and commit the changes ImageProp.Item(0) = PictureURL profile.Commit()
Next
End Sub
End Module

First, we need to get a SPSite. This is done by creating a new instance of SPSite passing the site URL to the constructor. Next, we have to pass the site context to the user profile manager's constructor. Then we can iterate through all profiles and retrieve properties of the profile. Each property is returned as a UserProfilePropertyValueCollection. You can get an individual property by calling Prop.Item("PropertyName"). This will return an array of objects. Since most of the properties I'm working with are strings, there's not much of a need to cast them to other object types. Finally, I query the database with the method GetEmployeeID(FirstName,LastName) (which I have not detailed here) and write the values back into the image property using ImageProp.Item(0)=PictureURL. To write the changes to the profile, I finally call profile.Commit.

Hope this simple example can help some of you make necessary changes to your user profile stores in MOSS 2007.

3 comments:

Juan Carlos said...

Hi Chris,
Nice post...I have a question for you, do you know ift it's possible to read the user profiles inside MOSS (for example, using a web part)? I have implemented a web part that reads the profiles perfetly when using an administrator account. However, it doesn't work when using other account without administrator privileges...in the schenario I'm doing my proofs I have an Active Directory domain. I will appreciate any help you can provide me.

Cheers

Jc

p.d: my e-mail address is jcgonzalez@ciin.es

Chris said...

I haven't had the need to do this, but you may want to investigate impersonation within SharePoint, depending on your need. You can have a web-part run with elevated priviledges through impersonation. Unfortunately, I haven't come across this scenario just yet. I do know there are some examples in the SDK of doing this, but I would be careful doing this.

Ramprasad said...

You can look here for more information..

http://dotnetdreamer.wordpress.com/2008/10/17/accessing-user-profiles-in-moss-2007/

http://dotnetdreamer.wordpress.com/2009/01/15/enumerating-sharepoint-user-profiles-access-denied-exception/