• 操作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://&lt;GUID&gt;两种形式,但不限于这种形式。
        
    /// 一般方法均提供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, nullnull);
            }

            
    /// <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, 
    nullnull);
            }

            
    /// <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(nullnull);
            }

            
    // 根据用户名和密码,判断是否应该使用默认用户身份标识。
            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, nullnull);
            }


            
    /// <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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnullnull, userName, password);
            }

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


            
    /// <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, nullnull);
            }


            
    /// <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, nullnull);
            }


            
    #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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    #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, 
    nullnull);
            }

            
    #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, 
    nullnull);
            }

            
    /// <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, 
    nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnull, 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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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"nullnull, 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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    #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, 
    nullnull, 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, 
    nullnull, 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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    #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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    #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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    #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, 
    nullnull);
            }

            
    /// <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, 
    nullnull);
            }

            
    #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, 
    nullnull);
            }

            
    /// <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, 
    nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    /// <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, nullnull);
            }

            
    #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) + "*"nullnullnull, 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;
            }

        }
    }
  • 相关阅读:
    用Instant client批量安装Oracle客户端安装配置
    Oracle case when 用法(转)
    C# 读写ini文件 【转】
    oracle数据库删除数据Delete语句和Truncate语句的对比
    C#使用instantclient连接 Oracle 10g (转)
    SQL Server CONVERT() 函数
    c#格式化数字(转)
    InstantClient安装使用 (转)
    C# 四个字节十六进制数和单精度浮点数之间的相互转化
    oracle case when的使用方法
  • 原文地址:https://www.cnblogs.com/lzhdim/p/1344009.html
Copyright © 2020-2023  润新知