Migrating Person list columns between web applications
A few days ago we started migrating a portal site from one web application to another on the same machine.
As part of the migration process I needed to copy lists from the old site to the new site. Some lists, contained Person list columns, with single or multiple selection.
While the migration went smoothly during the export/import process itself the result was weird – all the user names were altered on the new portal.
Reason:
1. Person list columns store the user name (as text) and the user id from the profiles list.
2. Each web application has it’s own profiles – with different user id’s given to each user.
Instead of starting to migrate the profiles from one portal to another I simply wrote a small utility which fix the Person columns of selected lists (imported ones) by taking the user id, getting the email of the user from the old portal, finding the new user id on the new portal and updating the list item:
public partial class Form1 : Form
{
private List<MigrationField> _migrationfields;
private SPSite _sourcesite;
private SPList _targetlist;
private SPSite _targetsite;
public Form1()
{
InitializeComponent();
Source.Text = Settings.Default["SourceSite"].ToString();
Target.Text = Settings.Default["TargetSite"].ToString();
}
private void btnVerifyColumns_Click(object sender, EventArgs e)
{
_sourcesite = new SPSite(Source.Text);
_targetsite = new SPSite(Target.Text);
_targetlist = _targetsite.RootWeb.GetList(TargetListUrl.Text);
_migrationfields = new List<MigrationField>();
Columns.Items.Clear();
Log.Items.Clear();
foreach (SPField field in _targetlist.Fields)
{
if (field.TypeAsString.Equals("User") || field.TypeAsString.Equals("UserMulti"))
{
Columns.Items.Add("Field Name: " + field.Title + ", Multi:" + field.TypeAsString.Equals("UserMulti"));
_migrationfields.Add(new MigrationField { FieldName = field.Title, IsMulti = field.TypeAsString.Equals("UserMulti") });
}
}
btnMigrate.Enabled = true;
}
private string GetEmailFromSource(string userid)
{
if (!String.IsNullOrEmpty(userid))
return _sourcesite.RootWeb.SiteUsers.GetByID(Convert.ToInt32(userid)).Email;
return String.Empty;
}
private SPUser GetUserFromTarget(string emailaddress)
{
if (!string.IsNullOrEmpty(emailaddress))
return _targetsite.RootWeb.SiteUsers.GetByEmail(emailaddress);
return null;
}
private void btnMigrate_Click(object sender, EventArgs e)
{
foreach (SPItem item in _targetlist.Items)
{
try
{
foreach (MigrationField field in _migrationfields)
{
if (item[field.FieldName] != null)
{
switch (field.IsMulti)
{
case true:
string[] userids = item[field.FieldName].ToString().Split(';');
var userscollection = new SPFieldUserValueCollection();
for (int i = 0; i < userids.Length; i += 2)
{
SPUser user = GetUserFromTarget(GetEmailFromSource(userids[i].Replace("#", "")));
if (user != null)
userscollection.Add(new SPFieldUserValue(_targetsite.RootWeb, user.ID,
user.Name));
}
item[field.FieldName] = userscollection;
item.Update();
break;
case false:
string email =
GetEmailFromSource(item[field.FieldName].ToString().Substring(0,
item[
field.
FieldName]
.
ToString().
IndexOf
(';')));
SPUser newuser = GetUserFromTarget(email);
if (newuser != null)
{
item[field.FieldName] = newuser;
item.Update();
}
break;
}
}
}
}
catch (Exception ex)
{
Log.Items.Add("itemid " + item.ID + ": " + ex.Message);
}
}
MessageBox.Show("Done migrating");
}
}
public class MigrationField
{
public string FieldName { get; set; }
public bool IsMulti { get; set; }
}