DCSIMG
September 2009 - Posts - Doron Goldberg

September 2009 - Posts

After setting up a new web application for a new portal I faced a crawling problem of the new site collection.

Description:

Right after starting the crawler it stops, giving 2-3 error messages, all with the same syntax:

Error in the Site Data Web Service. (Value does not fall within the expected range.)

 

The crawl log was the only place the error was logged, with no additional information regarding the cause of the problem.

 

Searching the web came up with very little solutions, while only one of them seemed to apply to our case:

 

1. stsadm -o export -url http://intranet/sites/it -filename D:\it.back.11.21.08.cmp -versions 2
2. Delete the site collection
3. stsadm -o import -url http://intranet/sites/it -filename D:\it.back.11.21.08.cmp -updateversions 2 –nofilecompression

(See here)

 

While option 1 and 3 are reasonable, deleting the site collection didn’t apply since the portal was already in production stage. (along with the fact faze 1 didn’t pass either due to some technical issues… so I had to look for a better way to solve the issue)

After opening a support ticket, Microsoft’s support team came up with a nicer solution:

First of all, the cause behind this problem:

Corrupted SIDs in the UserInfo table

Solution:

1. Run the following sql query using your moss content database:

Select tp_login, tp_systemid, tp_deleted from userinfo where len(ltrim(rtrim(tp_systemid))) <25 and tp_deleted = 0

2. Give some kind of permissions to the root site of the site collection to all the users returned by the query, except system users:

NT AUTHORITY\authenticated users
NT AUTHORITY\local service
NT AUTHORITY\system
SHAREPOINT\system

4. After the query returns no results (accept the system accounts) start a full crawl.

 

Notes:

1. As for stage 2, you better test 2-3 users just to make sure that after you give them permissions to the root site they are infect removed from the query search results.

2. By give permission I mean any type of permission, “read” is enough. While giving permissions to a user in the root level the SID is updated and fixed (somehow…).

3. I had a local problem with some of the users which appeared in the returned result – I couldn’t add them to the site collection because they were deleted from the Active Directory (former employees) so simply had to delete them through the “People and Groups” of the site collection.

Posted by dorong | 9 comment(s)
תגים:, , ,

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; }
}
Posted by dorong | 3 comment(s)
תגים:, , , ,