Friday, June 02, 2006

New challenge! pt2

Well, I told you before about the challenge I was faced with (migrating users from a foreign domain to an existing domain in Sharepoint) The luck I had was that the usernames were the same, so that only the domainnames were different. First I had to discover if a user existed on a site and if so, what is the role that this user has. Then I had to add the new user to the site. So I designed four functions : 1. GetAllWebs (loop through all the portals and sites) 2. GetUser (look for the user) 3. GetGroups (get's the role from the users (eg. reader/contributor) 4. MigrateUser (add the new account with the same securitysettings) Since I don't have the rights on the frontend server, I could only use webservices. Thus I was confronted by the lack of support to enumerate through all the sites that belong to a portal. The "Webs" webservice only collects the area's from a portal. So if anyone knows how to get the webs from a portal, I'm all ears ;) GetAllWebs

private void GetAllWebs(string url) { ArrayList list = new ArrayList(); Webs.Webs web = new WebApplication5.Webs.Webs(); web.Url = url + "/_vti_bin/webs.asmx"; web.Credentials = new System.Net.NetworkCredential("username", "password", "domain"); try { XmlNode subwebs = web.GetAllSubWebCollection(); foreach(XmlElement item in subwebs.SelectNodes("*")) { GetUsers(item.Attributes["Url"].Value.ToString()); } } catch(Exception) { Response.Write(url + " does not exist"); } }
GetUsers
private void GetUsers(string url) { ArrayList users = new ArrayList(); UserGroup.UserGroup usgrp = new WebApplication5.UserGroup.UserGroup(); usgrp.Url = url + "/_vti_bin/usergroup.asmx"; usgrp.Credentials = new System.Net.NetworkCredential("username", "password", "domain"); XmlNode node = usgrp.GetUserCollectionFromWeb(); foreach(XmlElement item in node.SelectNodes("*")) { foreach (XmlElement items in item.SelectNodes("*")) { if (items.Attributes["LoginName"].Value.IndexOf("OLDDOMAIN") > -1) { Response.Write("

" + url + "

"); Response.Write("
" + items.Attributes["Name"].Value.ToString()); Response.Write("  " + items.Attributes["LoginName"].Value.ToString()); Response.Write("  " + items.Attributes["Email"].Value.ToString()); GetGroups(items.Attributes["LoginName"].Value.ToString(), url, items.Attributes["Name"].Value.ToString(), items.Attributes["Email"].Value.ToString()); } } } }
GetGroups
private void GetGroups(string loginname, string url, string username, string email) { UserGroup.UserGroup usgrp = new WebApplication5.UserGroup.UserGroup(); usgrp.Url = url + "/_vti_bin/usergroup.asmx"; usgrp.Credentials = new System.Net.NetworkCredential("username", "password", "domain"); try { XmlNode node = usgrp.GetRoleCollectionFromUser(loginname); foreach(XmlElement item in node.SelectNodes("*")) { foreach (XmlElement items in item.SelectNodes("*")) { Response.Write("  " + items.Attributes["Name"].Value.ToString()); MigrateUser(items.Attributes["Name"].Value.ToString(), username, loginname, email, url); //users.Add(items.Attributes["LoginName"].Value.ToString()); } } } catch(Exception error) { Response.Write("
" + error.Message.ToString()); } }
MigrateUser
private void MigrateUser(string role, string username, string loginname, string email, string url) { UserGroup.UserGroup usgrp = new WebApplication5.UserGroup.UserGroup(); usgrp.Url = url + "/_vti_bin/usergroup.asmx"; usgrp.Credentials = new System.Net.NetworkCredential("username", "password", "domain"); if (loginname.IndexOf("OLDDDOMAIN") > -1) { loginname = loginname.Replace("OLDDOMAIN","NEWDOMAIN"); try { usgrp.AddUserToRole(role, username, loginname, email, ""); Response.Write(username + " is added with " + role + " right"); } // catch (Microsoft.SharePoint.SoapServer.SoapServerException soaperr) // { // //Response.Write("User cannot be added to the site"); // Response.Write("
" + soaperr.InnerException.Message.ToString()); // } catch (Exception error) { Response.Write("
" + error.Message.ToString()); } } }
If all the users are migrated succesfully then I have to write another function to remove the old accounts. Btw if you are wondering why I haven't used the SPUserUtilSuite from Keith Richie, it required (although I think it did) to execute the files on the front-end server of the farm. Unfortunatly I did not have that luxury.. Btw.. todo's are : instead of using Response.Write's is to write the results in a nice xml file and have a webservice that collects all the webs from a portal (instead of the areas) :)

2 comments:

Anonymous said...

Hey - Great code, thank you. I am having an issue using the UserGroup webservice with the NetworkCredentials - works with DefaultCredentials, but not NetworkCredentials. Any thoughts?
-morna@highstream.net

digital signatures said...

Excellent! Thanks for this - I've been looking at this feature for ages. Followed your instructions and it works a treat!