Wednesday, 26 October 2011

Update SharePoint User Profile for all users in a Active Directory Distribution List

Putting my 2010 project work aside, I was asked to programmatically update each users "User Profile" that was a member of a group (Distribution List) in active directory. In my case, I had to create a custom user profile property called "location". I then had to map each person from their DL in AD to a location in their user profile.


So if I am based in "Glasgow" and I am in the Active Directory Group "Scotland_All" - they wanted some code to update my user profile property, on a mass scale (12,000 users)..


I did some googling before i set about the task but didn't find very much so figured i'd post a quick how-to.


First I went through active directory to get all users that were a member of X group.





const string ADaddress = "domain.com";

const string ADuserName = @"domain\admin";

const string ADPassword = "DomainAdminPassword";

const string ad_group = "Xgroup";

const string domain_name = "Domain"; //not entirely needed

const string sp_site = "http://yourSharePointSite.domain.com";

const string location_value = "Value";




I had to use an account and password with access to AD.






try

{

//Create connection to AD and get all users in specified group

PrincipalContext ctx = new PrincipalContext

(ContextType.Domain,

ADaddress,

ADuserName,

ADPassword);



//Search for members in group

GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, ad_group); //CL_France being the DL we need

PrincipalSearchResult members = group.GetMembers(); //getting them all



//Get the user names and add the domain (we are assuming that all these users will be "s7")

foreach (Principal member in members)

{

string domainUserName = domain_name + @"\" + member.SamAccountName;



//Update in Sharepoint

UpdatespProfile(domainUserName);

}

}

catch (Exception ex)

{

Console.WriteLine(ex); //show me the error

Console.Read(); //pause



}

}




Once have the users details, I start updating their user profile. This is done using the object model so the console app was run locally. It can be done via web services but with so many users and transactions I found that simelar tasks would time out..





//take user names, check they have a user profile - if they do, update "localtion" field

static void UpdatespProfile(string uName)

{

//show user in console

Console.WriteLine(uName);//member.SamAccountName);



try

{



using (SPSite site = new SPSite(sp_site))

{

//Connect to user manager and pass in user name

UserProfileManager profileManager = new UserProfileManager(ServerContext.GetContext(site));

UserProfile userProfile = profileManager.GetUserProfile(uName);



//check if we have a valid user profile

if (userProfile != null)

{



//Update location field

userProfile["Location"].Value = location_value;


//update the user profile

userProfile.Commit();



//show it worked in console

Console.WriteLine("Updated Location to" +" " + location_value);



}

else

{

//show we didn't have a valid user profile in console

Console.WriteLine("No user profile");

}

}

}

catch (Exception ex)

{

//show the error

Console.WriteLine(ex);

//pause

Console.Read();

}

}



Works very nicely. Hope someone out there finds it useful.