操作Active Directory C#

2020-12-13 16:13

阅读:295

标签:des   style   blog   http   io   ar   os   使用   sp   

 

.Net平台操作活动目录Active Directory,使用System.DirectoryServices.ActiveDirectory,主要是User OU 和Group的操作。

代码运行了一年多,还没有出现问题,应该算是经过了验证。

更新的代码在www.codeplex.com/ADBlock

/*
 * Copyright [2008]. Sherwin Zhu. sherwinzhu@126.com
 *
 * http://www.gnu.org/licenses/lgpl-3.0.txt
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
using System.Collections;
using System.DirectoryServices.ActiveDirectory;

namespace TB.ADBlock
{
    /// 
    /// 用于进行AD管理里的对象,提供操作AD的静态方法。
    /// 
    /// 
    /// 这里ADsPath可以是LDAP://DN和LDAP://两种形式,但不限于这种形式。
    /// 一般方法均提供2种形式,一种是用参数提供的用户身份标识,一种是用默认的用户身份标识。
    /// 默认用户身份标识取决于当前进程的用户身份标识。
    /// 
    public class ADManager
    {
        #region 域信息

        /// 
        /// 将友好的域名称(friendly domain name)转换为合格的域名称(fully qualified domain name)。
        /// eg:tb -- > tb.com
        /// 
        /// 友好的域名称(friendly domain name)。
        /// 可以是:
        /// 域控制器的 DNS 名称。
        /// ADAM 服务器的 DNS 名称和 LDAP 端口号(如 adam_instance.fabrikam.com:389)。
        /// 域的 DNS 名称,如 sales.corp.fabrikam.com。
        /// 林的 DNS 名称,如 corp.fabrikam.com。
        /// 应用程序分区的 DNS 名称。
        /// 与服务连接点关联的关键字之一,该服务连接点由配置集的 ADAM 实例注册。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 
        public static string FriendlyDomainToLdapDomain(string friendlyDomainName, string userName, string password)
        {
            string ldapPath = null;
            try
            {
                DirectoryContext objContext = null;
                if (UseDefaultIdentity(userName, password))
                    objContext = new DirectoryContext(DirectoryContextType.Domain, friendlyDomainName);
                else
                    objContext = new DirectoryContext(DirectoryContextType.Domain, friendlyDomainName, userName, password);

                ldapPath = System.DirectoryServices.ActiveDirectory.Domain.GetDomain(objContext).Name;
            }
            catch (DirectoryServicesCOMException dsce)
            {
                throw dsce;
            }
            return ldapPath;
        }

        /// 
        /// 将友好的域名称(friendly domain name)转换为合格的域名称(fully qualified domain name)。
        /// eg:tb -- > tb.com
        /// 
        /// 友好的域名称(friendly domain name)。
        /// 可以是:
        /// 域控制器的 DNS 名称。
        /// ADAM 服务器的 DNS 名称和 LDAP 端口号(如 adam_instance.fabrikam.com:389)。
        /// 域的 DNS 名称,如 sales.corp.fabrikam.com。
        /// 林的 DNS 名称,如 corp.fabrikam.com。
        /// 应用程序分区的 DNS 名称。
        /// 与服务连接点关联的关键字之一,该服务连接点由配置集的 ADAM 实例注册。
        /// 
        public static string FriendlyDomainToLdapDomain(string friendlyDomainName)
        {
            return FriendlyDomainToLdapDomain(friendlyDomainName, null, null);
        }

        /// 
        /// 获取当前用户上下文的 Forest 对象中的所有域名称。
        /// 
        /// 
        public static List EnumerateDomains()
        {
            List alDomains = new List();
            Forest currentForest = Forest.GetCurrentForest();
            DomainCollection myDomains = currentForest.Domains;

            foreach (System.DirectoryServices.ActiveDirectory.Domain objDomain in myDomains)
            {
                alDomains.Add(objDomain.Name);
            }
            return alDomains;
        }

        /// 
        /// 获取当前用户上下文的 Forest 对象中所有的全局目录。 
        /// 
        /// 
        public static List EnumerateGlobalCatalogs()
        {
            List alGCs = new List();
            Forest currentForest = Forest.GetCurrentForest();
            foreach (GlobalCatalog gc in currentForest.GlobalCatalogs)
            {
                alGCs.Add(gc.Name);
            }
            return alGCs;
        }

        /// 
        /// 获取当前用户身份标识的 Domain 对象中的域控制器。
        /// 
        /// 
        public static List EnumerateDomainControllers()
        {
            List alDcs = new List();
            System.DirectoryServices.ActiveDirectory.Domain domain = System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain();
            foreach (DomainController dc in domain.DomainControllers)
            {
                alDcs.Add(dc.Name);
            }
            return alDcs;
        }

        #endregion


        #region Common

        /// 
        /// 检验指定的DirectoryEntry是否存在
        /// 
        /// ADsPath,自动添加LDAP_IDENTITY。完全转义过的。
        /// 
        public static bool Exists(string path)
        {
            if (path.StartsWith(ParaMgr.LDAP_IDENTITY))
                return DirectoryEntry.Exists(path);
            else
                return DirectoryEntry.Exists(ParaMgr.LDAP_IDENTITY + path);

        }

        /// 
        /// 移动DirectoryEntry到指定位置。
        /// 
        /// 要移动的DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。
        /// 移动到的位置的ADsPath。必须是DN形式。完全转义过的。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 被移动的对象和要移动到的位置对象必须使用DN形式的路径创建,不能使用GUID形式的路径,否则会引发异常。
        public static void Move(string objectPath, string newLocationPath, string userName, string password)
        {
            if (!Exists(objectPath))
                throw new EntryNotExistException("需要被移动的对象不存在。");

            DirectoryEntry de = null;
            try
            {
                de = GetByPath(objectPath, userName, password);

                Move(de, newLocationPath, userName, password);
            }
            catch
            {
                throw;
            }
            finally
            {
                if (de != null)
                {
                    de.Close();
                    de.Dispose();
                }
            }
        }

        /// 
        /// 移动DirectoryEntry到指定位置,使用默认用户身份标识。
        /// 
        /// 要移动的DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。
        /// 移动到的位置的ADsPath。必须是DN形式。完全转义过的。
        public static void Move(string objectPath, string newLocationPath)
        {
            Move(objectPath, newLocationPath, null, null);
        }

        /// 
        /// 移动DirectoryEntry到指定位置。
        /// 
        /// 要移动的DirectoryEntry对象
        /// 移动到的位置的ADsPath。必须是DN形式。完全转义过的。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 被移动的对象和要移动到的位置对象必须使用DN形式的路径创建,不能使用GUID形式的路径,否则会引发异常。
        internal static void Move(DirectoryEntry de, string newLocationPath, string userName, string password)
        {
            if (!Exists(newLocationPath))
                throw new EntryNotExistException("移动到的位置对象不存在。");

            DirectoryEntry newLocation = null;
            try
            {
                newLocation = GetByPath(newLocationPath, userName, password);

                string newLocationDN = Utils.EscapeDNBackslashedChar(newLocation.Properties[BaseObject.PROPERTY_DN].Value.ToString());
                string deDN = Utils.EscapeDNBackslashedChar(de.Properties[BaseObject.PROPERTY_DN].Value.ToString());
                if (Exists(Utils.GenerateDN(Utils.GetRDN(deDN), deDN)))
                    throw new SameRDNException("移动到的位置下存在同名对象。");

                de.MoveTo(newLocation);

                de.CommitChanges();
            }
            catch (InvalidOperationException ioe)   // 指定的 DirectoryEntry 不是容器。
            {
                throw new NotContainerException(ioe.Message, ioe);
            }
            catch (DirectoryServicesCOMException dsce)
            {
                throw dsce;
            }
            finally
            {
                if (newLocation != null)
                {
                    newLocation.Close();
                    newLocation.Dispose();
                }
            }
        }


        /// 
        /// 获取应用程序设置的默认域。
        /// 
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 
        public static DirectoryEntry GetAppSetDomain(string userName, string password)
        {
            return GetByDN(ParaMgr.ADFullPath, userName, password);
        }

        /// 
        /// 获取应用程序设置的默认域,使用默认用户身份标识。
        /// 
        /// 
        public static DirectoryEntry GetAppSetDomain()
        {
            return GetAppSetDomain(null, null);
        }

        // 根据用户名和密码,判断是否应该使用默认用户身份标识。
        private static bool UseDefaultIdentity(string userName, string password)
        {
            if (String.IsNullOrEmpty(userName))
                return true;
            else
                return false;
        }


        #endregion


        #region Get & Search

        /// 
        /// 获取DirectoryEntry
        /// 
        /// 自定义模式
        /// 类型
        /// 类别
        /// 根对象DN,null表示整个域。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        internal static DirectoryEntry Get(string schema, string objectClass, string objectCategory, string rootDN, string userName, string password)
        {
            DirectoryEntry de = GetByDN((String.IsNullOrEmpty(rootDN) ? (ParaMgr.ADFullPath) : rootDN), 
                userName, password);

            DirectorySearcher deSearch = new DirectorySearcher();
            deSearch.SearchRoot = de;
            if (!String.IsNullOrEmpty(objectClass) ||
                !String.IsNullOrEmpty(objectCategory) ||
                !String.IsNullOrEmpty(schema))
            {
                deSearch.Filter = String.Format("(&{0}{1}{2})",
                    ((!String.IsNullOrEmpty(objectClass)) ? String.Format("(objectClass={0})", objectClass) : ""),
                    ((!String.IsNullOrEmpty(objectCategory)) ? String.Format("(objectCategory={0})", objectCategory) : ""),
                    ((!String.IsNullOrEmpty(schema)) ? String.Format("({0})", schema) : "")
                    );
            }
            deSearch.SearchScope = SearchScope.Subtree;
            SearchResult results = deSearch.FindOne();
            DirectoryEntry rde = null;
            if (results != null)
                rde = GetByPath(results.Path);
            else
                rde = null;

            de.Close();
            de.Dispose();

            return rde;
        }

        /// 
        /// 获取DirectoryEntry,使用默认用户身份标识。
        /// 
        /// 自定义模式
        /// 类型
        /// 类别
        /// 根对象DN,null表示整个域。
        /// 如果不存在,返回null。
        internal static DirectoryEntry Get(string schema, string objectClass, string objectCategory, string rootDN)
        {
            return Get(schema, objectClass, objectCategory, rootDN, null, null);
        }


        /// 
        /// 查找DirectoryEntry
        /// 
        /// 自定义模式
        /// 类型
        /// 类别
        /// 根对象ADsPath
        /// SearchScope
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回空集合。
        internal static List Search(string schema, string objectClass, string objectCategory,
            string rootPath, SearchScope scope, string userName, string password)
        {
            DirectoryEntry de = null;

            if (!String.IsNullOrEmpty(rootPath))
            {
                de = GetByPath(rootPath, userName, password);
            }
            if (de == null)
                de = GetByPath(ParaMgr.ADFullPath, userName, password);


            DirectorySearcher deSearch = new DirectorySearcher();
            if (de != null)
                deSearch.SearchRoot = de;
            if (!String.IsNullOrEmpty(objectClass) ||
                !String.IsNullOrEmpty(objectCategory) ||
                !String.IsNullOrEmpty(schema))
            {
                deSearch.Filter = String.Format("(&{0}{1}{2})",
                    ((!String.IsNullOrEmpty(objectClass)) ? String.Format("(objectClass={0})", objectClass) : ""),
                    ((!String.IsNullOrEmpty(objectCategory)) ? String.Format("(objectCategory={0})", objectCategory) : ""),
                    ((!String.IsNullOrEmpty(schema)) ? String.Format("({0})", schema) : "")
                    );
            }
            deSearch.SearchScope = scope;
            SearchResultCollection results = deSearch.FindAll();

            List entries = new List();
            if (results != null)
            {
                foreach (SearchResult se in results)
                {
                    //entries.Add(GetByPath(se.Path));
                    entries.Add(se.GetDirectoryEntry());
                }
            }

            de.Close();
            de.Dispose();

            return entries;

        }

        /// 
        /// 查找DirectoryEntry,使用默认用户身份标识。
        /// 
        /// 自定义模式
        /// 类型
        /// 类别
        /// 根对象ADsPath
        /// SearchScope
        /// 如果不存在,返回空集合。
        internal static List Search(string schema, string objectClass, string objectCategory, 
            string rootPath, SearchScope scope)
        {
            return Search(schema, objectClass, objectCategory, rootPath, scope, null, null);
        }

        /// 
        /// 查找DirectoryEntry,结果为字符串形式
        /// 
        /// 自定义模式
        /// 类型
        /// 类别
        /// 根对象ADsPath
        /// SearchScope
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回空集合。
        /// 包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass。
        /// 最后添加了sAMAccountName。
        internal static List Search2(string schema, string objectClass, string objectCategory,
            string rootPath, SearchScope scope, string userName, string password)
        {
            DirectoryEntry de = null;

            if (!String.IsNullOrEmpty(rootPath))
            {
                de = GetByPath(rootPath, userName, password);
            }
            if (de == null)
                de = GetByPath(ParaMgr.ADFullPath, userName, password);


            DirectorySearcher deSearch = new DirectorySearcher();
            if (de != null)
                deSearch.SearchRoot = de;
            if (!String.IsNullOrEmpty(objectClass) ||
                !String.IsNullOrEmpty(objectCategory) ||
                !String.IsNullOrEmpty(schema))
            {
                deSearch.Filter = String.Format("(&{0}{1}{2})",
                    ((!String.IsNullOrEmpty(objectClass)) ? String.Format("(objectClass={0})", objectClass) : ""),
                    ((!String.IsNullOrEmpty(objectCategory)) ? String.Format("(objectCategory={0})", objectCategory) : ""),
                    ((!String.IsNullOrEmpty(schema)) ? String.Format("({0})", schema) : "")
                    );
            }
            deSearch.SearchScope = scope;
            SearchResultCollection results = deSearch.FindAll();

            List entriesProperty = new List();
            if (results != null)
            {
                foreach (SearchResult se in results)
                {
                    string nativeGuid = "";
                    foreach(byte g in (byte[])se.Properties["objectguid"][0])
                    {
                        nativeGuid += g.ToString("x2");
                    }
                    string oc = "";
                    foreach (object c in se.Properties["objectclass"])
                    {
                        oc = oc + "," + c.ToString();
                    }

                    string sAMAccountName = null;
                    if (se.Properties.Contains("sAMAccountName"))
                        sAMAccountName = se.Properties["sAMAccountName"][0].ToString();


                    entriesProperty.Add(new string[] {
                        se.Properties["distinguishedname"][0].ToString(),
                        Utils.ConvertNativeGuidToGuid(nativeGuid).ToString(),
                        se.Properties["name"][0].ToString(),
                        ((se.Properties["description"].Count > 0) ? se.Properties["description"][0].ToString() : null),
                        se.Properties["adspath"][0].ToString(),
                        se.Properties["objectcategory"][0].ToString(),
                        oc.Substring(1),
                        sAMAccountName
                    });
                }
            }

            de.Close();
            de.Dispose();

            return entriesProperty;

        }

        /// 
        /// 查找DirectoryEntry,使用默认用户身份标识。结果为字符串形式
        /// 
        /// 自定义模式
        /// 类型
        /// 类别
        /// 根对象ADsPath
        /// SearchScope
        /// 如果不存在,返回空集合。
        /// 包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass
        internal static List Search2(string schema, string objectClass, string objectCategory,
            string rootPath, SearchScope scope)
        {
            return Search2(schema, objectClass, objectCategory, rootPath, scope, null, null);
        }

        /// 
        /// 查找DirectoryEntry
        /// 
        /// 自定义模式
        /// 类型
        /// 类别
        /// 根对象ADsPath
        /// SearchScope
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回空集合。
        internal static SearchResultCollection Search3(string schema, string objectClass, string objectCategory,
            string rootPath, SearchScope scope, string userName, string password)
        {
            DirectoryEntry de = null;

            if (!String.IsNullOrEmpty(rootPath))
            {
                de = GetByPath(rootPath, userName, password);
            }
            if (de == null)
                de = GetByPath(ParaMgr.ADFullPath, userName, password);


            DirectorySearcher deSearch = new DirectorySearcher();
            if (de != null)
                deSearch.SearchRoot = de;
            if (!String.IsNullOrEmpty(objectClass) ||
                !String.IsNullOrEmpty(objectCategory) ||
                !String.IsNullOrEmpty(schema))
            {
                deSearch.Filter = String.Format("(&{0}{1}{2})",
                    ((!String.IsNullOrEmpty(objectClass)) ? String.Format("(objectClass={0})", objectClass) : ""),
                    ((!String.IsNullOrEmpty(objectCategory)) ? String.Format("(objectCategory={0})", objectCategory) : ""),
                    ((!String.IsNullOrEmpty(schema)) ? String.Format("({0})", schema) : "")
                    );
            }
            deSearch.SearchScope = scope;
            
            SearchResultCollection results = deSearch.FindAll();

            de.Close();
            de.Dispose();

            return results;
        }

        /// 
        /// 查找DirectoryEntry,使用默认用户身份标识。
        /// 
        /// 自定义模式
        /// 类型
        /// 类别
        /// 根对象ADsPath
        /// SearchScope
        /// 如果不存在,返回空集合。
        internal static SearchResultCollection Search3(string schema, string objectClass, string objectCategory,
            string rootPath, SearchScope scope)
        {
            return Search3(schema, objectClass, objectCategory, rootPath, scope, null, null);
        }

        /// 
        /// 根据DirectoryEntry的Guid得到DirectoryEntry对象。
        /// 
        /// Guid
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        internal static DirectoryEntry GetByGuid(Guid guid, string userName, string password)
        {
            return GetByPath(Utils.GenerateADsPath(guid), userName, password);
        }

        /// 
        /// 根据DirectoryEntry的Guid得到DirectoryEntry对象,使用默认用户身份标识。
        /// 
        /// Guid
        /// 如果不存在,返回null。
        internal static DirectoryEntry GetByGuid(Guid guid)
        {
            return GetByGuid(guid, null,null );
        }


        /// 
        /// 根据DirectoryEntry的SID得到DirectoryEntry对象。
        /// 
        /// objectSID
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        internal static DirectoryEntry GetBySid(string sid, string userName, string password)
        {
            return Get("objectSID=" + sid, null, null, null, userName, password);
        }

        /// 
        /// 根据DirectoryEntry的SID得到DirectoryEntry对象,使用默认用户身份标识。
        /// 
        /// objectSID
        /// 如果不存在,返回null。
        internal static DirectoryEntry GetBySid(string sid)
        {
            return GetBySid(sid, null, null);
        }


        /// 
        /// 根据DirectoryEntry的DN得到DirectoryEntry对象。
        /// 
        /// DN。完全转义过的。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        internal static DirectoryEntry GetByDN(string dn, string userName, string password)
        {
            return GetByPath(ParaMgr.LDAP_IDENTITY + dn, userName, password);
        }

        /// 
        /// 根据DirectoryEntry的DN得到DirectoryEntry对象,使用默认用户身份标识。
        /// 
        /// DN。完全转义过的。
        /// 如果不存在,返回null。
        internal static DirectoryEntry GetByDN(string dn)
        {
            return GetByDN(dn, null, null);
        }


        /// 
        /// 根据DirectoryEntry的ADsPath得到DirectoryEntry对象。
        /// 
        /// 完整的ADsPath,自动添加LDAP_IDENTITY。完全转义过的。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        /// 
        internal static DirectoryEntry GetByPath(string path, string userName, string password)
        {
            if (Exists(path))
            {
                if (UseDefaultIdentity(userName, password))
                    return new DirectoryEntry((path.StartsWith(ParaMgr.LDAP_IDENTITY)) ? path : (ParaMgr.LDAP_IDENTITY + path));
                else
                    return new DirectoryEntry(
                        (path.StartsWith(ParaMgr.LDAP_IDENTITY)) ? path : (ParaMgr.LDAP_IDENTITY + path),
                        userName,
                        password,
                        AuthenticationTypes.Secure);

            }
            else
                return null;
        }
        
        /// 
        /// 根据DirectoryEntry的ADsPath得到DirectoryEntry对象,使用默认用户身份标识。
        /// 
        /// 完整的ADsPath。完全转义过的。
        /// 如果不存在,返回null。
        /// 
        internal static DirectoryEntry GetByPath(string path)
        {
            return GetByPath(path, null, null);
        }


        #endregion


        #region User

        #region Search

        /// 
        /// 获取指定所有用户。
        /// 
        /// 根对象ADsPath,null表示整个域。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        public static List GetUserAll(string rootPath, string userName, string password)
        {
            List entries = Search(null, "user", "person", rootPath, SearchScope.Subtree, userName, password);
            List users = new List();
            foreach (DirectoryEntry de in entries)
            {
                users.Add(new User(de));

                de.Close();
                de.Dispose();
            }

            return users;
        }

        /// 
        /// 获取指定所有用户,使用默认用户身份标识。
        /// 
        /// 根对象ADsPath,null表示整个域。
        /// 如果不存在,返回null。
        public static List GetUserAll(string rootPath)
        {
            return GetUserAll(rootPath, null, null);
        }

        /// 
        /// 获取指定所有用户。
        /// 
        /// 根对象ADsPath,null表示整个域。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        /// 包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass。
        /// 最后添加了sAMAccountName。
        public static List GetUserAllSimple(string rootPath, string userName, string password)
        {
            return Search2(null, "user", "person", rootPath, SearchScope.Subtree, userName, password);
        }

        /// 
        /// 获取指定所有用户,使用默认用户身份标识。
        /// 
        /// 根对象ADsPath,null表示整个域。
        /// 如果不存在,返回null。
        /// 包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass
        public static List GetUserAllSimple(string rootPath)
        {
            return GetUserAllSimple(rootPath, null, null);
        }

        /// 
        /// 获取指定所有用户。直接解析查询结果,速度较GetUserAll快。
        /// 
        /// 根对象ADsPath,null表示整个域。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        public static List GetUserAllQuick(string rootPath, string userName, string password)
        {
            SearchResultCollection results = Search3(null, "user", "person", rootPath, SearchScope.Subtree, userName, password);

            List users = new List();
            foreach (SearchResult se in results)
            {
                users.Add(new User(se));
            }

            return users;
        }

        /// 
        /// 获取指定所有用户,使用默认用户身份标识。直接解析查询结果,速度较GetUserAll快。
        /// 
        /// 根对象ADsPath,null表示整个域。
        /// 如果不存在,返回null。
        public static List GetUserAllQuick(string rootPath)
        {
            return GetUserAllQuick(rootPath, null, null);
        }

        /// 
        /// 根据userPrincipalName获取Group。
        /// 
        /// userPrincipalName。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        public static User GetUserByPrincipalName(string userPrincipalName, string userName, string password)
        {
            List entries = Search("userPrincipalName=" + Utils.Escape4Query(userPrincipalName), 
                "user", "person", null, SearchScope.Subtree, userName, password);
            if (entries.Count == 1)
            {
                DirectoryEntry de = entries[0];

                User user = new User(de);

                de.Close();
                de.Dispose();

                return user;
            }

            return null;
        }

        /// 
        /// 根据sAMAccountName获取User。
        /// 
        /// sAMAccountName。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        public static User GetUserBySAMAccountName(string sAMAccountName, string userName, string password)
        {
            List entries = Search("sAMAccountName=" + Utils.Escape4Query(sAMAccountName), 
                "user", "person", null, SearchScope.Subtree, userName, password);
            if (entries.Count == 1)
            {
                DirectoryEntry de = entries[0];

                User user = new User(de);

                de.Close();
                de.Dispose();

                return user;
            }

            return null;
        }
        #endregion

        #region Get

        /// 
        /// 根据用户的Guid得到用户对象。
        /// 
        /// Guid
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        public static User GetUserByGuid(Guid guid, string userName, string password)
        {
            return GetUserByPath(Utils.GenerateADsPath(guid), userName, password);
        }

        /// 
        /// 根据用户的Guid得到用户对象,使用默认用户身份标识。
        /// 
        /// Guid
        /// 如果不存在,返回null。
        public static User GetUserByGuid(Guid guid)
        {
            return GetUserByGuid(guid, null, null);
        }

        /// 
        /// 根据用户的DN得到用户对象。
        /// 
        /// DN。完全转义过的。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        public static User GetUserByDN(string dn, string userName, string password)
        {
            return GetUserByPath(dn, userName, password);    
        }

        /// 
        /// 根据用户的DN得到用户对象,使用默认用户身份标识。
        /// 
        /// DN。完全转义过的。
        /// 如果不存在,返回null。
        public static User GetUserByDN(string dn)
        {
            return GetUserByDN(dn, null, null);
        }

        /// 
        /// 根据用户的ADsPath得到用户对象。
        /// 
        /// ADsPath。完全转义过的。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        public static User GetUserByPath(string path, string userName, string password)
        {
            DirectoryEntry entry = GetByPath(path, userName, password);
            if (entry != null)
            {
                User user = new User(entry);
                entry.Close();
                entry.Dispose();

                return user;
            }
            else
                return null;
        }

        /// 
        /// 根据用户的ADsPath得到用户对象,使用默认用户身份标识。
        /// 
        /// ADsPath。完全转义过的。
        /// 如果不存在,返回null。
        public static User GetUserByPath(string path)
        {
            return GetUserByPath(path, null, null);
        }

        #endregion

        #region Password

        /// 
        /// 设置用户密码。
        /// 
        /// 用户DirectoryEntry的Guid。
        /// 新密码。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        public static void SetUserPassword(Guid guid, string newPassword, string userName, string password)
        {
            DirectoryEntry de = null;
            try
            {
                de = GetByGuid(guid, userName, password);

                if (de == null)
                    throw new EntryNotExistException("用户对象不存在。");

                if (de.SchemaClassName != SchemaClass.user.ToString("F"))
                    throw new SchemaClassException("对象类型不是" + SchemaClass.user.ToString("F") + "。");

                de.Invoke("SetPassword", new object[] { newPassword });

                de.CommitChanges();
            }
            catch (DirectoryServicesCOMException dsce)
            {
                throw dsce;
            }
            finally
            {
                if (de != null)
                {
                    de.Close();
                    de.Dispose();
                }
            }
        }

        /// 
        /// 设置用户密码,使用默认用户身份标识。
        /// 
        /// 用户DirectoryEntry的Guid。
        /// 新密码。
        public static void SetUserPassword(Guid guid, string newPassword)
        {
            SetUserPassword(guid, newPassword, null, null);
        }

        #endregion

        #region Move

        /// 
        /// 移动用户DirectoryEntry到指定位置。
        /// 
        /// 要移动的用户DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。
        /// 移动到的位置的ADsPath。必须是DN形式。完全转义过的。
        /// 移动到的位置对应的DirectoryEntry是否必须是组织单位。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        public static void MoveUser(string userPath, string newLocationPath, bool mustOU, string userName, string password)
        {
            if (!Exists(userPath))
                throw new EntryNotExistException("需要被移动的对象不存在。");

            DirectoryEntry de = null;
            try
            {
                de = GetByPath(userPath, userName, password);

                MoveUser(de, newLocationPath, mustOU, userName, password);
            }
            catch
            {
                throw;
            }
            finally
            {
                if (de != null)
                {
                    de.Close();
                    de.Dispose();
                }
            }
        }

        /// 
        /// 移动用户DirectoryEntry到指定位置,使用默认用户身份标识。
        /// 
        /// 要移动的用户DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。
        /// 移动到的位置的ADsPath。必须是DN形式。完全转义过的。
        /// 移动到的位置对应的DirectoryEntry是否必须是组织单位。
        public static void MoveUser(string userPath, string newLocationPath, bool mustOU)
        {
            MoveUser(userPath, newLocationPath, mustOU, null, null);
        }

        /// 
        /// 移动用户DirectoryEntry到指定位置。
        /// 
        /// 要移动的用户DirectoryEntry的Guid
        /// 移动到的位置的Guid
        /// 移动到的位置对应的DirectoryEntry是否必须是组织单位。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        public static void MoveUser(Guid user, Guid newLocation, bool mustOU, string userName, string password)
        {
            MoveUser(GetUserByGuid(user).Dn, GetOUByGuid(newLocation).Dn, mustOU, userName, password);
        }

        /// 
        /// 移动用户DirectoryEntry到指定位置,使用默认用户身份标识。
        /// 
        /// 要移动的用户DirectoryEntry的Guid
        /// 移动到的位置的Guid
        /// 移动到的位置对应的DirectoryEntry是否必须是组织单位。
        public static void MoveUser(Guid user, Guid newLocation, bool mustOU)
        {
            MoveUser(GetUserByGuid(user).Dn, GetOUByGuid(newLocation).Dn, mustOU, null, null);
        }

        /// 
        /// 移动用户DirectoryEntry到指定位置。
        /// 
        /// 要移动的用户DirectoryEntry对象。必须是通过DN形式路径得到的对象。
        /// 移动到的位置的ADsPath。必须是DN形式。完全转义过的。
        /// 移动到的位置对应的DirectoryEntry是否必须是组织单位。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        internal static void MoveUser(DirectoryEntry de, string newLocationPath, bool mustOU, string userName, string password)
        {
            if (!Exists(newLocationPath))
                throw new EntryNotExistException("移动到的位置对象不存在。");

            DirectoryEntry newLocation = null;
            try
            {
                newLocation = GetByPath(newLocationPath, userName, password);

                if (de.SchemaClassName != SchemaClass.user.ToString("F"))
                    throw new SchemaClassException("需要被移动的对象类型不是" + SchemaClass.user.ToString("F") + "。");

                if (mustOU && newLocation.SchemaClassName != SchemaClass.organizationalUnit.ToString("F"))
                    throw new SchemaClassException("移动到的位置对象类型不是" + SchemaClass.organizationalUnit.ToString("F") + "。");

                if (Exists(Utils.GetRDNValue(de.Properties[BaseObject.PROPERTY_DN].Value.ToString()) + "," +
                    newLocation.Properties[BaseObject.PROPERTY_DN].Value.ToString()))
                    throw new SameRDNException("移动到的位置下存在同名对象。");

                de.MoveTo(newLocation);
                de.CommitChanges();
            }
            catch (InvalidOperationException ioe)   // 指定的 DirectoryEntry 不是容器。
            {
                throw new NotContainerException(ioe.Message, ioe);
            }
            catch (DirectoryServicesCOMException dsce)
            {
                throw dsce;
            }
            finally
            {
                if (newLocation != null)
                {
                    newLocation.Close();
                    newLocation.Dispose();
                }
            }
        }

        #endregion

        #region MemberOf

        /// 
        /// 获取用户DirectoryEntry对象的PrimaryGroup DirectoryEntry对象。
        /// 
        /// 用户DirectoryEntry的ADsPath。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 不存在返回null。
        public static DirectoryEntry GetUserPrimaryGroup(string userPath, string userName, string password)
        {
            DirectoryEntry de = GetByPath(userPath, userName, password);

            if (de == null)
                throw new EntryNotExistException("用户对象不存在。");

            if (de.SchemaClassName != SchemaClass.user.ToString("F"))
                throw new SchemaClassException("对象类型不是" + SchemaClass.user.ToString("F") + "。");

            return GetUserPrimaryGroup(de, userName, password);
        }

        /// 
        /// 获取用户DirectoryEntry对象的PrimaryGroup DirectoryEntry对象,使用默认用户身份标识。
        /// 
        /// 用户DirectoryEntry的ADsPath。
        /// 不存在返回null。
        public static DirectoryEntry GetUserPrimaryGroup(string userPath)
        {
            return GetUserPrimaryGroup(userPath, null, null);
        }

        /// 
        /// 获取用户DirectoryEntry对象的PrimaryGroup DirectoryEntry对象。
        /// 
        /// 用户DirectoryEntry对象。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 不存在返回null。
        internal static DirectoryEntry GetUserPrimaryGroup(DirectoryEntry user, string userName, string password)
        {
            string primaryGroupSID = User.GeneratePrimaryGroupSID((byte[])(user.Properties[BaseObject.PROPERTY_OBJECTSID].Value),
                Convert.ToInt32(user.Properties[User.PROPERTY_MEMBEROF_PRIMARY].Value));

            return GetBySid(primaryGroupSID, userName, password);
        }

        /// 
        /// 获取用户DirectoryEntry对象的隶属组的DN。
        /// 
        /// 用户DirectoryEntry的ADsPath。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 是否包括PrimaryGroup
        /// 不存在返回空集合。
        public static List GetUserMemberOfDN(string userPath, string userName, string password, bool includePrimaryGroup)
        {
            DirectoryEntry de = GetByPath(userPath, userName, password);

            if (de == null)
                throw new EntryNotExistException("用户对象不存在。");

            if (de.SchemaClassName != SchemaClass.user.ToString("F"))
                throw new SchemaClassException("对象类型不是" + SchemaClass.user.ToString("F") + "。");

            List dn = new List();

            if (includePrimaryGroup)
            {
                DirectoryEntry primary = GetUserPrimaryGroup(de, userName, password);
                if (primary != null)
                {
                    dn.Add(Utils.EscapeDNBackslashedChar(primary.Properties[BaseObject.PROPERTY_DN].Value.ToString()));

                    primary.Close();
                    primary.Dispose();
                }
            }
            if (de.Properties.Contains(User.PROPERTY_MEMBEROF_ALL))
            {
                foreach (object m in de.Properties[User.PROPERTY_MEMBEROF_ALL])
                {
                    dn.Add(Utils.EscapeDNBackslashedChar(m.ToString()));        // 转义/
                }
            }

            de.Close();
            de.Dispose();

            return dn;
        }

        /// 
        /// 获取用户DirectoryEntry对象的隶属组的DN,使用默认用户身份标识。
        /// 
        /// 用户DirectoryEntry的ADsPath。
        /// 是否包括PrimaryGroup
        /// 不存在返回空集合。
        public static List GetUserMemberOfDN(string userPath, bool includePrimaryGroup)
        {
            return GetUserMemberOfDN(userPath, null, null, includePrimaryGroup);
        }

        #endregion

        #endregion


        #region Group

        #region Search

        /// 
        /// 获取指定所有组。
        /// 
        /// 组CN。
        /// 组描述。
        /// 根对象ADsPath,null表示整个域。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        public static List SearchGroup(string cn, string description, string rootPath, string userName, string password)
        {
            string schema = null;
            if (!String.IsNullOrEmpty(cn) || !String.IsNullOrEmpty(description))
                schema = String.Format("(&{0}{1})", 
                    (!String.IsNullOrEmpty(cn) ? String.Format("(cn=*{0}*)", Utils.Escape4Query(cn)) : "" ),
                    (!String.IsNullOrEmpty(description) ? String.Format("(description=*{0}*)", Utils.Escape4Query(description)) : ""));

            List entries = Search(schema, "group", null, rootPath, SearchScope.Subtree, userName, password);
            List groups = new List();
            foreach (DirectoryEntry de in entries)
            {
                groups.Add(new Group(de));

                de.Close();
                de.Dispose();
            }

            return groups;
        }

        /// 
        /// 获取指定所有组,使用默认用户身份标识。
        /// 
        /// 组CN。
        /// 组描述。
        /// 根对象ADsPath,null表示整个域。
        /// 如果不存在,返回null。
        public static List SearchGroup(string cn, string description, string rootPath)
        {
            return SearchGroup(cn, description, rootPath, null, null);
        }

        /// 
        /// 获取指定所有组。
        /// 
        /// 组CN。
        /// 组描述。
        /// 根对象ADsPath,null表示整个域。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        /// 包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass。
        /// 最后添加了sAMAccountName。
        public static List SearchGroupSimple(string cn, string description, string rootPath, string userName, string password)
        {
            string schema = null;
            if (!String.IsNullOrEmpty(cn) || !String.IsNullOrEmpty(description))
                schema = String.Format("&{0}{1}",
                    (!String.IsNullOrEmpty(cn) ? String.Format("(cn=*{0}*)", Utils.Escape4Query(cn)) : ""),
                    (!String.IsNullOrEmpty(description) ? String.Format("(cn=*{0}*)", Utils.Escape4Query(description)) : ""));

            return Search2(schema, "group", null, rootPath, SearchScope.Subtree, userName, password);
        }

        /// 
        /// 获取指定所有组,使用默认用户身份标识。
        /// 
        /// 组CN。
        /// 组描述。
        /// 根对象ADsPath,null表示整个域。
        /// 如果不存在,返回null。
        /// 包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass
        public static List SearchGroupSimple(string cn, string description, string rootPath)
        {
            return SearchGroupSimple(cn, description, rootPath, null, null);
        }

        /// 
        /// 获取指定所有组。直接解析查询结果,速度较SearchGroup快。
        /// 
        /// 组CN。
        /// 组描述。
        /// 根对象ADsPath,null表示整个域。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        public static List SearchGroupQuick(string cn, string description, string rootPath, string userName, string password)
        {
            string schema = null;
            if (!String.IsNullOrEmpty(cn) || !String.IsNullOrEmpty(description))
                schema = String.Format("&{0}{1}",
                    (!String.IsNullOrEmpty(cn) ? String.Format("(cn=*{0}*)", Utils.Escape4Query(cn)) : ""),
                    (!String.IsNullOrEmpty(description) ? String.Format("(cn=*{0}*)", Utils.Escape4Query(description)) : ""));

            SearchResultCollection results = Search3(schema, "group", null, rootPath, SearchScope.Subtree, userName, password);

            List groups = new List();
            foreach (SearchResult se in results)
            {
                groups.Add(new Group(se));
            }

            return groups;
        }

        /// 
        /// 获取指定所有组,使用默认用户身份标识。直接解析查询结果,速度较SearchGroup快。
        /// 
        /// 组CN。
        /// 组描述。
        /// 根对象ADsPath,null表示整个域。
        /// 如果不存在,返回null。
        public static List SearchGroupQuick(string cn, string description, string rootPath)
        {
            return SearchGroupQuick(null,null, rootPath, null, null);
        }

        /// 
        /// 根据sAMAccountName获取Group。
        /// 
        /// sAMAccountName。
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        public static Group GetGroupBySAMAccountName(string sAMAccountName, string userName, string password)
        {
            List entries = Search("sAMAccountName=" + Utils.Escape4Query(sAMAccountName), 
                "group", null, null, SearchScope.Subtree, userName, password);
            if (entries.Count == 1)
            {
                DirectoryEntry de = entries[0];

                Group group = new Group(de);

                de.Close();
                de.Dispose();

                return group;
            }

            return null;
        }

        #endregion

        #region Get

        /// 
        /// 根据用户的Guid得到组对象。
        /// 
        /// Guid
        /// 用户身份标识--用户名。为空时使用默认用户身份标识。
        /// 用户身份标识--密码。
        /// 如果不存在,返回null。
        public static Group GetGroupByGuid(Guid guid, string userName, string password)
        {
            return GetGroupByPath(Utils.GenerateADsPath(guid), userName, password);

        }

        /// 
        /// 根据用户的Guid得到组对象,使用默认用户身份标识。
        /// 
        /// Guid
        /// 如果不存在,返回null。
        public static Group GetGroupByGuid(G


评论


亲,登录后才可以留言!