首页 > 代码库 > 操作Active Directory C#

操作Active Directory C#

 

.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{    /// <summary>    /// 用于进行AD管理里的对象,提供操作AD的静态方法。    /// </summary>    /// <remarks>    /// 这里ADsPath可以是LDAP://DN和LDAP://<GUID>两种形式,但不限于这种形式。    /// 一般方法均提供2种形式,一种是用参数提供的用户身份标识,一种是用默认的用户身份标识。    /// 默认用户身份标识取决于当前进程的用户身份标识。    /// </remarks>    public class ADManager    {        #region 域信息        /// <summary>        /// 将友好的域名称(friendly domain name)转换为合格的域名称(fully qualified domain name)。        /// eg:tb -- > tb.com        /// </summary>        /// <param name="friendlyDomainName">友好的域名称(friendly domain name)。        /// 可以是:        /// 域控制器的 DNS 名称。        /// ADAM 服务器的 DNS 名称和 LDAP 端口号(如 adam_instance.fabrikam.com:389)。        /// 域的 DNS 名称,如 sales.corp.fabrikam.com。        /// 林的 DNS 名称,如 corp.fabrikam.com。        /// 应用程序分区的 DNS 名称。        /// 与服务连接点关联的关键字之一,该服务连接点由配置集的 ADAM 实例注册。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns></returns>        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;        }        /// <summary>        /// 将友好的域名称(friendly domain name)转换为合格的域名称(fully qualified domain name)。        /// eg:tb -- > tb.com        /// </summary>        /// <param name="friendlyDomainName">友好的域名称(friendly domain name)。        /// 可以是:        /// 域控制器的 DNS 名称。        /// ADAM 服务器的 DNS 名称和 LDAP 端口号(如 adam_instance.fabrikam.com:389)。        /// 域的 DNS 名称,如 sales.corp.fabrikam.com。        /// 林的 DNS 名称,如 corp.fabrikam.com。        /// 应用程序分区的 DNS 名称。        /// 与服务连接点关联的关键字之一,该服务连接点由配置集的 ADAM 实例注册。</param>        /// <returns></returns>        public static string FriendlyDomainToLdapDomain(string friendlyDomainName)        {            return FriendlyDomainToLdapDomain(friendlyDomainName, null, null);        }        /// <summary>        /// 获取当前用户上下文的 Forest 对象中的所有域名称。        /// </summary>        /// <returns></returns>        public static List<string> EnumerateDomains()        {            List<string> alDomains = new List<string>();            Forest currentForest = Forest.GetCurrentForest();            DomainCollection myDomains = currentForest.Domains;            foreach (System.DirectoryServices.ActiveDirectory.Domain objDomain in myDomains)            {                alDomains.Add(objDomain.Name);            }            return alDomains;        }        /// <summary>        /// 获取当前用户上下文的 Forest 对象中所有的全局目录。         /// </summary>        /// <returns></returns>        public static List<string> EnumerateGlobalCatalogs()        {            List<string> alGCs = new List<string>();            Forest currentForest = Forest.GetCurrentForest();            foreach (GlobalCatalog gc in currentForest.GlobalCatalogs)            {                alGCs.Add(gc.Name);            }            return alGCs;        }        /// <summary>        /// 获取当前用户身份标识的 Domain 对象中的域控制器。        /// </summary>        /// <returns></returns>        public static List<string> EnumerateDomainControllers()        {            List<string> alDcs = new List<string>();            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        /// <summary>        /// 检验指定的DirectoryEntry是否存在        /// </summary>        /// <param name="path">ADsPath,自动添加LDAP_IDENTITY。完全转义过的。</param>        /// <returns></returns>        public static bool Exists(string path)        {            if (path.StartsWith(ParaMgr.LDAP_IDENTITY))                return DirectoryEntry.Exists(path);            else                return DirectoryEntry.Exists(ParaMgr.LDAP_IDENTITY + path);        }        /// <summary>        /// 移动DirectoryEntry到指定位置。        /// </summary>        /// <param name="objectPath">要移动的DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。</param>        /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <remarks>被移动的对象和要移动到的位置对象必须使用DN形式的路径创建,不能使用GUID形式的路径,否则会引发异常。</remarks>        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();                }            }        }        /// <summary>        /// 移动DirectoryEntry到指定位置,使用默认用户身份标识。        /// </summary>        /// <param name="objectPath">要移动的DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。</param>        /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>        public static void Move(string objectPath, string newLocationPath)        {            Move(objectPath, newLocationPath, null, null);        }        /// <summary>        /// 移动DirectoryEntry到指定位置。        /// </summary>        /// <param name="de">要移动的DirectoryEntry对象</param>        /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <remarks>被移动的对象和要移动到的位置对象必须使用DN形式的路径创建,不能使用GUID形式的路径,否则会引发异常。</remarks>        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();                }            }        }        /// <summary>        /// 获取应用程序设置的默认域。        /// </summary>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns></returns>        public static DirectoryEntry GetAppSetDomain(string userName, string password)        {            return GetByDN(ParaMgr.ADFullPath, userName, password);        }        /// <summary>        /// 获取应用程序设置的默认域,使用默认用户身份标识。        /// </summary>        /// <returns></returns>        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        /// <summary>        /// 获取DirectoryEntry        /// </summary>        /// <param name="schema">自定义模式</param>        /// <param name="objectClass">类型</param>        /// <param name="objectCategory">类别</param>        /// <param name="rootDN">根对象DN,null表示整个域。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        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;        }        /// <summary>        /// 获取DirectoryEntry,使用默认用户身份标识。        /// </summary>        /// <param name="schema">自定义模式</param>        /// <param name="objectClass">类型</param>        /// <param name="objectCategory">类别</param>        /// <param name="rootDN">根对象DN,null表示整个域。</param>        /// <returns>如果不存在,返回null。</returns>        internal static DirectoryEntry Get(string schema, string objectClass, string objectCategory, string rootDN)        {            return Get(schema, objectClass, objectCategory, rootDN, null, null);        }        /// <summary>        /// 查找DirectoryEntry        /// </summary>        /// <param name="schema">自定义模式</param>        /// <param name="objectClass">类型</param>        /// <param name="objectCategory">类别</param>        /// <param name="rootPath">根对象ADsPath</param>        /// <param name="scope">SearchScope</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回空集合。</returns>        internal static List<DirectoryEntry> 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<DirectoryEntry> entries = new List<DirectoryEntry>();            if (results != null)            {                foreach (SearchResult se in results)                {                    //entries.Add(GetByPath(se.Path));                    entries.Add(se.GetDirectoryEntry());                }            }            de.Close();            de.Dispose();            return entries;        }        /// <summary>        /// 查找DirectoryEntry,使用默认用户身份标识。        /// </summary>        /// <param name="schema">自定义模式</param>        /// <param name="objectClass">类型</param>        /// <param name="objectCategory">类别</param>        /// <param name="rootPath">根对象ADsPath</param>        /// <param name="scope">SearchScope</param>        /// <returns>如果不存在,返回空集合。</returns>        internal static List<DirectoryEntry> Search(string schema, string objectClass, string objectCategory,             string rootPath, SearchScope scope)        {            return Search(schema, objectClass, objectCategory, rootPath, scope, null, null);        }        /// <summary>        /// 查找DirectoryEntry,结果为字符串形式        /// </summary>        /// <param name="schema">自定义模式</param>        /// <param name="objectClass">类型</param>        /// <param name="objectCategory">类别</param>        /// <param name="rootPath">根对象ADsPath</param>        /// <param name="scope">SearchScope</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回空集合。</returns>        /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass。        /// 最后添加了sAMAccountName。</remarks>        internal static List<string[]> 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<string[]> entriesProperty = new List<string[]>();            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;        }        /// <summary>        /// 查找DirectoryEntry,使用默认用户身份标识。结果为字符串形式        /// </summary>        /// <param name="schema">自定义模式</param>        /// <param name="objectClass">类型</param>        /// <param name="objectCategory">类别</param>        /// <param name="rootPath">根对象ADsPath</param>        /// <param name="scope">SearchScope</param>        /// <returns>如果不存在,返回空集合。</returns>        /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass</remarks>        internal static List<string[]> Search2(string schema, string objectClass, string objectCategory,            string rootPath, SearchScope scope)        {            return Search2(schema, objectClass, objectCategory, rootPath, scope, null, null);        }        /// <summary>        /// 查找DirectoryEntry        /// </summary>        /// <param name="schema">自定义模式</param>        /// <param name="objectClass">类型</param>        /// <param name="objectCategory">类别</param>        /// <param name="rootPath">根对象ADsPath</param>        /// <param name="scope">SearchScope</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回空集合。</returns>        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;        }        /// <summary>        /// 查找DirectoryEntry,使用默认用户身份标识。        /// </summary>        /// <param name="schema">自定义模式</param>        /// <param name="objectClass">类型</param>        /// <param name="objectCategory">类别</param>        /// <param name="rootPath">根对象ADsPath</param>        /// <param name="scope">SearchScope</param>        /// <returns>如果不存在,返回空集合。</returns>        internal static SearchResultCollection Search3(string schema, string objectClass, string objectCategory,            string rootPath, SearchScope scope)        {            return Search3(schema, objectClass, objectCategory, rootPath, scope, null, null);        }        /// <summary>        /// 根据DirectoryEntry的Guid得到DirectoryEntry对象。        /// </summary>        /// <param name="guid">Guid</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        internal static DirectoryEntry GetByGuid(Guid guid, string userName, string password)        {            return GetByPath(Utils.GenerateADsPath(guid), userName, password);        }        /// <summary>        /// 根据DirectoryEntry的Guid得到DirectoryEntry对象,使用默认用户身份标识。        /// </summary>        /// <param name="guid">Guid</param>        /// <returns>如果不存在,返回null。</returns>        internal static DirectoryEntry GetByGuid(Guid guid)        {            return GetByGuid(guid, null,null );        }        /// <summary>        /// 根据DirectoryEntry的SID得到DirectoryEntry对象。        /// </summary>        /// <param name="sid">objectSID</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        internal static DirectoryEntry GetBySid(string sid, string userName, string password)        {            return Get("objectSID=" + sid, null, null, null, userName, password);        }        /// <summary>        /// 根据DirectoryEntry的SID得到DirectoryEntry对象,使用默认用户身份标识。        /// </summary>        /// <param name="sid">objectSID</param>        /// <returns>如果不存在,返回null。</returns>        internal static DirectoryEntry GetBySid(string sid)        {            return GetBySid(sid, null, null);        }        /// <summary>        /// 根据DirectoryEntry的DN得到DirectoryEntry对象。        /// </summary>        /// <param name="dn">DN。完全转义过的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        internal static DirectoryEntry GetByDN(string dn, string userName, string password)        {            return GetByPath(ParaMgr.LDAP_IDENTITY + dn, userName, password);        }        /// <summary>        /// 根据DirectoryEntry的DN得到DirectoryEntry对象,使用默认用户身份标识。        /// </summary>        /// <param name="dn">DN。完全转义过的。</param>        /// <returns>如果不存在,返回null。</returns>        internal static DirectoryEntry GetByDN(string dn)        {            return GetByDN(dn, null, null);        }        /// <summary>        /// 根据DirectoryEntry的ADsPath得到DirectoryEntry对象。        /// </summary>        /// <param name="path">完整的ADsPath,自动添加LDAP_IDENTITY。完全转义过的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        /// <returns></returns>        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;        }                /// <summary>        /// 根据DirectoryEntry的ADsPath得到DirectoryEntry对象,使用默认用户身份标识。        /// </summary>        /// <param name="path">完整的ADsPath。完全转义过的。</param>        /// <returns>如果不存在,返回null。</returns>        /// <returns></returns>        internal static DirectoryEntry GetByPath(string path)        {            return GetByPath(path, null, null);        }        #endregion        #region User        #region Search        /// <summary>        /// 获取指定所有用户。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<User> GetUserAll(string rootPath, string userName, string password)        {            List<DirectoryEntry> entries = Search(null, "user", "person", rootPath, SearchScope.Subtree, userName, password);            List<User> users = new List<User>();            foreach (DirectoryEntry de in entries)            {                users.Add(new User(de));                de.Close();                de.Dispose();            }            return users;        }        /// <summary>        /// 获取指定所有用户,使用默认用户身份标识。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<User> GetUserAll(string rootPath)        {            return GetUserAll(rootPath, null, null);        }        /// <summary>        /// 获取指定所有用户。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass。        /// 最后添加了sAMAccountName。</remarks>        public static List<string[]> GetUserAllSimple(string rootPath, string userName, string password)        {            return Search2(null, "user", "person", rootPath, SearchScope.Subtree, userName, password);        }        /// <summary>        /// 获取指定所有用户,使用默认用户身份标识。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <returns>如果不存在,返回null。</returns>        /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass</remarks>        public static List<string[]> GetUserAllSimple(string rootPath)        {            return GetUserAllSimple(rootPath, null, null);        }        /// <summary>        /// 获取指定所有用户。直接解析查询结果,速度较GetUserAll快。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<User> GetUserAllQuick(string rootPath, string userName, string password)        {            SearchResultCollection results = Search3(null, "user", "person", rootPath, SearchScope.Subtree, userName, password);            List<User> users = new List<User>();            foreach (SearchResult se in results)            {                users.Add(new User(se));            }            return users;        }        /// <summary>        /// 获取指定所有用户,使用默认用户身份标识。直接解析查询结果,速度较GetUserAll快。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<User> GetUserAllQuick(string rootPath)        {            return GetUserAllQuick(rootPath, null, null);        }        /// <summary>        /// 根据userPrincipalName获取Group。        /// </summary>        /// <param name="userPrincipalName">userPrincipalName。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static User GetUserByPrincipalName(string userPrincipalName, string userName, string password)        {            List<DirectoryEntry> 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;        }        /// <summary>        /// 根据sAMAccountName获取User。        /// </summary>        /// <param name="sAMAccountName">sAMAccountName。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static User GetUserBySAMAccountName(string sAMAccountName, string userName, string password)        {            List<DirectoryEntry> 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        /// <summary>        /// 根据用户的Guid得到用户对象。        /// </summary>        /// <param name="guid">Guid</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static User GetUserByGuid(Guid guid, string userName, string password)        {            return GetUserByPath(Utils.GenerateADsPath(guid), userName, password);        }        /// <summary>        /// 根据用户的Guid得到用户对象,使用默认用户身份标识。        /// </summary>        /// <param name="guid">Guid</param>        /// <returns>如果不存在,返回null。</returns>        public static User GetUserByGuid(Guid guid)        {            return GetUserByGuid(guid, null, null);        }        /// <summary>        /// 根据用户的DN得到用户对象。        /// </summary>        /// <param name="dn">DN。完全转义过的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static User GetUserByDN(string dn, string userName, string password)        {            return GetUserByPath(dn, userName, password);            }        /// <summary>        /// 根据用户的DN得到用户对象,使用默认用户身份标识。        /// </summary>        /// <param name="dn">DN。完全转义过的。</param>        /// <returns>如果不存在,返回null。</returns>        public static User GetUserByDN(string dn)        {            return GetUserByDN(dn, null, null);        }        /// <summary>        /// 根据用户的ADsPath得到用户对象。        /// </summary>        /// <param name="path">ADsPath。完全转义过的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        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;        }        /// <summary>        /// 根据用户的ADsPath得到用户对象,使用默认用户身份标识。        /// </summary>        /// <param name="path">ADsPath。完全转义过的。</param>        /// <returns>如果不存在,返回null。</returns>        public static User GetUserByPath(string path)        {            return GetUserByPath(path, null, null);        }        #endregion        #region Password        /// <summary>        /// 设置用户密码。        /// </summary>        /// <param name="guid">用户DirectoryEntry的Guid。</param>        /// <param name="newPassword">新密码。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        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();                }            }        }        /// <summary>        /// 设置用户密码,使用默认用户身份标识。        /// </summary>        /// <param name="guid">用户DirectoryEntry的Guid。</param>        /// <param name="newPassword">新密码。</param>        public static void SetUserPassword(Guid guid, string newPassword)        {            SetUserPassword(guid, newPassword, null, null);        }        #endregion        #region Move        /// <summary>        /// 移动用户DirectoryEntry到指定位置。        /// </summary>        /// <param name="userPath">要移动的用户DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。</param>        /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>        /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        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();                }            }        }        /// <summary>        /// 移动用户DirectoryEntry到指定位置,使用默认用户身份标识。        /// </summary>        /// <param name="userPath">要移动的用户DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。</param>        /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>        /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>        public static void MoveUser(string userPath, string newLocationPath, bool mustOU)        {            MoveUser(userPath, newLocationPath, mustOU, null, null);        }        /// <summary>        /// 移动用户DirectoryEntry到指定位置。        /// </summary>        /// <param name="user">要移动的用户DirectoryEntry的Guid</param>        /// <param name="newLocation">移动到的位置的Guid</param>        /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        public static void MoveUser(Guid user, Guid newLocation, bool mustOU, string userName, string password)        {            MoveUser(GetUserByGuid(user).Dn, GetOUByGuid(newLocation).Dn, mustOU, userName, password);        }        /// <summary>        /// 移动用户DirectoryEntry到指定位置,使用默认用户身份标识。        /// </summary>        /// <param name="user">要移动的用户DirectoryEntry的Guid</param>        /// <param name="newLocation">移动到的位置的Guid</param>        /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>        public static void MoveUser(Guid user, Guid newLocation, bool mustOU)        {            MoveUser(GetUserByGuid(user).Dn, GetOUByGuid(newLocation).Dn, mustOU, null, null);        }        /// <summary>        /// 移动用户DirectoryEntry到指定位置。        /// </summary>        /// <param name="de">要移动的用户DirectoryEntry对象。必须是通过DN形式路径得到的对象。</param>        /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>        /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        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        /// <summary>        /// 获取用户DirectoryEntry对象的PrimaryGroup DirectoryEntry对象。        /// </summary>        /// <param name="userPath">用户DirectoryEntry的ADsPath。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>不存在返回null。</returns>        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);        }        /// <summary>        /// 获取用户DirectoryEntry对象的PrimaryGroup DirectoryEntry对象,使用默认用户身份标识。        /// </summary>        /// <param name="userPath">用户DirectoryEntry的ADsPath。</param>        /// <returns>不存在返回null。</returns>        public static DirectoryEntry GetUserPrimaryGroup(string userPath)        {            return GetUserPrimaryGroup(userPath, null, null);        }        /// <summary>        /// 获取用户DirectoryEntry对象的PrimaryGroup DirectoryEntry对象。        /// </summary>        /// <param name="user">用户DirectoryEntry对象。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>不存在返回null。</returns>        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);        }        /// <summary>        /// 获取用户DirectoryEntry对象的隶属组的DN。        /// </summary>        /// <param name="userPath">用户DirectoryEntry的ADsPath。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <param name="includePrimaryGroup">是否包括PrimaryGroup</param>        /// <returns>不存在返回空集合。</returns>        public static List<string> 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<string> dn = new List<string>();            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;        }        /// <summary>        /// 获取用户DirectoryEntry对象的隶属组的DN,使用默认用户身份标识。        /// </summary>        /// <param name="userPath">用户DirectoryEntry的ADsPath。</param>        /// <param name="includePrimaryGroup">是否包括PrimaryGroup</param>        /// <returns>不存在返回空集合。</returns>        public static List<string> GetUserMemberOfDN(string userPath, bool includePrimaryGroup)        {            return GetUserMemberOfDN(userPath, null, null, includePrimaryGroup);        }        #endregion        #endregion        #region Group        #region Search        /// <summary>        /// 获取指定所有组。        /// </summary>        /// <param name="cn">组CN。</param>        /// <param name="description">组描述。</param>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<Group> 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<DirectoryEntry> entries = Search(schema, "group", null, rootPath, SearchScope.Subtree, userName, password);            List<Group> groups = new List<Group>();            foreach (DirectoryEntry de in entries)            {                groups.Add(new Group(de));                de.Close();                de.Dispose();            }            return groups;        }        /// <summary>        /// 获取指定所有组,使用默认用户身份标识。        /// </summary>        /// <param name="cn">组CN。</param>        /// <param name="description">组描述。</param>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<Group> SearchGroup(string cn, string description, string rootPath)        {            return SearchGroup(cn, description, rootPath, null, null);        }        /// <summary>        /// 获取指定所有组。        /// </summary>        /// <param name="cn">组CN。</param>        /// <param name="description">组描述。</param>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass。        /// 最后添加了sAMAccountName。</remarks>        public static List<String[]> 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);        }        /// <summary>        /// 获取指定所有组,使用默认用户身份标识。        /// </summary>        /// <param name="cn">组CN。</param>        /// <param name="description">组描述。</param>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <returns>如果不存在,返回null。</returns>        /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass</remarks>        public static List<String[]> SearchGroupSimple(string cn, string description, string rootPath)        {            return SearchGroupSimple(cn, description, rootPath, null, null);        }        /// <summary>        /// 获取指定所有组。直接解析查询结果,速度较SearchGroup快。        /// </summary>        /// <param name="cn">组CN。</param>        /// <param name="description">组描述。</param>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<Group> 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<Group> groups = new List<Group>();            foreach (SearchResult se in results)            {                groups.Add(new Group(se));            }            return groups;        }        /// <summary>        /// 获取指定所有组,使用默认用户身份标识。直接解析查询结果,速度较SearchGroup快。        /// </summary>        /// <param name="cn">组CN。</param>        /// <param name="description">组描述。</param>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<Group> SearchGroupQuick(string cn, string description, string rootPath)        {            return SearchGroupQuick(null,null, rootPath, null, null);        }        /// <summary>        /// 根据sAMAccountName获取Group。        /// </summary>        /// <param name="sAMAccountName">sAMAccountName。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static Group GetGroupBySAMAccountName(string sAMAccountName, string userName, string password)        {            List<DirectoryEntry> 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        /// <summary>        /// 根据用户的Guid得到组对象。        /// </summary>        /// <param name="guid">Guid</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static Group GetGroupByGuid(Guid guid, string userName, string password)        {            return GetGroupByPath(Utils.GenerateADsPath(guid), userName, password);        }        /// <summary>        /// 根据用户的Guid得到组对象,使用默认用户身份标识。        /// </summary>        /// <param name="guid">Guid</param>        /// <returns>如果不存在,返回null。</returns>        public static Group GetGroupByGuid(Guid guid)        {            return GetGroupByGuid(guid, null,null);        }        /// <summary>        /// 根据用户的DN得到用户组。        /// </summary>        /// <param name="dn">DN。完全转义过的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static Group GetGroupByDN(string dn, string userName, string password)        {            return GetGroupByPath(dn, userName, password);        }        /// <summary>        /// 根据用户的DN得到组对象,使用默认用户身份标识。        /// </summary>        /// <param name="dn">DN。完全转义过的。</param>        /// <returns>如果不存在,返回null。</returns>        public static Group GetGroupByDN(string dn)        {            return GetGroupByDN(dn, null, null);        }        /// <summary>        /// 根据用户的ADsPath得到组对象。        /// </summary>        /// <param name="path">ADsPath。完全转义过的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static Group GetGroupByPath(string path, string userName, string password)        {            DirectoryEntry entry = GetByPath(path, userName, password);            if (entry != null)            {                Group group = new Group(entry);                entry.Close();                entry.Dispose();                return group;            }            else                return null;                    }        /// <summary>        /// 根据用户的ADsPath得到组对象,使用默认用户身份标识。        /// </summary>        /// <param name="path">ADsPath。完全转义过的。</param>        /// <returns>如果不存在,返回null。</returns>        public static Group GetGroupByPath(string path)        {            return GetGroupByPath(path, null, null);        }        #endregion        #region Rename        /// <summary>        /// 更改组DirectoryEntry对象的名称。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath</param>        /// <param name="newName">该项的新名称。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        public static void RenameGroup(string groupPath, string newName, string userName, string password)        {            DirectoryEntry de = GetByPath(groupPath, userName, password);            if (de == null)                throw new EntryNotExistException("组对象不存在。");            if (de.SchemaClassName != SchemaClass.group.ToString("F"))                throw new SchemaClassException("对象类型不是" + SchemaClass.group.ToString("F") + "。");            string dn = Utils.EscapeDNBackslashedChar(de.Properties[BaseObject.PROPERTY_DN].Value.ToString());            string rdn = Utils.GenerateRDNCN(newName);            if(Exists(Utils.GenerateDN(rdn, Utils.GetParentDN(dn))))                throw new SameRDNException("已存在同名对象。");            try            {                de.Rename(rdn);                de.CommitChanges();            }            catch (DirectoryServicesCOMException dsce)            {                throw dsce;            }            finally            {                if (de != null)                {                    de.Close();                    de.Dispose();                }            }        }        /// <summary>        /// 更改组DirectoryEntry对象的名称,使用默认用户身份标识。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath</param>        /// <param name="newName">该项的新名称。</param>        public static void RenameGroup(string groupPath, string newName)        {            RenameGroup(groupPath, newName);        }        #endregion        #region Member Change        /// <summary>        /// 将用户添加到组。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <param name="userDN">需要添加的用户的DN。完全转义的。</param>        public static void AddUserToGroup(string groupPath, string userName, string password, params string[] userDN)        {            DirectoryEntry de = GetByPath(groupPath, userName, password);            if (de == null)                throw new EntryNotExistException("组对象不存在。");            if (de.SchemaClassName != SchemaClass.group.ToString("F"))                throw new SchemaClassException("对象类型不是" + SchemaClass.group.ToString("F") + "。");            // 得到已有的Member            List<string> ms = new List<string>();            foreach (object m in de.Properties[Group.PROPERTY_MEMBER])            {                ms.Add(Utils.EscapeDNBackslashedChar(m.ToString()));            }            ms.Sort();          // 已排序 -- 以便内部使用            List<string> toAdd = new List<string>();            foreach (string udn in userDN)            {                if (!(ms.BinarySearch(udn) >= 0))                {                    if (!toAdd.Exists(delegate(string a ) {return a == udn;}))                        toAdd.Add(udn);                }            }            try            {                foreach (string udn in toAdd)                {                    de.Invoke("Add", new object[] { ParaMgr.LDAP_IDENTITY + udn });         // 需要ADsPath                }                de.CommitChanges();            }            catch (DirectoryServicesCOMException dsce)            {                throw dsce;            }            finally            {                if (de != null)                {                    de.Close();                    de.Dispose();                }            }        }        /// <summary>        /// 将用户添加到组,使用默认用户身份标识。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <param name="userDN">需要添加的用户的DN。</param>        public static void AddUserToGroup(string groupPath, params string[] userDN)        {            AddUserToGroup(groupPath, null,null,userDN);        }        /// <summary>        /// 将用户添加到组。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <param name="userGuid">需要添加的用户的Guid。</param>        public static void AddUserToGroup(string groupPath, string userName, string password, params Guid[] userGuid)        {            List<string> userDN = new List<string>();            User user = null;            foreach(Guid guid in userGuid)            {                user = GetUserByGuid(guid);                if (user != null)                {                    userDN.Add(user.Dn);                }            }            AddUserToGroup(groupPath, userName, password, userDN.ToArray());        }        /// <summary>        /// 将用户添加到组,使用默认用户身份标识。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <param name="userGuid">需要添加的用户的Guid。</param>        public static void AddUserToGroup(string groupPath, params Guid[] userGuid)        {            AddUserToGroup(groupPath, null, null, userGuid);        }        /// <summary>        /// 将用户从组中移除。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <param name="userDN">需要移除的用户的DN。完全转义的。</param>        public static void RemoveUserFromGroup(string groupPath, string userName, string password, params string[] userDN)        {            DirectoryEntry de = GetByPath(groupPath, userName, password);            if (de == null)                throw new EntryNotExistException("组对象不存在。");            if (de.SchemaClassName != SchemaClass.group.ToString("F"))                throw new SchemaClassException("对象类型不是" + SchemaClass.group.ToString("F") + "。");            // 得到已有的Group            List<string> ms = new List<string>();            foreach (object m in de.Properties[Group.PROPERTY_MEMBER])            {                ms.Add(Utils.EscapeDNBackslashedChar(m.ToString()));            }            ms.Sort();          // 已排序 -- 以便内部使用            List<string> toRemove = new List<string>();            foreach (string udn in userDN)            {                if (ms.BinarySearch(udn) >= 0)                {                    if (!toRemove.Exists(delegate(string a) { return a == udn; }))                        toRemove.Add(udn);                }            }            try            {                foreach (string udn in toRemove)                {                    de.Invoke("Remove", new object[] { ParaMgr.LDAP_IDENTITY + udn });         // 需要ADsPath                }                //de.Invoke("Remove", userDN);        // TODO:是否需要保留转义的/,是否需要ADsPath,like AddUserToGroup                de.CommitChanges();            }            catch (DirectoryServicesCOMException dsce)            {                throw dsce;            }            finally            {                if (de != null)                {                    de.Close();                    de.Dispose();                }            }        }        /// <summary>        /// 将用户从组中移除,使用默认用户身份标识。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <param name="userDN">需要移除的用户的DN。</param>                public static void RemoveUserFromGroup(string groupPath, params string[] userDN)        {            RemoveUserFromGroup(groupPath, null,null,userDN);        }        /// <summary>        /// 将用户从组中移除。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <param name="userGuid">需要移除的用户的Guid。</param>        public static void RemoveUserFromGroup(string groupPath, string userName, string password, params Guid[] userGuid)        {            List<string> userDN = new List<string>();            User user = null;            foreach(Guid guid in userGuid)            {                user = GetUserByGuid(guid);                if (user != null)                {                    userDN.Add(user.Dn);                }            }            RemoveUserFromGroup(groupPath, userName, password, userDN.ToArray());        }        /// <summary>        /// 将用户从组中移除,使用默认用户身份标识。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <param name="userGuid">需要移除的用户的Guid。</param>        public static void RemoveUserFromGroup(string groupPath, params Guid[] userGuid)        {            RemoveUserFromGroup(groupPath, null, null, userGuid);        }        #endregion        #region MemberOf & Member        /// <summary>        /// 获取组的隶属组的DN        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns></returns>        public static List<string> GetGroupMemberOfDN(string groupPath, string userName, string password)        {            DirectoryEntry de = GetByPath(groupPath, userName, password);            if (de == null)                throw new EntryNotExistException("组对象不存在。");            if (de.SchemaClassName != SchemaClass.group.ToString("F"))                throw new SchemaClassException("对象类型不是" + SchemaClass.group.ToString("F") + "。");            List<string> dn = new List<string>();            if (de.Properties.Contains(Group.PROPERTY_MEMBEROF))            {                foreach (object m in de.Properties[Group.PROPERTY_MEMBEROF])                {                    dn.Add(Utils.EscapeDNBackslashedChar(m.ToString()));                }            }            de.Close();            de.Dispose();            return dn;        }        /// <summary>        /// 获取组的隶属组的DN,使用默认用户身份标识。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <returns></returns>        public static List<string> GetGroupMemberOfDN(string groupPath)        {            return GetGroupMemberOfDN(groupPath, null, null);        }        /// <summary>        /// 获取组的成员(仅用户)        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns></returns>        public static List<User> GetGroupUserMember(string groupPath, string userName, string password)        {            DirectoryEntry de = GetByPath(groupPath, userName, password);            if (de == null)                throw new EntryNotExistException("组对象不存在。");            if (de.SchemaClassName != SchemaClass.group.ToString("F"))                throw new SchemaClassException("对象类型不是" + SchemaClass.group.ToString("F") + "。");            List<User> users = new List<User>();            string userSchemaClassName = SchemaClass.user.ToString("F");            if (de.Properties.Contains(Group.PROPERTY_MEMBER))            {                foreach (object memberDN in de.Properties[Group.PROPERTY_MEMBER])                {                    de = GetByDN(Utils.EscapeDNBackslashedChar(memberDN.ToString()), userName, password);                    if (de != null)                    {                        if (de.SchemaClassName == userSchemaClassName)                        {                            users.Add(new User(de));                        }                        de.Close();                        de.Dispose();                    }                }            }            return users;        }        /// <summary>        /// 获取组的成员(仅用户),使用默认用户身份标识。        /// </summary>        /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>        /// <returns></returns>        public static List<User> GetGroupUserMember(string groupPath)        {            return GetGroupUserMember(groupPath, null, null);        }        #endregion        #endregion        #region OU        #region Search        /// <summary>        /// 获取指定所有组织单位。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<OU> GetOUAll(string rootPath, string userName, string password)        {            List<DirectoryEntry> entries = Search(null, "organizationalUnit", null, rootPath, SearchScope.Subtree, userName, password);            List<OU> ous = new List<OU>();            foreach (DirectoryEntry de in entries)            {                ous.Add(new OU(de));                de.Close();                de.Dispose();            }            return ous;        }        /// <summary>        /// 获取指定所有组织单位,使用默认用户身份标识。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<OU> GetOUAll(string rootPath)        {            return GetOUAll(rootPath, null, null);        }        /// <summary>        /// 获取指定所有组织单位。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass</remarks>        public static List<String[]> GetOUAllSimple(string rootPath, string userName, string password)        {            return Search2(null, "organizationalUnit", null, rootPath, SearchScope.Subtree, userName, password);        }        /// <summary>        /// 获取指定所有组织单位,使用默认用户身份标识。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <returns>如果不存在,返回null。</returns>        /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass</remarks>        public static List<String[]> GetOUAllSimple(string rootPath)        {            return GetOUAllSimple(rootPath, null, null);        }        /// <summary>        /// 获取指定所有组织单位。直接解析查询结果,速度较GetUserAll快。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<OU> GetOUAllQuick(string rootPath, string userName, string password)        {            SearchResultCollection results = Search3(null, "organizationalUnit", null, rootPath, SearchScope.Subtree, userName, password);            List<OU> ous = new List<OU>();            foreach (SearchResult se in results)            {                ous.Add(new OU(se));            }            return ous;        }        /// <summary>        /// 获取指定所有组织单位,使用默认用户身份标识。直接解析查询结果,速度较GetUserAll快。        /// </summary>        /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>        /// <returns>如果不存在,返回null。</returns>        public static List<OU> GetOUAllQuick(string rootPath)        {            return GetOUAllQuick(rootPath, null, null);        }        #endregion        #region Get        /// <summary>        /// 根据组织单位的Guid得到组织单位对象。        /// </summary>        /// <param name="guid">Guid</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static OU GetOUByGuid(Guid guid, string userName, string password)        {            return GetOUByPath(Utils.GenerateADsPath(guid), userName, password);        }        /// <summary>        /// 根据组织单位的Guid得到组织单位对象,使用默认用户身份标识。        /// </summary>        /// <param name="guid">Guid</param>        /// <returns>如果不存在,返回null。</returns>        public static OU GetOUByGuid(Guid guid)        {            return GetOUByGuid(guid, null, null);        }        /// <summary>        /// 根据组织单位的DN得到组织单位对象。        /// </summary>        /// <param name="dn">DN。完全转义过的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static OU GetOUByDN(string dn, string userName, string password)        {            return GetOUByPath(dn, userName, password);        }        /// <summary>        /// 根据组织单位的DN得到组织单位对象,使用默认用户身份标识。        /// </summary>        /// <param name="dn">DN。完全转义过的。</param>        /// <returns>如果不存在,返回null。</returns>        public static OU GetOUByDN(string dn)        {            return GetOUByDN(dn, null, null);        }        /// <summary>        /// 根据组织单位的ADsPath得到组织单位对象。        /// </summary>        /// <param name="path">ADsPath。完全转义过的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static OU GetOUByPath(string path, string userName, string password)        {            DirectoryEntry entry = GetByPath(path, userName, password);            if (entry != null)            {                OU ou = new OU(entry);                entry.Close();                entry.Dispose();                return ou;            }            else                return null;        }        /// <summary>        /// 根据组织单位的ADsPath得到组织单位对象,使用默认用户身份标识。        /// </summary>        /// <param name="path">ADsPath。完全转义过的。</param>        /// <returns>如果不存在,返回null。</returns>        public static OU GetOUByPath(string path)        {            return GetOUByPath(path, null, null);        }        #endregion        #region Rename        /// <summary>        /// 更改组织单位DirectoryEntry对象的名称。        /// </summary>        /// <param name="ouPath">组织单位DirectoryEntry的ADsPath。必须是DN形式,且完全转义。</param>        /// <param name="newName">该项的新名称。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        public static void RenameOU(string ouPath, string newName, string userName, string password)        {            DirectoryEntry de = GetByPath(ouPath, userName, password);            if (de == null)                throw new EntryNotExistException("组织单位对象不存在。");            if (de.SchemaClassName != SchemaClass.organizationalUnit.ToString("F"))                throw new SchemaClassException("对象类型不是" + SchemaClass.organizationalUnit.ToString("F") + "。");            string dn = Utils.EscapeDNBackslashedChar(de.Properties[BaseObject.PROPERTY_DN].Value.ToString());            string rdn = Utils.GenerateRDNOU(newName);            if (Exists(Utils.GenerateDN(rdn, Utils.GetParentDN(dn))))                throw new SameRDNException("已存在同名对象。");            try            {                de.Rename(rdn);                de.CommitChanges();            }            catch (DirectoryServicesCOMException dsce)            {                throw dsce;            }            finally            {                if (de != null)                {                    de.Close();                    de.Dispose();                }            }        }        /// <summary>        /// 更改组DirectoryEntry对象的名称,使用默认用户身份标识。        /// </summary>        /// <param name="ouPath">组织单位DirectoryEntry的ADsPath。必须是DN形式,且完全转义。</param>        /// <param name="newName">该项的新名称。</param>        public static void RenameOU(string ouPath, string newName)        {            RenameOU(ouPath, newName, null, null);        }        /// <summary>        /// 更改组织单位DirectoryEntry对象的名称。        /// </summary>        /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>        /// <param name="newName">该项的新名称。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        public static void RenameOU(Guid ouGuid, string newName, string userName, string password)        {            RenameOU(TB.ADBlock.ADManager.GetOUByGuid(ouGuid).Dn, newName, userName, password);        }        /// <summary>        /// 更改组织单位DirectoryEntry对象的名称,使用默认用户身份标识。        /// </summary>        /// <param name="ouGuid">组织单位DirectoryEntry的ADsPath</param>        /// <param name="newName">该项的新名称。</param>        public static void RenameOU(Guid ouGuid, string newName)        {            RenameOU(Utils.GenerateADsPath(ouGuid), newName, null, null);        }        #endregion        #region Move        /// <summary>        /// 移动组织单位DirectoryEntry到指定位置。        /// </summary>        /// <param name="ouPath">要移动的组织单位DirectoryEntry的ADsPath。必须是DN形式,且完全转义。</param>        /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式,且完全转义。</param>        /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        public static void MoveOU(string ouPath, string newLocationPath, bool mustOU, string userName, string password)        {            if (!Exists(ouPath))                throw new EntryNotExistException("需要被移动的对象不存在。");            DirectoryEntry de = null;            try            {                de = GetByPath(ouPath, userName, password);                MoveOU(de, newLocationPath, mustOU, userName, password);            }            catch            {                throw;            }            finally            {                if (de != null)                {                    de.Close();                    de.Dispose();                }            }        }        /// <summary>        /// 移动组织单位DirectoryEntry到指定位置,使用默认用户身份标识。        /// </summary>        /// <param name="ouPath">要移动的组织单位DirectoryEntry的ADsPath</param>        /// <param name="newLocationPath">移动到的位置的ADsPath</param>        /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>        public static void MoveOU(string ouPath, string newLocationPath, bool mustOU)        {            MoveUser(ouPath, newLocationPath, mustOU, null, null);        }        /// <summary>        /// 移动组织单位DirectoryEntry到指定位置。        /// </summary>        /// <param name="ou">要移动的组织单位DirectoryEntry的Guid</param>        /// <param name="newLocation">移动到的位置的Guid</param>        /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        public static void MoveOU(Guid ou, Guid newLocation, bool mustOU, string userName, string password)        {            MoveUser(TB.ADBlock.ADManager.GetOUByGuid(ou).Dn,               TB.ADBlock.ADManager.GetOUByGuid(newLocation).Dn, mustOU, userName, password);        }        /// <summary>        /// 移动组织单位DirectoryEntry到指定位置,使用默认用户身份标识。        /// </summary>        /// <param name="ou">要移动的组织单位DirectoryEntry的Guid</param>        /// <param name="newLocationPath">移动到的位置的Guid</param>        /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>        public static void MoveOU(Guid ou, Guid newLocationPath, bool mustOU)        {            MoveUser(ou, newLocationPath, mustOU, null, null);        }        /// <summary>        /// 移动组织单位DirectoryEntry到指定位置。        /// </summary>        /// <param name="de">要移动的组织单位DirectoryEntry对象</param>        /// <param name="newLocationPath">移动到的位置的ADsPath</param>        /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        internal static void MoveOU(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.organizationalUnit.ToString("F"))                    throw new SchemaClassException("需要被移动的对象类型不是" + SchemaClass.organizationalUnit.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 Structure        /// <summary>        /// 获取组织单位子树。        /// </summary>        /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns></returns>        public OU GetOUSubTree(Guid ouGuid, string userName, string password)        {            OU ou = GetOUByGuid(ouGuid);            if (ou == null)                throw new EntryNotExistException("组织单位对象不存在。");            return ou.GetSubTree(userName, password);        }        /// <summary>        /// 获取组织单位子树,使用默认用户身份标识。        /// </summary>        /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>        /// <returns></returns>        public OU GetOUSubTree(Guid ouGuid)        {            return GetOUSubTree(ouGuid, null, null);        }        /// <summary>        /// 获取组织单位子组织单位。        /// </summary>        /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns></returns>        public List<OU> GetOUChildren(Guid ouGuid, string userName, string password)        {            OU ou = GetOUByGuid(ouGuid);            if (ou == null)                throw new EntryNotExistException("组织单位对象不存在。");            return ou.GetChildren(userName, password);        }        /// <summary>        /// 获取组织单位子组织单位,使用默认用户身份标识。        /// </summary>        /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>        /// <returns></returns>        public List<OU> GetOUChildren(Guid ouGuid)        {            return GetOUChildren(ouGuid, null, null);        }        /// <summary>        /// 获取组织单位父组织单位。        /// </summary>        /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns></returns>        public OU GetOUParent(Guid ouGuid, string userName, string password)        {            OU ou = GetOUByGuid(ouGuid);            if (ou == null)                throw new EntryNotExistException("组织单位对象不存在。");            return ou.GetParent(userName, password);        }        /// <summary>        /// 获取组织单位父组织单位,使用默认用户身份标识。        /// </summary>        /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>        /// <returns></returns>        public OU GetOUParent(Guid ouGuid)        {            return GetOUParent(ouGuid, null, null);        }        #endregion        #endregion        /// <summary>        /// 通过ADsPath获取对象。目前仅限User,OU和Group        /// </summary>        /// <param name="path">ADsPath。完全转义过的。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回null。</returns>        public static BaseObject GetObjectByPath(string path, string userName, string password)        {            BaseObject baseObject = null;            DirectoryEntry entry = GetByPath(path, userName, password);            if (entry != null)            {                SchemaClass schema = SchemaClass.none;                try                {                    schema = (SchemaClass)(Enum.Parse(typeof(SchemaClass), entry.SchemaClassName));                    switch (schema)                    {                        case SchemaClass.user:                            baseObject = new User(entry);                            break;                        case SchemaClass.group:                            baseObject = new Group(entry);                            break;                        case SchemaClass.organizationalUnit:                            baseObject = new OU(entry);                            break;                    }                }                catch                { }                                entry.Close();                entry.Dispose();                return baseObject;            }            else                return null;        }        /// <summary>        /// 指定的SAMAccountName用户或组是否存在。        /// </summary>        /// <param name="sAMAccountName">sAMAccountName</param>        /// <param name="an">如果存在,对应的sAMAccountName。</param>        /// <param name="dn">如果存在,对应的DN。</param>        /// <param name="precision">true表示完全匹配,false表示前向匹配。</param>        /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>        /// <param name="password">用户身份标识--密码。</param>        /// <returns>如果不存在,返回false。</returns>        public static bool SAMAccountNameExists(string sAMAccountName, out string an, out string dn, bool precision,            string userName, string password)        {            an = null;            dn = null;            List<DirectoryEntry> entries = Search("sAMAccountName=" + Utils.Escape4Query(sAMAccountName) + "*", null, null, null, SearchScope.Subtree, userName, password);            if (entries.Count >= 1)            {                string schemaClassName = entries[0].SchemaClassName;                bool valid = ((schemaClassName == SchemaClass.group.ToString("F")) || (schemaClassName == SchemaClass.user.ToString("F")));                if (valid)                {                    an = entries[0].Properties["sAMAccountName"].Value.ToString();                    if ((precision && (an == sAMAccountName)) || (!precision))                    {                        dn = Utils.EscapeDNBackslashedChar(entries[0].Properties[BaseObject.PROPERTY_DN].Value.ToString());                    }                    else                    {                        an = null;                        valid = false;                    }                                    }                entries[0].Close();                entries[0].Dispose();                return valid;            }            return false;        }    }}

 

操作Active Directory C#