65.9K
CodeProject 正在变化。 阅读更多。
Home

使用更多 Active Directory 信息更新 SharePoint UserInfo 列表

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.45/5 (5投票s)

2009年3月19日

CPOL

2分钟阅读

viewsIcon

60602

downloadIcon

383

展示如何编写一个作业,使用更多 Active Directory 信息更新 UserInfo 列表。

引言

前段时间,我下载了一个 Web Part,它应该显示当前用户的天气。它被编码为查询 SiteUserInfoList 并提取用户的 WorkCityWorkStateWorkCountry 属性,以便正确地定位用户。我安装了这个 Web Part,发现它不起作用。这些属性在 Moss 的用户配置文件中,但不在 Site 集合的 SiteUserInfoList 中。编写 Web Part 的人显然不喜欢进行测试。那么,我该怎么办?我不想依赖 Moss 的用户配置文件,因为我希望我的所有 Web Part 都能在非 Moss 实现中工作。因此,我决定编写一个作业,每天晚上运行以使用更多 Active Directory 属性更新 SiteUserInfoList

另外,您是否厌倦了在将用户添加到组时收到“用户不存在或不唯一”错误?那么,这段代码还将更新 Active Directory 中缺失的每个用户的标题为“XX - <previousTitle>”。这是一种简单的方法,可以向您展示用户在 Active Directory 中缺失,以便在使用用户选择器对话框时,您可以防止自己收到该错误。

UserDialog.png

安装

首先,将构建目录复制到您农场中每个服务器的桌面上。以管理员身份运行“Install AD Updator.bat”。输入您要安装到的 Web 应用程序的名称,然后按 Enter。请确保一次只在一个服务器上运行此操作。

代码

该代码遍历 SharePoint 中的所有用户,然后从 Active Directory 中提取他们的信息。然后,它获取来自 Active Directory 的信息并更新特定的字段,例如 TitlePhone 等。然后,它将剩余的信息(WorkCityWorkZip 等)存储在用户 UserInfo 项目的属性包中。

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using System.Diagnostics;
using Microsoft.SharePoint.Utilities;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Security.Principal;
namespace Mullivan.SharePoint.Jobs
{
    public class AdUserInfoUpdateJobDefinition : SPJobDefinition
    {
        internal const string _JOBNAME = "AD User Info Update Job";
        public AdUserInfoUpdateJobDefinition () : base() { }
        public AdUserInfoUpdateJobDefinition(SPWebApplication webApp)
            : base(_JOBNAME, webApp, null, SPJobLockType.Job)
        {
            this.Title = _JOBNAME;
        }
        public override void Execute(Guid targetInstanceId)
        {
            try
            {
                DirectoryEntry domain = GetDomainEntry();
                if (domain == null)
                    throw new Exception("Domain not found.");
                foreach (SPSite site in this.WebApplication.Sites)
                {
                    using (SPWeb web = site.RootWeb)
                    {
                        SPListItemCollection userItems = web.SiteUserInfoList.Items;
                        for (int i = 0; i < userItems.Count; i++)
                        {
                            try
                            {
                                double progress = ((double)(i + 1)) / 
                                                   (double)userItems.Count;
                                UpdateProgress(Convert.ToInt32(progress * 100));
                                SPListItem userItem = userItems[i];
                       
                                SPUser user = web.SiteUsers.GetByID(userItem.ID);
                                if (user == null)
                                    throw new Exception(string.Format(
                                      "User account {0} not found in site {1}.", 
                                      userItem.Name, site.Url));
                                DateTime dtUserItemUpdated = 
                                   (DateTime)userItem["Modified"];
                                if (IsPerson(userItem) && !IsSystem(user))
                                {
                                    AdUserInfo userInfo = GetUserInfo(user, domain);
                                    if (userInfo == null || !userInfo.IsActive)
                                    {
                                        string jobTitle = (string)userItem["JobTitle"];
                                        if (string.IsNullOrEmpty(jobTitle))
                                            jobTitle = string.Empty;
                                        if (!jobTitle.StartsWith("XX - "))
                                        {
                                            jobTitle = string.Format("XX - {0}", jobTitle);
                                            userItem["JobTitle"] = jobTitle;
                                            userItem.Update();
                                        }
                                    }
                                    else
                                    {
                                        object updateFlag = 
                                           userItem.Properties["AdUpdateFlag"];
                                        if (userInfo.LastModified > dtUserItemUpdated
                                            || updateFlag == null)
                                        {
                                            userItem.Properties["AdUpdateFlag"] = 1;
                                            if (userInfo.Email != null)
                                            {
                                                userItem["EMail"] = userInfo.Email;
                                                user.Email = userInfo.Email;
                                            }
                                            if (userInfo.Department != null)
                                                userItem["Department"] = userInfo.Department;
                                            if (userInfo.JobTitle != null)
                                                userItem["JobTitle"] = userInfo.JobTitle;
                                            else
                                            {
                                                string val = (string)userItem["JobTitle"];
                                                if (val != null)
                                                {
                                                    if (val.StartsWith("XX - "))
                                                        userItem["JobTitle"] = 
                                                           val.Substring(5, val.Length - 5);
                                                }
                                            }
                                            if (userInfo.FirstName != null)
                                                userItem["FirstName"] = userInfo.FirstName;
                                            if (userInfo.LastName != null)
                                                userItem["LastName"] = userInfo.LastName;
                                            if (userInfo.WorkPhone != null)
                                                userItem["WorkPhone"] = userInfo.WorkPhone;
                                            if (userInfo.Office != null)
                                                userItem["Office"] = userInfo.Office;
                                            if (userInfo.WorkZip != null)
                                                userItem.Properties["WorkZip"] = 
                                                                    userInfo.WorkZip;
                                            if (userInfo.WorkCity != null)
                                                userItem.Properties["WorkCity"] = 
                                                                    userInfo.WorkCity;
                                            if (userInfo.WorkState != null)
                                                userItem.Properties["WorkState"] = 
                                                                    userInfo.WorkState;
                                            if (userInfo.WorkCountry != null)
                                                userItem.Properties["WorkCountry"] = 
                                                                    userInfo.WorkCountry;
                                            userItem.Update();
                                            user.Update();
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                Logging.ServiceLog.LogException(_JOBNAME, ex);
                            }
                        }
                        web.Dispose();
                    }
                    site.Dispose();
                }
            }
            catch (Exception ex)
            {
                Logging.ServiceLog.LogException(_JOBNAME, ex);
            }
        }
        private bool IsSystem(SPUser user)
        {
            if (user.ID.Equals(1073741823))
                return true;
            if (user.LoginName == null)
                return true;
            if(user.LoginName.ToLower().StartsWith("nt authority"))
                return true;
            if (user.LoginName.ToLower().StartsWith("system"))
                return true;
            return false;
        }
        private AdUserInfo GetUserInfo(SPUser user, DirectoryEntry domain)
        {
            string id = user.Sid;
            bool localMachine = domain.Path.StartsWith("WinNT");
            string userFlagProperty = "userAccountControl";
            if (localMachine)
                userFlagProperty = "UserFlags";
            DirectoryEntry deUser = FindUser(id, domain);
            if (deUser != null)
            {
                AdUserInfo adUserInfo = new AdUserInfo();
                adUserInfo.IsActive = true;
                if (localMachine)
                {
                    //For testing purposes... Production Environment should be using
                    // Active Directory
                    adUserInfo.LastModified = DateTime.Now;
                    string value = GetValue("FullName", deUser);
                    if (!string.IsNullOrEmpty(value))
                    {
                        string[] vals = value.Split(new char[1] { ' ' }
                            , StringSplitOptions.RemoveEmptyEntries);
                        if (vals.Length > 0)
                            adUserInfo.FirstName = vals[0];
                        if (vals.Length > 1)
                            adUserInfo.LastName = vals[vals.Length - 1];
                    }
                    adUserInfo.WorkCity = "St Louis";
                    adUserInfo.WorkState = "MO";
                    adUserInfo.WorkZip = "63141";
                    
                }
                else
                {
                    DateTime dtModified = DateTime.Now;
                    if (DateTime.TryParse(GetValue("whenChanged", deUser), 
                                          out dtModified))
                        adUserInfo.LastModified = dtModified;
                    else
                        adUserInfo.LastModified = DateTime.Now;
                    adUserInfo.LastName = GetValue("sn", deUser);
                    adUserInfo.FirstName = GetValue("givenName", deUser);
                    adUserInfo.Name = GetValue("sAMAccountName", deUser);
                    adUserInfo.Office = GetValue("physicalDeliveryOfficeName", deUser);
                    adUserInfo.WorkPhone = GetValue("telephoneNumber", deUser);
                    adUserInfo.Department = GetValue("department", deUser);
                    adUserInfo.Email = GetValue("mail", deUser);
                    adUserInfo.JobTitle = GetValue("title", deUser);
                    adUserInfo.WorkCity = GetValue("l", deUser);
                    adUserInfo.WorkState = GetValue("st", deUser);
                    adUserInfo.WorkCountry = GetValue("c", deUser);
                    adUserInfo.WorkZip = GetValue("postalCode", deUser);
                }
                string userAC = GetValue(userFlagProperty, deUser);
                int userValue = 0;
                if(int.TryParse(userAC, out userValue))
                {
                    try
                    {
                        AdUserAccountControl userAccountControl = 
                                            (AdUserAccountControl)userValue;
                        adUserInfo.IsActive = 
                            //Make sure it's not disabled
                            ((userAccountControl & AdUserAccountControl.ACCOUNTDISABLE) 
                                        != AdUserAccountControl.ACCOUNTDISABLE)
                            //Make sure it's a normal account
                            && ((userAccountControl & 
                                  AdUserAccountControl.NORMAL_ACCOUNT) == 
                                  AdUserAccountControl.NORMAL_ACCOUNT);
                    }
                    catch (Exception ex)
                    {
                        Logging.ServiceLog.LogException(_JOBNAME, ex);
                    }
                }
                return adUserInfo;
            }
            else
                return null;
        }
        private string GetValue(string propertyName, DirectoryEntry deUser)
        {
            if (deUser.Properties.Contains(propertyName))
            {
                PropertyValueCollection pvc = deUser.Properties[propertyName];
                if (pvc.Count > 0)
                {
                    object objValue = pvc[0];
                    if (objValue != null)
                        return objValue.ToString();
                }
            }
            return null;
        }
        private DirectoryEntry FindUser(string id, DirectoryEntry domain)
        {
            if (!domain.Path.StartsWith("WinNT"))
            {
                DirectorySearcher search = new DirectorySearcher(domain);
                search.Filter = 
                  string.Format("(&(objectClass=person)(objectSid={0}))", id);
                SearchResult result = search.FindOne();
                if(result != null)
                    return result.GetDirectoryEntry();
            }
            else
            {
                foreach (DirectoryEntry de in domain.Children)
                {
                    SecurityIdentifier si = new SecurityIdentifier(
                        (byte[])de.Properties["objectSid"][0], 0);
                    if (string.Compare(si.Value, id, true) == 0)
                        return de;
                }
            }
            return null;
        }
        private DirectoryEntry GetDomainEntry()
        {
            try
            {
                return Domain.GetComputerDomain().GetDirectoryEntry();
            }
            catch(Exception ex)
            {
                Logging.ServiceLog.LogException(_JOBNAME, ex);
#if SULLYSERVER
                DirectoryEntry localMachine = new DirectoryEntry(
                    string.Format("WinNT://{0},Computer", Environment.MachineName));
                return localMachine;
#else
                return null;
#endif
            }
        }
        private bool IsPerson(SPListItem userItem)
        {
            string contentType = userItem.ContentType.Name;
            if (!contentType.Equals("Person"))
                return false;
            return true;
        }
        private void Trace(string message)
        {
            System.Diagnostics.Trace.WriteLine(message, _JOBNAME);
        }
    }
}

现在,我们可以通过以下方式提取这些信息并在我们的 Web Part 中使用它(这段代码是基于我修改过的 WeatherWebPart 中的示例)

private bool SetUserLocation()
{
    try
    {
        SPWeb web = SPContext.Current.Web;
        SPUser u = web.SiteUsers[web.CurrentUser.LoginName];
        SPList userList = web.SiteUserInfoList;
        SPListItem uItem = userList.Items.GetItemById(u.ID);
       
        if (uItem != null)
        {
            string strZip = uItem.Properties["WorkZip"] as string;
            if (!string.IsNullOrEmpty(strZip))
                this.Zip = strZip;
            return true;
        }
    }
    catch
    {
        this.Zip = DEFAULT_ZIP;
    }
    return false;
}

就这样,很简单!

© . All rights reserved.