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

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

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

  1. /*
  2. * Copyright [2008]. Sherwin Zhu. sherwinzhu@126.com
  3. *
  4. * http://www.gnu.org/licenses/lgpl-3.0.txt
  5. *
  6. * Unless required by applicable law or agreed to in writing, software
  7. * distributed under the License is distributed on an "AS IS" BASIS,
  8. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. * See the License for the specific language governing permissions and
  10. * limitations under the License.
  11. */
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Text;
  15. using System.DirectoryServices;
  16. using System.Collections;
  17. using System.DirectoryServices.ActiveDirectory;
  18.  
  19. namespace TB.ADBlock
  20. {
  21. /// <summary>
  22. /// 用于进行AD管理里的对象,提供操作AD的静态方法。
  23. /// </summary>
  24. /// <remarks>
  25. /// 这里ADsPath可以是LDAP://DN和LDAP://<GUID>两种形式,但不限于这种形式。
  26. /// 一般方法均提供2种形式,一种是用参数提供的用户身份标识,一种是用默认的用户身份标识。
  27. /// 默认用户身份标识取决于当前进程的用户身份标识。
  28. /// </remarks>
  29. public class ADManager
  30. {
  31. #region 域信息
  32.  
  33. /// <summary>
  34. /// 将友好的域名称(friendly domain name)转换为合格的域名称(fully qualified domain name)。
  35. /// eg:tb -- > tb.com
  36. /// </summary>
  37. /// <param name="friendlyDomainName">友好的域名称(friendly domain name)。
  38. /// 可以是:
  39. /// 域控制器的 DNS 名称。
  40. /// ADAM 服务器的 DNS 名称和 LDAP 端口号(如 adam_instance.fabrikam.com:389)。
  41. /// 域的 DNS 名称,如 sales.corp.fabrikam.com。
  42. /// 林的 DNS 名称,如 corp.fabrikam.com。
  43. /// 应用程序分区的 DNS 名称。
  44. /// 与服务连接点关联的关键字之一,该服务连接点由配置集的 ADAM 实例注册。</param>
  45. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  46. /// <param name="password">用户身份标识--密码。</param>
  47. /// <returns></returns>
  48. public static string FriendlyDomainToLdapDomain(string friendlyDomainName, string userName, string password)
  49. {
  50. string ldapPath = null;
  51. try
  52. {
  53. DirectoryContext objContext = null;
  54. if (UseDefaultIdentity(userName, password))
  55. objContext = new DirectoryContext(DirectoryContextType.Domain, friendlyDomainName);
  56. else
  57. objContext = new DirectoryContext(DirectoryContextType.Domain, friendlyDomainName, userName, password);
  58.  
  59. ldapPath = System.DirectoryServices.ActiveDirectory.Domain.GetDomain(objContext).Name;
  60. }
  61. catch (DirectoryServicesCOMException dsce)
  62. {
  63. throw dsce;
  64. }
  65. return ldapPath;
  66. }
  67.  
  68. /// <summary>
  69. /// 将友好的域名称(friendly domain name)转换为合格的域名称(fully qualified domain name)。
  70. /// eg:tb -- > tb.com
  71. /// </summary>
  72. /// <param name="friendlyDomainName">友好的域名称(friendly domain name)。
  73. /// 可以是:
  74. /// 域控制器的 DNS 名称。
  75. /// ADAM 服务器的 DNS 名称和 LDAP 端口号(如 adam_instance.fabrikam.com:389)。
  76. /// 域的 DNS 名称,如 sales.corp.fabrikam.com。
  77. /// 林的 DNS 名称,如 corp.fabrikam.com。
  78. /// 应用程序分区的 DNS 名称。
  79. /// 与服务连接点关联的关键字之一,该服务连接点由配置集的 ADAM 实例注册。</param>
  80. /// <returns></returns>
  81. public static string FriendlyDomainToLdapDomain(string friendlyDomainName)
  82. {
  83. return FriendlyDomainToLdapDomain(friendlyDomainName, null, null);
  84. }
  85.  
  86. /// <summary>
  87. /// 获取当前用户上下文的 Forest 对象中的所有域名称。
  88. /// </summary>
  89. /// <returns></returns>
  90. public static List<string> EnumerateDomains()
  91. {
  92. List<string> alDomains = new List<string>();
  93. Forest currentForest = Forest.GetCurrentForest();
  94. DomainCollection myDomains = currentForest.Domains;
  95.  
  96. foreach (System.DirectoryServices.ActiveDirectory.Domain objDomain in myDomains)
  97. {
  98. alDomains.Add(objDomain.Name);
  99. }
  100. return alDomains;
  101. }
  102.  
  103. /// <summary>
  104. /// 获取当前用户上下文的 Forest 对象中所有的全局目录。
  105. /// </summary>
  106. /// <returns></returns>
  107. public static List<string> EnumerateGlobalCatalogs()
  108. {
  109. List<string> alGCs = new List<string>();
  110. Forest currentForest = Forest.GetCurrentForest();
  111. foreach (GlobalCatalog gc in currentForest.GlobalCatalogs)
  112. {
  113. alGCs.Add(gc.Name);
  114. }
  115. return alGCs;
  116. }
  117.  
  118. /// <summary>
  119. /// 获取当前用户身份标识的 Domain 对象中的域控制器。
  120. /// </summary>
  121. /// <returns></returns>
  122. public static List<string> EnumerateDomainControllers()
  123. {
  124. List<string> alDcs = new List<string>();
  125. System.DirectoryServices.ActiveDirectory.Domain domain = System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain();
  126. foreach (DomainController dc in domain.DomainControllers)
  127. {
  128. alDcs.Add(dc.Name);
  129. }
  130. return alDcs;
  131. }
  132.  
  133. #endregion
  134.  
  135. #region Common
  136.  
  137. /// <summary>
  138. /// 检验指定的DirectoryEntry是否存在
  139. /// </summary>
  140. /// <param name="path">ADsPath,自动添加LDAP_IDENTITY。完全转义过的。</param>
  141. /// <returns></returns>
  142. public static bool Exists(string path)
  143. {
  144. if (path.StartsWith(ParaMgr.LDAP_IDENTITY))
  145. return DirectoryEntry.Exists(path);
  146. else
  147. return DirectoryEntry.Exists(ParaMgr.LDAP_IDENTITY + path);
  148.  
  149. }
  150.  
  151. /// <summary>
  152. /// 移动DirectoryEntry到指定位置。
  153. /// </summary>
  154. /// <param name="objectPath">要移动的DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。</param>
  155. /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>
  156. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  157. /// <param name="password">用户身份标识--密码。</param>
  158. /// <remarks>被移动的对象和要移动到的位置对象必须使用DN形式的路径创建,不能使用GUID形式的路径,否则会引发异常。</remarks>
  159. public static void Move(string objectPath, string newLocationPath, string userName, string password)
  160. {
  161. if (!Exists(objectPath))
  162. throw new EntryNotExistException("需要被移动的对象不存在。");
  163.  
  164. DirectoryEntry de = null;
  165. try
  166. {
  167. de = GetByPath(objectPath, userName, password);
  168.  
  169. Move(de, newLocationPath, userName, password);
  170. }
  171. catch
  172. {
  173. throw;
  174. }
  175. finally
  176. {
  177. if (de != null)
  178. {
  179. de.Close();
  180. de.Dispose();
  181. }
  182. }
  183. }
  184.  
  185. /// <summary>
  186. /// 移动DirectoryEntry到指定位置,使用默认用户身份标识。
  187. /// </summary>
  188. /// <param name="objectPath">要移动的DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。</param>
  189. /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>
  190. public static void Move(string objectPath, string newLocationPath)
  191. {
  192. Move(objectPath, newLocationPath, null, null);
  193. }
  194.  
  195. /// <summary>
  196. /// 移动DirectoryEntry到指定位置。
  197. /// </summary>
  198. /// <param name="de">要移动的DirectoryEntry对象</param>
  199. /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>
  200. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  201. /// <param name="password">用户身份标识--密码。</param>
  202. /// <remarks>被移动的对象和要移动到的位置对象必须使用DN形式的路径创建,不能使用GUID形式的路径,否则会引发异常。</remarks>
  203. internal static void Move(DirectoryEntry de, string newLocationPath, string userName, string password)
  204. {
  205. if (!Exists(newLocationPath))
  206. throw new EntryNotExistException("移动到的位置对象不存在。");
  207.  
  208. DirectoryEntry newLocation = null;
  209. try
  210. {
  211. newLocation = GetByPath(newLocationPath, userName, password);
  212.  
  213. string newLocationDN = Utils.EscapeDNBackslashedChar(newLocation.Properties[BaseObject.PROPERTY_DN].Value.ToString());
  214. string deDN = Utils.EscapeDNBackslashedChar(de.Properties[BaseObject.PROPERTY_DN].Value.ToString());
  215. if (Exists(Utils.GenerateDN(Utils.GetRDN(deDN), deDN)))
  216. throw new SameRDNException("移动到的位置下存在同名对象。");
  217.  
  218. de.MoveTo(newLocation);
  219.  
  220. de.CommitChanges();
  221. }
  222. catch (InvalidOperationException ioe) // 指定的 DirectoryEntry 不是容器。
  223. {
  224. throw new NotContainerException(ioe.Message, ioe);
  225. }
  226. catch (DirectoryServicesCOMException dsce)
  227. {
  228. throw dsce;
  229. }
  230. finally
  231. {
  232. if (newLocation != null)
  233. {
  234. newLocation.Close();
  235. newLocation.Dispose();
  236. }
  237. }
  238. }
  239.  
  240. /// <summary>
  241. /// 获取应用程序设置的默认域。
  242. /// </summary>
  243. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  244. /// <param name="password">用户身份标识--密码。</param>
  245. /// <returns></returns>
  246. public static DirectoryEntry GetAppSetDomain(string userName, string password)
  247. {
  248. return GetByDN(ParaMgr.ADFullPath, userName, password);
  249. }
  250.  
  251. /// <summary>
  252. /// 获取应用程序设置的默认域,使用默认用户身份标识。
  253. /// </summary>
  254. /// <returns></returns>
  255. public static DirectoryEntry GetAppSetDomain()
  256. {
  257. return GetAppSetDomain(null, null);
  258. }
  259.  
  260. // 根据用户名和密码,判断是否应该使用默认用户身份标识。
  261. private static bool UseDefaultIdentity(string userName, string password)
  262. {
  263. if (String.IsNullOrEmpty(userName))
  264. return true;
  265. else
  266. return false;
  267. }
  268.  
  269. #endregion
  270.  
  271. #region Get & Search
  272.  
  273. /// <summary>
  274. /// 获取DirectoryEntry
  275. /// </summary>
  276. /// <param name="schema">自定义模式</param>
  277. /// <param name="objectClass">类型</param>
  278. /// <param name="objectCategory">类别</param>
  279. /// <param name="rootDN">根对象DN,null表示整个域。</param>
  280. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  281. /// <param name="password">用户身份标识--密码。</param>
  282. /// <returns>如果不存在,返回null。</returns>
  283. internal static DirectoryEntry Get(string schema, string objectClass, string objectCategory, string rootDN, string userName, string password)
  284. {
  285. DirectoryEntry de = GetByDN((String.IsNullOrEmpty(rootDN) ? (ParaMgr.ADFullPath) : rootDN),
  286. userName, password);
  287.  
  288. DirectorySearcher deSearch = new DirectorySearcher();
  289. deSearch.SearchRoot = de;
  290. if (!String.IsNullOrEmpty(objectClass) ||
  291. !String.IsNullOrEmpty(objectCategory) ||
  292. !String.IsNullOrEmpty(schema))
  293. {
  294. deSearch.Filter = String.Format("(&{0}{1}{2})",
  295. ((!String.IsNullOrEmpty(objectClass)) ? String.Format("(objectClass={0})", objectClass) : ""),
  296. ((!String.IsNullOrEmpty(objectCategory)) ? String.Format("(objectCategory={0})", objectCategory) : ""),
  297. ((!String.IsNullOrEmpty(schema)) ? String.Format("({0})", schema) : "")
  298. );
  299. }
  300. deSearch.SearchScope = SearchScope.Subtree;
  301. SearchResult results = deSearch.FindOne();
  302. DirectoryEntry rde = null;
  303. if (results != null)
  304. rde = GetByPath(results.Path);
  305. else
  306. rde = null;
  307.  
  308. de.Close();
  309. de.Dispose();
  310.  
  311. return rde;
  312. }
  313.  
  314. /// <summary>
  315. /// 获取DirectoryEntry,使用默认用户身份标识。
  316. /// </summary>
  317. /// <param name="schema">自定义模式</param>
  318. /// <param name="objectClass">类型</param>
  319. /// <param name="objectCategory">类别</param>
  320. /// <param name="rootDN">根对象DN,null表示整个域。</param>
  321. /// <returns>如果不存在,返回null。</returns>
  322. internal static DirectoryEntry Get(string schema, string objectClass, string objectCategory, string rootDN)
  323. {
  324. return Get(schema, objectClass, objectCategory, rootDN, null, null);
  325. }
  326.  
  327. /// <summary>
  328. /// 查找DirectoryEntry
  329. /// </summary>
  330. /// <param name="schema">自定义模式</param>
  331. /// <param name="objectClass">类型</param>
  332. /// <param name="objectCategory">类别</param>
  333. /// <param name="rootPath">根对象ADsPath</param>
  334. /// <param name="scope">SearchScope</param>
  335. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  336. /// <param name="password">用户身份标识--密码。</param>
  337. /// <returns>如果不存在,返回空集合。</returns>
  338. internal static List<DirectoryEntry> Search(string schema, string objectClass, string objectCategory,
  339. string rootPath, SearchScope scope, string userName, string password)
  340. {
  341. DirectoryEntry de = null;
  342.  
  343. if (!String.IsNullOrEmpty(rootPath))
  344. {
  345. de = GetByPath(rootPath, userName, password);
  346. }
  347. if (de == null)
  348. de = GetByPath(ParaMgr.ADFullPath, userName, password);
  349.  
  350. DirectorySearcher deSearch = new DirectorySearcher();
  351. if (de != null)
  352. deSearch.SearchRoot = de;
  353. if (!String.IsNullOrEmpty(objectClass) ||
  354. !String.IsNullOrEmpty(objectCategory) ||
  355. !String.IsNullOrEmpty(schema))
  356. {
  357. deSearch.Filter = String.Format("(&{0}{1}{2})",
  358. ((!String.IsNullOrEmpty(objectClass)) ? String.Format("(objectClass={0})", objectClass) : ""),
  359. ((!String.IsNullOrEmpty(objectCategory)) ? String.Format("(objectCategory={0})", objectCategory) : ""),
  360. ((!String.IsNullOrEmpty(schema)) ? String.Format("({0})", schema) : "")
  361. );
  362. }
  363. deSearch.SearchScope = scope;
  364. SearchResultCollection results = deSearch.FindAll();
  365.  
  366. List<DirectoryEntry> entries = new List<DirectoryEntry>();
  367. if (results != null)
  368. {
  369. foreach (SearchResult se in results)
  370. {
  371. //entries.Add(GetByPath(se.Path));
  372. entries.Add(se.GetDirectoryEntry());
  373. }
  374. }
  375.  
  376. de.Close();
  377. de.Dispose();
  378.  
  379. return entries;
  380.  
  381. }
  382.  
  383. /// <summary>
  384. /// 查找DirectoryEntry,使用默认用户身份标识。
  385. /// </summary>
  386. /// <param name="schema">自定义模式</param>
  387. /// <param name="objectClass">类型</param>
  388. /// <param name="objectCategory">类别</param>
  389. /// <param name="rootPath">根对象ADsPath</param>
  390. /// <param name="scope">SearchScope</param>
  391. /// <returns>如果不存在,返回空集合。</returns>
  392. internal static List<DirectoryEntry> Search(string schema, string objectClass, string objectCategory,
  393. string rootPath, SearchScope scope)
  394. {
  395. return Search(schema, objectClass, objectCategory, rootPath, scope, null, null);
  396. }
  397.  
  398. /// <summary>
  399. /// 查找DirectoryEntry,结果为字符串形式
  400. /// </summary>
  401. /// <param name="schema">自定义模式</param>
  402. /// <param name="objectClass">类型</param>
  403. /// <param name="objectCategory">类别</param>
  404. /// <param name="rootPath">根对象ADsPath</param>
  405. /// <param name="scope">SearchScope</param>
  406. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  407. /// <param name="password">用户身份标识--密码。</param>
  408. /// <returns>如果不存在,返回空集合。</returns>
  409. /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass。
  410. /// 最后添加了sAMAccountName。</remarks>
  411. internal static List<string[]> Search2(string schema, string objectClass, string objectCategory,
  412. string rootPath, SearchScope scope, string userName, string password)
  413. {
  414. DirectoryEntry de = null;
  415.  
  416. if (!String.IsNullOrEmpty(rootPath))
  417. {
  418. de = GetByPath(rootPath, userName, password);
  419. }
  420. if (de == null)
  421. de = GetByPath(ParaMgr.ADFullPath, userName, password);
  422.  
  423. DirectorySearcher deSearch = new DirectorySearcher();
  424. if (de != null)
  425. deSearch.SearchRoot = de;
  426. if (!String.IsNullOrEmpty(objectClass) ||
  427. !String.IsNullOrEmpty(objectCategory) ||
  428. !String.IsNullOrEmpty(schema))
  429. {
  430. deSearch.Filter = String.Format("(&{0}{1}{2})",
  431. ((!String.IsNullOrEmpty(objectClass)) ? String.Format("(objectClass={0})", objectClass) : ""),
  432. ((!String.IsNullOrEmpty(objectCategory)) ? String.Format("(objectCategory={0})", objectCategory) : ""),
  433. ((!String.IsNullOrEmpty(schema)) ? String.Format("({0})", schema) : "")
  434. );
  435. }
  436. deSearch.SearchScope = scope;
  437. SearchResultCollection results = deSearch.FindAll();
  438.  
  439. List<string[]> entriesProperty = new List<string[]>();
  440. if (results != null)
  441. {
  442. foreach (SearchResult se in results)
  443. {
  444. string nativeGuid = "";
  445. foreach(byte g in (byte[])se.Properties["objectguid"][0])
  446. {
  447. nativeGuid += g.ToString("x2");
  448. }
  449. string oc = "";
  450. foreach (object c in se.Properties["objectclass"])
  451. {
  452. oc = oc + "," + c.ToString();
  453. }
  454.  
  455. string sAMAccountName = null;
  456. if (se.Properties.Contains("sAMAccountName"))
  457. sAMAccountName = se.Properties["sAMAccountName"][0].ToString();
  458.  
  459. entriesProperty.Add(new string[] {
  460. se.Properties["distinguishedname"][0].ToString(),
  461. Utils.ConvertNativeGuidToGuid(nativeGuid).ToString(),
  462. se.Properties["name"][0].ToString(),
  463. ((se.Properties["description"].Count > 0) ? se.Properties["description"][0].ToString() : null),
  464. se.Properties["adspath"][0].ToString(),
  465. se.Properties["objectcategory"][0].ToString(),
  466. oc.Substring(1),
  467. sAMAccountName
  468. });
  469. }
  470. }
  471.  
  472. de.Close();
  473. de.Dispose();
  474.  
  475. return entriesProperty;
  476.  
  477. }
  478.  
  479. /// <summary>
  480. /// 查找DirectoryEntry,使用默认用户身份标识。结果为字符串形式
  481. /// </summary>
  482. /// <param name="schema">自定义模式</param>
  483. /// <param name="objectClass">类型</param>
  484. /// <param name="objectCategory">类别</param>
  485. /// <param name="rootPath">根对象ADsPath</param>
  486. /// <param name="scope">SearchScope</param>
  487. /// <returns>如果不存在,返回空集合。</returns>
  488. /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass</remarks>
  489. internal static List<string[]> Search2(string schema, string objectClass, string objectCategory,
  490. string rootPath, SearchScope scope)
  491. {
  492. return Search2(schema, objectClass, objectCategory, rootPath, scope, null, null);
  493. }
  494.  
  495. /// <summary>
  496. /// 查找DirectoryEntry
  497. /// </summary>
  498. /// <param name="schema">自定义模式</param>
  499. /// <param name="objectClass">类型</param>
  500. /// <param name="objectCategory">类别</param>
  501. /// <param name="rootPath">根对象ADsPath</param>
  502. /// <param name="scope">SearchScope</param>
  503. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  504. /// <param name="password">用户身份标识--密码。</param>
  505. /// <returns>如果不存在,返回空集合。</returns>
  506. internal static SearchResultCollection Search3(string schema, string objectClass, string objectCategory,
  507. string rootPath, SearchScope scope, string userName, string password)
  508. {
  509. DirectoryEntry de = null;
  510.  
  511. if (!String.IsNullOrEmpty(rootPath))
  512. {
  513. de = GetByPath(rootPath, userName, password);
  514. }
  515. if (de == null)
  516. de = GetByPath(ParaMgr.ADFullPath, userName, password);
  517.  
  518. DirectorySearcher deSearch = new DirectorySearcher();
  519. if (de != null)
  520. deSearch.SearchRoot = de;
  521. if (!String.IsNullOrEmpty(objectClass) ||
  522. !String.IsNullOrEmpty(objectCategory) ||
  523. !String.IsNullOrEmpty(schema))
  524. {
  525. deSearch.Filter = String.Format("(&{0}{1}{2})",
  526. ((!String.IsNullOrEmpty(objectClass)) ? String.Format("(objectClass={0})", objectClass) : ""),
  527. ((!String.IsNullOrEmpty(objectCategory)) ? String.Format("(objectCategory={0})", objectCategory) : ""),
  528. ((!String.IsNullOrEmpty(schema)) ? String.Format("({0})", schema) : "")
  529. );
  530. }
  531. deSearch.SearchScope = scope;
  532.  
  533. SearchResultCollection results = deSearch.FindAll();
  534.  
  535. de.Close();
  536. de.Dispose();
  537.  
  538. return results;
  539. }
  540.  
  541. /// <summary>
  542. /// 查找DirectoryEntry,使用默认用户身份标识。
  543. /// </summary>
  544. /// <param name="schema">自定义模式</param>
  545. /// <param name="objectClass">类型</param>
  546. /// <param name="objectCategory">类别</param>
  547. /// <param name="rootPath">根对象ADsPath</param>
  548. /// <param name="scope">SearchScope</param>
  549. /// <returns>如果不存在,返回空集合。</returns>
  550. internal static SearchResultCollection Search3(string schema, string objectClass, string objectCategory,
  551. string rootPath, SearchScope scope)
  552. {
  553. return Search3(schema, objectClass, objectCategory, rootPath, scope, null, null);
  554. }
  555.  
  556. /// <summary>
  557. /// 根据DirectoryEntry的Guid得到DirectoryEntry对象。
  558. /// </summary>
  559. /// <param name="guid">Guid</param>
  560. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  561. /// <param name="password">用户身份标识--密码。</param>
  562. /// <returns>如果不存在,返回null。</returns>
  563. internal static DirectoryEntry GetByGuid(Guid guid, string userName, string password)
  564. {
  565. return GetByPath(Utils.GenerateADsPath(guid), userName, password);
  566. }
  567.  
  568. /// <summary>
  569. /// 根据DirectoryEntry的Guid得到DirectoryEntry对象,使用默认用户身份标识。
  570. /// </summary>
  571. /// <param name="guid">Guid</param>
  572. /// <returns>如果不存在,返回null。</returns>
  573. internal static DirectoryEntry GetByGuid(Guid guid)
  574. {
  575. return GetByGuid(guid, null,null );
  576. }
  577.  
  578. /// <summary>
  579. /// 根据DirectoryEntry的SID得到DirectoryEntry对象。
  580. /// </summary>
  581. /// <param name="sid">objectSID</param>
  582. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  583. /// <param name="password">用户身份标识--密码。</param>
  584. /// <returns>如果不存在,返回null。</returns>
  585. internal static DirectoryEntry GetBySid(string sid, string userName, string password)
  586. {
  587. return Get("objectSID=" + sid, null, null, null, userName, password);
  588. }
  589.  
  590. /// <summary>
  591. /// 根据DirectoryEntry的SID得到DirectoryEntry对象,使用默认用户身份标识。
  592. /// </summary>
  593. /// <param name="sid">objectSID</param>
  594. /// <returns>如果不存在,返回null。</returns>
  595. internal static DirectoryEntry GetBySid(string sid)
  596. {
  597. return GetBySid(sid, null, null);
  598. }
  599.  
  600. /// <summary>
  601. /// 根据DirectoryEntry的DN得到DirectoryEntry对象。
  602. /// </summary>
  603. /// <param name="dn">DN。完全转义过的。</param>
  604. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  605. /// <param name="password">用户身份标识--密码。</param>
  606. /// <returns>如果不存在,返回null。</returns>
  607. internal static DirectoryEntry GetByDN(string dn, string userName, string password)
  608. {
  609. return GetByPath(ParaMgr.LDAP_IDENTITY + dn, userName, password);
  610. }
  611.  
  612. /// <summary>
  613. /// 根据DirectoryEntry的DN得到DirectoryEntry对象,使用默认用户身份标识。
  614. /// </summary>
  615. /// <param name="dn">DN。完全转义过的。</param>
  616. /// <returns>如果不存在,返回null。</returns>
  617. internal static DirectoryEntry GetByDN(string dn)
  618. {
  619. return GetByDN(dn, null, null);
  620. }
  621.  
  622. /// <summary>
  623. /// 根据DirectoryEntry的ADsPath得到DirectoryEntry对象。
  624. /// </summary>
  625. /// <param name="path">完整的ADsPath,自动添加LDAP_IDENTITY。完全转义过的。</param>
  626. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  627. /// <param name="password">用户身份标识--密码。</param>
  628. /// <returns>如果不存在,返回null。</returns>
  629. /// <returns></returns>
  630. internal static DirectoryEntry GetByPath(string path, string userName, string password)
  631. {
  632. if (Exists(path))
  633. {
  634. if (UseDefaultIdentity(userName, password))
  635. return new DirectoryEntry((path.StartsWith(ParaMgr.LDAP_IDENTITY)) ? path : (ParaMgr.LDAP_IDENTITY + path));
  636. else
  637. return new DirectoryEntry(
  638. (path.StartsWith(ParaMgr.LDAP_IDENTITY)) ? path : (ParaMgr.LDAP_IDENTITY + path),
  639. userName,
  640. password,
  641. AuthenticationTypes.Secure);
  642.  
  643. }
  644. else
  645. return null;
  646. }
  647.  
  648. /// <summary>
  649. /// 根据DirectoryEntry的ADsPath得到DirectoryEntry对象,使用默认用户身份标识。
  650. /// </summary>
  651. /// <param name="path">完整的ADsPath。完全转义过的。</param>
  652. /// <returns>如果不存在,返回null。</returns>
  653. /// <returns></returns>
  654. internal static DirectoryEntry GetByPath(string path)
  655. {
  656. return GetByPath(path, null, null);
  657. }
  658.  
  659. #endregion
  660.  
  661. #region User
  662.  
  663. #region Search
  664.  
  665. /// <summary>
  666. /// 获取指定所有用户。
  667. /// </summary>
  668. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  669. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  670. /// <param name="password">用户身份标识--密码。</param>
  671. /// <returns>如果不存在,返回null。</returns>
  672. public static List<User> GetUserAll(string rootPath, string userName, string password)
  673. {
  674. List<DirectoryEntry> entries = Search(null, "user", "person", rootPath, SearchScope.Subtree, userName, password);
  675. List<User> users = new List<User>();
  676. foreach (DirectoryEntry de in entries)
  677. {
  678. users.Add(new User(de));
  679.  
  680. de.Close();
  681. de.Dispose();
  682. }
  683.  
  684. return users;
  685. }
  686.  
  687. /// <summary>
  688. /// 获取指定所有用户,使用默认用户身份标识。
  689. /// </summary>
  690. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  691. /// <returns>如果不存在,返回null。</returns>
  692. public static List<User> GetUserAll(string rootPath)
  693. {
  694. return GetUserAll(rootPath, null, null);
  695. }
  696.  
  697. /// <summary>
  698. /// 获取指定所有用户。
  699. /// </summary>
  700. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  701. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  702. /// <param name="password">用户身份标识--密码。</param>
  703. /// <returns>如果不存在,返回null。</returns>
  704. /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass。
  705. /// 最后添加了sAMAccountName。</remarks>
  706. public static List<string[]> GetUserAllSimple(string rootPath, string userName, string password)
  707. {
  708. return Search2(null, "user", "person", rootPath, SearchScope.Subtree, userName, password);
  709. }
  710.  
  711. /// <summary>
  712. /// 获取指定所有用户,使用默认用户身份标识。
  713. /// </summary>
  714. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  715. /// <returns>如果不存在,返回null。</returns>
  716. /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass</remarks>
  717. public static List<string[]> GetUserAllSimple(string rootPath)
  718. {
  719. return GetUserAllSimple(rootPath, null, null);
  720. }
  721.  
  722. /// <summary>
  723. /// 获取指定所有用户。直接解析查询结果,速度较GetUserAll快。
  724. /// </summary>
  725. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  726. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  727. /// <param name="password">用户身份标识--密码。</param>
  728. /// <returns>如果不存在,返回null。</returns>
  729. public static List<User> GetUserAllQuick(string rootPath, string userName, string password)
  730. {
  731. SearchResultCollection results = Search3(null, "user", "person", rootPath, SearchScope.Subtree, userName, password);
  732.  
  733. List<User> users = new List<User>();
  734. foreach (SearchResult se in results)
  735. {
  736. users.Add(new User(se));
  737. }
  738.  
  739. return users;
  740. }
  741.  
  742. /// <summary>
  743. /// 获取指定所有用户,使用默认用户身份标识。直接解析查询结果,速度较GetUserAll快。
  744. /// </summary>
  745. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  746. /// <returns>如果不存在,返回null。</returns>
  747. public static List<User> GetUserAllQuick(string rootPath)
  748. {
  749. return GetUserAllQuick(rootPath, null, null);
  750. }
  751.  
  752. /// <summary>
  753. /// 根据userPrincipalName获取Group。
  754. /// </summary>
  755. /// <param name="userPrincipalName">userPrincipalName。</param>
  756. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  757. /// <param name="password">用户身份标识--密码。</param>
  758. /// <returns>如果不存在,返回null。</returns>
  759. public static User GetUserByPrincipalName(string userPrincipalName, string userName, string password)
  760. {
  761. List<DirectoryEntry> entries = Search("userPrincipalName=" + Utils.Escape4Query(userPrincipalName),
  762. "user", "person", null, SearchScope.Subtree, userName, password);
  763. if (entries.Count == 1)
  764. {
  765. DirectoryEntry de = entries[0];
  766.  
  767. User user = new User(de);
  768.  
  769. de.Close();
  770. de.Dispose();
  771.  
  772. return user;
  773. }
  774.  
  775. return null;
  776. }
  777.  
  778. /// <summary>
  779. /// 根据sAMAccountName获取User。
  780. /// </summary>
  781. /// <param name="sAMAccountName">sAMAccountName。</param>
  782. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  783. /// <param name="password">用户身份标识--密码。</param>
  784. /// <returns>如果不存在,返回null。</returns>
  785. public static User GetUserBySAMAccountName(string sAMAccountName, string userName, string password)
  786. {
  787. List<DirectoryEntry> entries = Search("sAMAccountName=" + Utils.Escape4Query(sAMAccountName),
  788. "user", "person", null, SearchScope.Subtree, userName, password);
  789. if (entries.Count == 1)
  790. {
  791. DirectoryEntry de = entries[0];
  792.  
  793. User user = new User(de);
  794.  
  795. de.Close();
  796. de.Dispose();
  797.  
  798. return user;
  799. }
  800.  
  801. return null;
  802. }
  803. #endregion
  804.  
  805. #region Get
  806.  
  807. /// <summary>
  808. /// 根据用户的Guid得到用户对象。
  809. /// </summary>
  810. /// <param name="guid">Guid</param>
  811. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  812. /// <param name="password">用户身份标识--密码。</param>
  813. /// <returns>如果不存在,返回null。</returns>
  814. public static User GetUserByGuid(Guid guid, string userName, string password)
  815. {
  816. return GetUserByPath(Utils.GenerateADsPath(guid), userName, password);
  817. }
  818.  
  819. /// <summary>
  820. /// 根据用户的Guid得到用户对象,使用默认用户身份标识。
  821. /// </summary>
  822. /// <param name="guid">Guid</param>
  823. /// <returns>如果不存在,返回null。</returns>
  824. public static User GetUserByGuid(Guid guid)
  825. {
  826. return GetUserByGuid(guid, null, null);
  827. }
  828.  
  829. /// <summary>
  830. /// 根据用户的DN得到用户对象。
  831. /// </summary>
  832. /// <param name="dn">DN。完全转义过的。</param>
  833. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  834. /// <param name="password">用户身份标识--密码。</param>
  835. /// <returns>如果不存在,返回null。</returns>
  836. public static User GetUserByDN(string dn, string userName, string password)
  837. {
  838. return GetUserByPath(dn, userName, password);
  839. }
  840.  
  841. /// <summary>
  842. /// 根据用户的DN得到用户对象,使用默认用户身份标识。
  843. /// </summary>
  844. /// <param name="dn">DN。完全转义过的。</param>
  845. /// <returns>如果不存在,返回null。</returns>
  846. public static User GetUserByDN(string dn)
  847. {
  848. return GetUserByDN(dn, null, null);
  849. }
  850.  
  851. /// <summary>
  852. /// 根据用户的ADsPath得到用户对象。
  853. /// </summary>
  854. /// <param name="path">ADsPath。完全转义过的。</param>
  855. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  856. /// <param name="password">用户身份标识--密码。</param>
  857. /// <returns>如果不存在,返回null。</returns>
  858. public static User GetUserByPath(string path, string userName, string password)
  859. {
  860. DirectoryEntry entry = GetByPath(path, userName, password);
  861. if (entry != null)
  862. {
  863. User user = new User(entry);
  864. entry.Close();
  865. entry.Dispose();
  866.  
  867. return user;
  868. }
  869. else
  870. return null;
  871. }
  872.  
  873. /// <summary>
  874. /// 根据用户的ADsPath得到用户对象,使用默认用户身份标识。
  875. /// </summary>
  876. /// <param name="path">ADsPath。完全转义过的。</param>
  877. /// <returns>如果不存在,返回null。</returns>
  878. public static User GetUserByPath(string path)
  879. {
  880. return GetUserByPath(path, null, null);
  881. }
  882.  
  883. #endregion
  884.  
  885. #region Password
  886.  
  887. /// <summary>
  888. /// 设置用户密码。
  889. /// </summary>
  890. /// <param name="guid">用户DirectoryEntry的Guid。</param>
  891. /// <param name="newPassword">新密码。</param>
  892. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  893. /// <param name="password">用户身份标识--密码。</param>
  894. public static void SetUserPassword(Guid guid, string newPassword, string userName, string password)
  895. {
  896. DirectoryEntry de = null;
  897. try
  898. {
  899. de = GetByGuid(guid, userName, password);
  900.  
  901. if (de == null)
  902. throw new EntryNotExistException("用户对象不存在。");
  903.  
  904. if (de.SchemaClassName != SchemaClass.user.ToString("F"))
  905. throw new SchemaClassException("对象类型不是" + SchemaClass.user.ToString("F") + "。");
  906.  
  907. de.Invoke("SetPassword", new object[] { newPassword });
  908.  
  909. de.CommitChanges();
  910. }
  911. catch (DirectoryServicesCOMException dsce)
  912. {
  913. throw dsce;
  914. }
  915. finally
  916. {
  917. if (de != null)
  918. {
  919. de.Close();
  920. de.Dispose();
  921. }
  922. }
  923. }
  924.  
  925. /// <summary>
  926. /// 设置用户密码,使用默认用户身份标识。
  927. /// </summary>
  928. /// <param name="guid">用户DirectoryEntry的Guid。</param>
  929. /// <param name="newPassword">新密码。</param>
  930. public static void SetUserPassword(Guid guid, string newPassword)
  931. {
  932. SetUserPassword(guid, newPassword, null, null);
  933. }
  934.  
  935. #endregion
  936.  
  937. #region Move
  938.  
  939. /// <summary>
  940. /// 移动用户DirectoryEntry到指定位置。
  941. /// </summary>
  942. /// <param name="userPath">要移动的用户DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。</param>
  943. /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>
  944. /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>
  945. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  946. /// <param name="password">用户身份标识--密码。</param>
  947. public static void MoveUser(string userPath, string newLocationPath, bool mustOU, string userName, string password)
  948. {
  949. if (!Exists(userPath))
  950. throw new EntryNotExistException("需要被移动的对象不存在。");
  951.  
  952. DirectoryEntry de = null;
  953. try
  954. {
  955. de = GetByPath(userPath, userName, password);
  956.  
  957. MoveUser(de, newLocationPath, mustOU, userName, password);
  958. }
  959. catch
  960. {
  961. throw;
  962. }
  963. finally
  964. {
  965. if (de != null)
  966. {
  967. de.Close();
  968. de.Dispose();
  969. }
  970. }
  971. }
  972.  
  973. /// <summary>
  974. /// 移动用户DirectoryEntry到指定位置,使用默认用户身份标识。
  975. /// </summary>
  976. /// <param name="userPath">要移动的用户DirectoryEntry的ADsPath。必须是DN形式。完全转义过的。</param>
  977. /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>
  978. /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>
  979. public static void MoveUser(string userPath, string newLocationPath, bool mustOU)
  980. {
  981. MoveUser(userPath, newLocationPath, mustOU, null, null);
  982. }
  983.  
  984. /// <summary>
  985. /// 移动用户DirectoryEntry到指定位置。
  986. /// </summary>
  987. /// <param name="user">要移动的用户DirectoryEntry的Guid</param>
  988. /// <param name="newLocation">移动到的位置的Guid</param>
  989. /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>
  990. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  991. /// <param name="password">用户身份标识--密码。</param>
  992. public static void MoveUser(Guid user, Guid newLocation, bool mustOU, string userName, string password)
  993. {
  994. MoveUser(GetUserByGuid(user).Dn, GetOUByGuid(newLocation).Dn, mustOU, userName, password);
  995. }
  996.  
  997. /// <summary>
  998. /// 移动用户DirectoryEntry到指定位置,使用默认用户身份标识。
  999. /// </summary>
  1000. /// <param name="user">要移动的用户DirectoryEntry的Guid</param>
  1001. /// <param name="newLocation">移动到的位置的Guid</param>
  1002. /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>
  1003. public static void MoveUser(Guid user, Guid newLocation, bool mustOU)
  1004. {
  1005. MoveUser(GetUserByGuid(user).Dn, GetOUByGuid(newLocation).Dn, mustOU, null, null);
  1006. }
  1007.  
  1008. /// <summary>
  1009. /// 移动用户DirectoryEntry到指定位置。
  1010. /// </summary>
  1011. /// <param name="de">要移动的用户DirectoryEntry对象。必须是通过DN形式路径得到的对象。</param>
  1012. /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式。完全转义过的。</param>
  1013. /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>
  1014. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1015. /// <param name="password">用户身份标识--密码。</param>
  1016. internal static void MoveUser(DirectoryEntry de, string newLocationPath, bool mustOU, string userName, string password)
  1017. {
  1018. if (!Exists(newLocationPath))
  1019. throw new EntryNotExistException("移动到的位置对象不存在。");
  1020.  
  1021. DirectoryEntry newLocation = null;
  1022. try
  1023. {
  1024. newLocation = GetByPath(newLocationPath, userName, password);
  1025.  
  1026. if (de.SchemaClassName != SchemaClass.user.ToString("F"))
  1027. throw new SchemaClassException("需要被移动的对象类型不是" + SchemaClass.user.ToString("F") + "。");
  1028.  
  1029. if (mustOU && newLocation.SchemaClassName != SchemaClass.organizationalUnit.ToString("F"))
  1030. throw new SchemaClassException("移动到的位置对象类型不是" + SchemaClass.organizationalUnit.ToString("F") + "。");
  1031.  
  1032. if (Exists(Utils.GetRDNValue(de.Properties[BaseObject.PROPERTY_DN].Value.ToString()) + "," +
  1033. newLocation.Properties[BaseObject.PROPERTY_DN].Value.ToString()))
  1034. throw new SameRDNException("移动到的位置下存在同名对象。");
  1035.  
  1036. de.MoveTo(newLocation);
  1037. de.CommitChanges();
  1038. }
  1039. catch (InvalidOperationException ioe) // 指定的 DirectoryEntry 不是容器。
  1040. {
  1041. throw new NotContainerException(ioe.Message, ioe);
  1042. }
  1043. catch (DirectoryServicesCOMException dsce)
  1044. {
  1045. throw dsce;
  1046. }
  1047. finally
  1048. {
  1049. if (newLocation != null)
  1050. {
  1051. newLocation.Close();
  1052. newLocation.Dispose();
  1053. }
  1054. }
  1055. }
  1056.  
  1057. #endregion
  1058.  
  1059. #region MemberOf
  1060.  
  1061. /// <summary>
  1062. /// 获取用户DirectoryEntry对象的PrimaryGroup DirectoryEntry对象。
  1063. /// </summary>
  1064. /// <param name="userPath">用户DirectoryEntry的ADsPath。</param>
  1065. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1066. /// <param name="password">用户身份标识--密码。</param>
  1067. /// <returns>不存在返回null。</returns>
  1068. public static DirectoryEntry GetUserPrimaryGroup(string userPath, string userName, string password)
  1069. {
  1070. DirectoryEntry de = GetByPath(userPath, userName, password);
  1071.  
  1072. if (de == null)
  1073. throw new EntryNotExistException("用户对象不存在。");
  1074.  
  1075. if (de.SchemaClassName != SchemaClass.user.ToString("F"))
  1076. throw new SchemaClassException("对象类型不是" + SchemaClass.user.ToString("F") + "。");
  1077.  
  1078. return GetUserPrimaryGroup(de, userName, password);
  1079. }
  1080.  
  1081. /// <summary>
  1082. /// 获取用户DirectoryEntry对象的PrimaryGroup DirectoryEntry对象,使用默认用户身份标识。
  1083. /// </summary>
  1084. /// <param name="userPath">用户DirectoryEntry的ADsPath。</param>
  1085. /// <returns>不存在返回null。</returns>
  1086. public static DirectoryEntry GetUserPrimaryGroup(string userPath)
  1087. {
  1088. return GetUserPrimaryGroup(userPath, null, null);
  1089. }
  1090.  
  1091. /// <summary>
  1092. /// 获取用户DirectoryEntry对象的PrimaryGroup DirectoryEntry对象。
  1093. /// </summary>
  1094. /// <param name="user">用户DirectoryEntry对象。</param>
  1095. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1096. /// <param name="password">用户身份标识--密码。</param>
  1097. /// <returns>不存在返回null。</returns>
  1098. internal static DirectoryEntry GetUserPrimaryGroup(DirectoryEntry user, string userName, string password)
  1099. {
  1100. string primaryGroupSID = User.GeneratePrimaryGroupSID((byte[])(user.Properties[BaseObject.PROPERTY_OBJECTSID].Value),
  1101. Convert.ToInt32(user.Properties[User.PROPERTY_MEMBEROF_PRIMARY].Value));
  1102.  
  1103. return GetBySid(primaryGroupSID, userName, password);
  1104. }
  1105.  
  1106. /// <summary>
  1107. /// 获取用户DirectoryEntry对象的隶属组的DN。
  1108. /// </summary>
  1109. /// <param name="userPath">用户DirectoryEntry的ADsPath。</param>
  1110. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1111. /// <param name="password">用户身份标识--密码。</param>
  1112. /// <param name="includePrimaryGroup">是否包括PrimaryGroup</param>
  1113. /// <returns>不存在返回空集合。</returns>
  1114. public static List<string> GetUserMemberOfDN(string userPath, string userName, string password, bool includePrimaryGroup)
  1115. {
  1116. DirectoryEntry de = GetByPath(userPath, userName, password);
  1117.  
  1118. if (de == null)
  1119. throw new EntryNotExistException("用户对象不存在。");
  1120.  
  1121. if (de.SchemaClassName != SchemaClass.user.ToString("F"))
  1122. throw new SchemaClassException("对象类型不是" + SchemaClass.user.ToString("F") + "。");
  1123.  
  1124. List<string> dn = new List<string>();
  1125.  
  1126. if (includePrimaryGroup)
  1127. {
  1128. DirectoryEntry primary = GetUserPrimaryGroup(de, userName, password);
  1129. if (primary != null)
  1130. {
  1131. dn.Add(Utils.EscapeDNBackslashedChar(primary.Properties[BaseObject.PROPERTY_DN].Value.ToString()));
  1132.  
  1133. primary.Close();
  1134. primary.Dispose();
  1135. }
  1136. }
  1137. if (de.Properties.Contains(User.PROPERTY_MEMBEROF_ALL))
  1138. {
  1139. foreach (object m in de.Properties[User.PROPERTY_MEMBEROF_ALL])
  1140. {
  1141. dn.Add(Utils.EscapeDNBackslashedChar(m.ToString())); // 转义/
  1142. }
  1143. }
  1144.  
  1145. de.Close();
  1146. de.Dispose();
  1147.  
  1148. return dn;
  1149. }
  1150.  
  1151. /// <summary>
  1152. /// 获取用户DirectoryEntry对象的隶属组的DN,使用默认用户身份标识。
  1153. /// </summary>
  1154. /// <param name="userPath">用户DirectoryEntry的ADsPath。</param>
  1155. /// <param name="includePrimaryGroup">是否包括PrimaryGroup</param>
  1156. /// <returns>不存在返回空集合。</returns>
  1157. public static List<string> GetUserMemberOfDN(string userPath, bool includePrimaryGroup)
  1158. {
  1159. return GetUserMemberOfDN(userPath, null, null, includePrimaryGroup);
  1160. }
  1161.  
  1162. #endregion
  1163.  
  1164. #endregion
  1165.  
  1166. #region Group
  1167.  
  1168. #region Search
  1169.  
  1170. /// <summary>
  1171. /// 获取指定所有组。
  1172. /// </summary>
  1173. /// <param name="cn">组CN。</param>
  1174. /// <param name="description">组描述。</param>
  1175. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1176. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1177. /// <param name="password">用户身份标识--密码。</param>
  1178. /// <returns>如果不存在,返回null。</returns>
  1179. public static List<Group> SearchGroup(string cn, string description, string rootPath, string userName, string password)
  1180. {
  1181. string schema = null;
  1182. if (!String.IsNullOrEmpty(cn) || !String.IsNullOrEmpty(description))
  1183. schema = String.Format("(&{0}{1})",
  1184. (!String.IsNullOrEmpty(cn) ? String.Format("(cn=*{0}*)", Utils.Escape4Query(cn)) : "" ),
  1185. (!String.IsNullOrEmpty(description) ? String.Format("(description=*{0}*)", Utils.Escape4Query(description)) : ""));
  1186.  
  1187. List<DirectoryEntry> entries = Search(schema, "group", null, rootPath, SearchScope.Subtree, userName, password);
  1188. List<Group> groups = new List<Group>();
  1189. foreach (DirectoryEntry de in entries)
  1190. {
  1191. groups.Add(new Group(de));
  1192.  
  1193. de.Close();
  1194. de.Dispose();
  1195. }
  1196.  
  1197. return groups;
  1198. }
  1199.  
  1200. /// <summary>
  1201. /// 获取指定所有组,使用默认用户身份标识。
  1202. /// </summary>
  1203. /// <param name="cn">组CN。</param>
  1204. /// <param name="description">组描述。</param>
  1205. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1206. /// <returns>如果不存在,返回null。</returns>
  1207. public static List<Group> SearchGroup(string cn, string description, string rootPath)
  1208. {
  1209. return SearchGroup(cn, description, rootPath, null, null);
  1210. }
  1211.  
  1212. /// <summary>
  1213. /// 获取指定所有组。
  1214. /// </summary>
  1215. /// <param name="cn">组CN。</param>
  1216. /// <param name="description">组描述。</param>
  1217. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1218. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1219. /// <param name="password">用户身份标识--密码。</param>
  1220. /// <returns>如果不存在,返回null。</returns>
  1221. /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass。
  1222. /// 最后添加了sAMAccountName。</remarks>
  1223. public static List<String[]> SearchGroupSimple(string cn, string description, string rootPath, string userName, string password)
  1224. {
  1225. string schema = null;
  1226. if (!String.IsNullOrEmpty(cn) || !String.IsNullOrEmpty(description))
  1227. schema = String.Format("&{0}{1}",
  1228. (!String.IsNullOrEmpty(cn) ? String.Format("(cn=*{0}*)", Utils.Escape4Query(cn)) : ""),
  1229. (!String.IsNullOrEmpty(description) ? String.Format("(cn=*{0}*)", Utils.Escape4Query(description)) : ""));
  1230.  
  1231. return Search2(schema, "group", null, rootPath, SearchScope.Subtree, userName, password);
  1232. }
  1233.  
  1234. /// <summary>
  1235. /// 获取指定所有组,使用默认用户身份标识。
  1236. /// </summary>
  1237. /// <param name="cn">组CN。</param>
  1238. /// <param name="description">组描述。</param>
  1239. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1240. /// <returns>如果不存在,返回null。</returns>
  1241. /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass</remarks>
  1242. public static List<String[]> SearchGroupSimple(string cn, string description, string rootPath)
  1243. {
  1244. return SearchGroupSimple(cn, description, rootPath, null, null);
  1245. }
  1246.  
  1247. /// <summary>
  1248. /// 获取指定所有组。直接解析查询结果,速度较SearchGroup快。
  1249. /// </summary>
  1250. /// <param name="cn">组CN。</param>
  1251. /// <param name="description">组描述。</param>
  1252. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1253. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1254. /// <param name="password">用户身份标识--密码。</param>
  1255. /// <returns>如果不存在,返回null。</returns>
  1256. public static List<Group> SearchGroupQuick(string cn, string description, string rootPath, string userName, string password)
  1257. {
  1258. string schema = null;
  1259. if (!String.IsNullOrEmpty(cn) || !String.IsNullOrEmpty(description))
  1260. schema = String.Format("&{0}{1}",
  1261. (!String.IsNullOrEmpty(cn) ? String.Format("(cn=*{0}*)", Utils.Escape4Query(cn)) : ""),
  1262. (!String.IsNullOrEmpty(description) ? String.Format("(cn=*{0}*)", Utils.Escape4Query(description)) : ""));
  1263.  
  1264. SearchResultCollection results = Search3(schema, "group", null, rootPath, SearchScope.Subtree, userName, password);
  1265.  
  1266. List<Group> groups = new List<Group>();
  1267. foreach (SearchResult se in results)
  1268. {
  1269. groups.Add(new Group(se));
  1270. }
  1271.  
  1272. return groups;
  1273. }
  1274.  
  1275. /// <summary>
  1276. /// 获取指定所有组,使用默认用户身份标识。直接解析查询结果,速度较SearchGroup快。
  1277. /// </summary>
  1278. /// <param name="cn">组CN。</param>
  1279. /// <param name="description">组描述。</param>
  1280. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1281. /// <returns>如果不存在,返回null。</returns>
  1282. public static List<Group> SearchGroupQuick(string cn, string description, string rootPath)
  1283. {
  1284. return SearchGroupQuick(null,null, rootPath, null, null);
  1285. }
  1286.  
  1287. /// <summary>
  1288. /// 根据sAMAccountName获取Group。
  1289. /// </summary>
  1290. /// <param name="sAMAccountName">sAMAccountName。</param>
  1291. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1292. /// <param name="password">用户身份标识--密码。</param>
  1293. /// <returns>如果不存在,返回null。</returns>
  1294. public static Group GetGroupBySAMAccountName(string sAMAccountName, string userName, string password)
  1295. {
  1296. List<DirectoryEntry> entries = Search("sAMAccountName=" + Utils.Escape4Query(sAMAccountName),
  1297. "group", null, null, SearchScope.Subtree, userName, password);
  1298. if (entries.Count == 1)
  1299. {
  1300. DirectoryEntry de = entries[0];
  1301.  
  1302. Group group = new Group(de);
  1303.  
  1304. de.Close();
  1305. de.Dispose();
  1306.  
  1307. return group;
  1308. }
  1309.  
  1310. return null;
  1311. }
  1312.  
  1313. #endregion
  1314.  
  1315. #region Get
  1316.  
  1317. /// <summary>
  1318. /// 根据用户的Guid得到组对象。
  1319. /// </summary>
  1320. /// <param name="guid">Guid</param>
  1321. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1322. /// <param name="password">用户身份标识--密码。</param>
  1323. /// <returns>如果不存在,返回null。</returns>
  1324. public static Group GetGroupByGuid(Guid guid, string userName, string password)
  1325. {
  1326. return GetGroupByPath(Utils.GenerateADsPath(guid), userName, password);
  1327.  
  1328. }
  1329.  
  1330. /// <summary>
  1331. /// 根据用户的Guid得到组对象,使用默认用户身份标识。
  1332. /// </summary>
  1333. /// <param name="guid">Guid</param>
  1334. /// <returns>如果不存在,返回null。</returns>
  1335. public static Group GetGroupByGuid(Guid guid)
  1336. {
  1337. return GetGroupByGuid(guid, null,null);
  1338. }
  1339.  
  1340. /// <summary>
  1341. /// 根据用户的DN得到用户组。
  1342. /// </summary>
  1343. /// <param name="dn">DN。完全转义过的。</param>
  1344. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1345. /// <param name="password">用户身份标识--密码。</param>
  1346. /// <returns>如果不存在,返回null。</returns>
  1347. public static Group GetGroupByDN(string dn, string userName, string password)
  1348. {
  1349. return GetGroupByPath(dn, userName, password);
  1350. }
  1351.  
  1352. /// <summary>
  1353. /// 根据用户的DN得到组对象,使用默认用户身份标识。
  1354. /// </summary>
  1355. /// <param name="dn">DN。完全转义过的。</param>
  1356. /// <returns>如果不存在,返回null。</returns>
  1357. public static Group GetGroupByDN(string dn)
  1358. {
  1359. return GetGroupByDN(dn, null, null);
  1360. }
  1361.  
  1362. /// <summary>
  1363. /// 根据用户的ADsPath得到组对象。
  1364. /// </summary>
  1365. /// <param name="path">ADsPath。完全转义过的。</param>
  1366. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1367. /// <param name="password">用户身份标识--密码。</param>
  1368. /// <returns>如果不存在,返回null。</returns>
  1369. public static Group GetGroupByPath(string path, string userName, string password)
  1370. {
  1371. DirectoryEntry entry = GetByPath(path, userName, password);
  1372. if (entry != null)
  1373. {
  1374. Group group = new Group(entry);
  1375. entry.Close();
  1376. entry.Dispose();
  1377.  
  1378. return group;
  1379. }
  1380. else
  1381. return null;
  1382.  
  1383. }
  1384.  
  1385. /// <summary>
  1386. /// 根据用户的ADsPath得到组对象,使用默认用户身份标识。
  1387. /// </summary>
  1388. /// <param name="path">ADsPath。完全转义过的。</param>
  1389. /// <returns>如果不存在,返回null。</returns>
  1390. public static Group GetGroupByPath(string path)
  1391. {
  1392. return GetGroupByPath(path, null, null);
  1393. }
  1394.  
  1395. #endregion
  1396.  
  1397. #region Rename
  1398.  
  1399. /// <summary>
  1400. /// 更改组DirectoryEntry对象的名称。
  1401. /// </summary>
  1402. /// <param name="groupPath">组DirectoryEntry的ADsPath</param>
  1403. /// <param name="newName">该项的新名称。</param>
  1404. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1405. /// <param name="password">用户身份标识--密码。</param>
  1406. public static void RenameGroup(string groupPath, string newName, string userName, string password)
  1407. {
  1408. DirectoryEntry de = GetByPath(groupPath, userName, password);
  1409.  
  1410. if (de == null)
  1411. throw new EntryNotExistException("组对象不存在。");
  1412.  
  1413. if (de.SchemaClassName != SchemaClass.group.ToString("F"))
  1414. throw new SchemaClassException("对象类型不是" + SchemaClass.group.ToString("F") + "。");
  1415.  
  1416. string dn = Utils.EscapeDNBackslashedChar(de.Properties[BaseObject.PROPERTY_DN].Value.ToString());
  1417. string rdn = Utils.GenerateRDNCN(newName);
  1418. if(Exists(Utils.GenerateDN(rdn, Utils.GetParentDN(dn))))
  1419. throw new SameRDNException("已存在同名对象。");
  1420. try
  1421. {
  1422. de.Rename(rdn);
  1423.  
  1424. de.CommitChanges();
  1425. }
  1426. catch (DirectoryServicesCOMException dsce)
  1427. {
  1428. throw dsce;
  1429. }
  1430. finally
  1431. {
  1432. if (de != null)
  1433. {
  1434. de.Close();
  1435. de.Dispose();
  1436. }
  1437. }
  1438. }
  1439.  
  1440. /// <summary>
  1441. /// 更改组DirectoryEntry对象的名称,使用默认用户身份标识。
  1442. /// </summary>
  1443. /// <param name="groupPath">组DirectoryEntry的ADsPath</param>
  1444. /// <param name="newName">该项的新名称。</param>
  1445. public static void RenameGroup(string groupPath, string newName)
  1446. {
  1447. RenameGroup(groupPath, newName);
  1448. }
  1449.  
  1450. #endregion
  1451.  
  1452. #region Member Change
  1453.  
  1454. /// <summary>
  1455. /// 将用户添加到组。
  1456. /// </summary>
  1457. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1458. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1459. /// <param name="password">用户身份标识--密码。</param>
  1460. /// <param name="userDN">需要添加的用户的DN。完全转义的。</param>
  1461. public static void AddUserToGroup(string groupPath, string userName, string password, params string[] userDN)
  1462. {
  1463. DirectoryEntry de = GetByPath(groupPath, userName, password);
  1464.  
  1465. if (de == null)
  1466. throw new EntryNotExistException("组对象不存在。");
  1467.  
  1468. if (de.SchemaClassName != SchemaClass.group.ToString("F"))
  1469. throw new SchemaClassException("对象类型不是" + SchemaClass.group.ToString("F") + "。");
  1470.  
  1471. // 得到已有的Member
  1472. List<string> ms = new List<string>();
  1473. foreach (object m in de.Properties[Group.PROPERTY_MEMBER])
  1474. {
  1475. ms.Add(Utils.EscapeDNBackslashedChar(m.ToString()));
  1476. }
  1477. ms.Sort(); // 已排序 -- 以便内部使用
  1478.  
  1479. List<string> toAdd = new List<string>();
  1480. foreach (string udn in userDN)
  1481. {
  1482. if (!(ms.BinarySearch(udn) >= 0))
  1483. {
  1484. if (!toAdd.Exists(delegate(string a ) {return a == udn;}))
  1485. toAdd.Add(udn);
  1486. }
  1487. }
  1488.  
  1489. try
  1490. {
  1491. foreach (string udn in toAdd)
  1492. {
  1493. de.Invoke("Add", new object[] { ParaMgr.LDAP_IDENTITY + udn }); // 需要ADsPath
  1494. }
  1495.  
  1496. de.CommitChanges();
  1497. }
  1498. catch (DirectoryServicesCOMException dsce)
  1499. {
  1500. throw dsce;
  1501. }
  1502. finally
  1503. {
  1504. if (de != null)
  1505. {
  1506. de.Close();
  1507. de.Dispose();
  1508. }
  1509. }
  1510. }
  1511.  
  1512. /// <summary>
  1513. /// 将用户添加到组,使用默认用户身份标识。
  1514. /// </summary>
  1515. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1516. /// <param name="userDN">需要添加的用户的DN。</param>
  1517. public static void AddUserToGroup(string groupPath, params string[] userDN)
  1518. {
  1519. AddUserToGroup(groupPath, null,null,userDN);
  1520. }
  1521.  
  1522. /// <summary>
  1523. /// 将用户添加到组。
  1524. /// </summary>
  1525. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1526. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1527. /// <param name="password">用户身份标识--密码。</param>
  1528. /// <param name="userGuid">需要添加的用户的Guid。</param>
  1529. public static void AddUserToGroup(string groupPath, string userName, string password, params Guid[] userGuid)
  1530. {
  1531. List<string> userDN = new List<string>();
  1532. User user = null;
  1533. foreach(Guid guid in userGuid)
  1534. {
  1535. user = GetUserByGuid(guid);
  1536. if (user != null)
  1537. {
  1538. userDN.Add(user.Dn);
  1539. }
  1540. }
  1541.  
  1542. AddUserToGroup(groupPath, userName, password, userDN.ToArray());
  1543. }
  1544.  
  1545. /// <summary>
  1546. /// 将用户添加到组,使用默认用户身份标识。
  1547. /// </summary>
  1548. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1549. /// <param name="userGuid">需要添加的用户的Guid。</param>
  1550. public static void AddUserToGroup(string groupPath, params Guid[] userGuid)
  1551. {
  1552. AddUserToGroup(groupPath, null, null, userGuid);
  1553. }
  1554.  
  1555. /// <summary>
  1556. /// 将用户从组中移除。
  1557. /// </summary>
  1558. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1559. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1560. /// <param name="password">用户身份标识--密码。</param>
  1561. /// <param name="userDN">需要移除的用户的DN。完全转义的。</param>
  1562. public static void RemoveUserFromGroup(string groupPath, string userName, string password, params string[] userDN)
  1563. {
  1564. DirectoryEntry de = GetByPath(groupPath, userName, password);
  1565.  
  1566. if (de == null)
  1567. throw new EntryNotExistException("组对象不存在。");
  1568.  
  1569. if (de.SchemaClassName != SchemaClass.group.ToString("F"))
  1570. throw new SchemaClassException("对象类型不是" + SchemaClass.group.ToString("F") + "。");
  1571.  
  1572. // 得到已有的Group
  1573. List<string> ms = new List<string>();
  1574. foreach (object m in de.Properties[Group.PROPERTY_MEMBER])
  1575. {
  1576. ms.Add(Utils.EscapeDNBackslashedChar(m.ToString()));
  1577. }
  1578. ms.Sort(); // 已排序 -- 以便内部使用
  1579.  
  1580. List<string> toRemove = new List<string>();
  1581. foreach (string udn in userDN)
  1582. {
  1583. if (ms.BinarySearch(udn) >= 0)
  1584. {
  1585. if (!toRemove.Exists(delegate(string a) { return a == udn; }))
  1586. toRemove.Add(udn);
  1587. }
  1588. }
  1589.  
  1590. try
  1591. {
  1592. foreach (string udn in toRemove)
  1593. {
  1594. de.Invoke("Remove", new object[] { ParaMgr.LDAP_IDENTITY + udn }); // 需要ADsPath
  1595. }
  1596.  
  1597. //de.Invoke("Remove", userDN); // TODO:是否需要保留转义的/,是否需要ADsPath,like AddUserToGroup
  1598.  
  1599. de.CommitChanges();
  1600. }
  1601. catch (DirectoryServicesCOMException dsce)
  1602. {
  1603. throw dsce;
  1604. }
  1605. finally
  1606. {
  1607. if (de != null)
  1608. {
  1609. de.Close();
  1610. de.Dispose();
  1611. }
  1612. }
  1613. }
  1614.  
  1615. /// <summary>
  1616. /// 将用户从组中移除,使用默认用户身份标识。
  1617. /// </summary>
  1618. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1619. /// <param name="userDN">需要移除的用户的DN。</param>
  1620. public static void RemoveUserFromGroup(string groupPath, params string[] userDN)
  1621. {
  1622. RemoveUserFromGroup(groupPath, null,null,userDN);
  1623. }
  1624.  
  1625. /// <summary>
  1626. /// 将用户从组中移除。
  1627. /// </summary>
  1628. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1629. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1630. /// <param name="password">用户身份标识--密码。</param>
  1631. /// <param name="userGuid">需要移除的用户的Guid。</param>
  1632. public static void RemoveUserFromGroup(string groupPath, string userName, string password, params Guid[] userGuid)
  1633. {
  1634. List<string> userDN = new List<string>();
  1635. User user = null;
  1636. foreach(Guid guid in userGuid)
  1637. {
  1638. user = GetUserByGuid(guid);
  1639. if (user != null)
  1640. {
  1641. userDN.Add(user.Dn);
  1642. }
  1643. }
  1644.  
  1645. RemoveUserFromGroup(groupPath, userName, password, userDN.ToArray());
  1646. }
  1647.  
  1648. /// <summary>
  1649. /// 将用户从组中移除,使用默认用户身份标识。
  1650. /// </summary>
  1651. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1652. /// <param name="userGuid">需要移除的用户的Guid。</param>
  1653. public static void RemoveUserFromGroup(string groupPath, params Guid[] userGuid)
  1654. {
  1655. RemoveUserFromGroup(groupPath, null, null, userGuid);
  1656. }
  1657.  
  1658. #endregion
  1659.  
  1660. #region MemberOf & Member
  1661.  
  1662. /// <summary>
  1663. /// 获取组的隶属组的DN
  1664. /// </summary>
  1665. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1666. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1667. /// <param name="password">用户身份标识--密码。</param>
  1668. /// <returns></returns>
  1669. public static List<string> GetGroupMemberOfDN(string groupPath, string userName, string password)
  1670. {
  1671. DirectoryEntry de = GetByPath(groupPath, userName, password);
  1672.  
  1673. if (de == null)
  1674. throw new EntryNotExistException("组对象不存在。");
  1675.  
  1676. if (de.SchemaClassName != SchemaClass.group.ToString("F"))
  1677. throw new SchemaClassException("对象类型不是" + SchemaClass.group.ToString("F") + "。");
  1678.  
  1679. List<string> dn = new List<string>();
  1680. if (de.Properties.Contains(Group.PROPERTY_MEMBEROF))
  1681. {
  1682. foreach (object m in de.Properties[Group.PROPERTY_MEMBEROF])
  1683. {
  1684. dn.Add(Utils.EscapeDNBackslashedChar(m.ToString()));
  1685. }
  1686. }
  1687.  
  1688. de.Close();
  1689. de.Dispose();
  1690.  
  1691. return dn;
  1692. }
  1693.  
  1694. /// <summary>
  1695. /// 获取组的隶属组的DN,使用默认用户身份标识。
  1696. /// </summary>
  1697. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1698. /// <returns></returns>
  1699. public static List<string> GetGroupMemberOfDN(string groupPath)
  1700. {
  1701. return GetGroupMemberOfDN(groupPath, null, null);
  1702. }
  1703.  
  1704. /// <summary>
  1705. /// 获取组的成员(仅用户)
  1706. /// </summary>
  1707. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1708. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1709. /// <param name="password">用户身份标识--密码。</param>
  1710. /// <returns></returns>
  1711. public static List<User> GetGroupUserMember(string groupPath, string userName, string password)
  1712. {
  1713. DirectoryEntry de = GetByPath(groupPath, userName, password);
  1714.  
  1715. if (de == null)
  1716. throw new EntryNotExistException("组对象不存在。");
  1717.  
  1718. if (de.SchemaClassName != SchemaClass.group.ToString("F"))
  1719. throw new SchemaClassException("对象类型不是" + SchemaClass.group.ToString("F") + "。");
  1720.  
  1721. List<User> users = new List<User>();
  1722. string userSchemaClassName = SchemaClass.user.ToString("F");
  1723.  
  1724. if (de.Properties.Contains(Group.PROPERTY_MEMBER))
  1725. {
  1726. foreach (object memberDN in de.Properties[Group.PROPERTY_MEMBER])
  1727. {
  1728. de = GetByDN(Utils.EscapeDNBackslashedChar(memberDN.ToString()), userName, password);
  1729.  
  1730. if (de != null)
  1731. {
  1732. if (de.SchemaClassName == userSchemaClassName)
  1733. {
  1734. users.Add(new User(de));
  1735. }
  1736.  
  1737. de.Close();
  1738. de.Dispose();
  1739. }
  1740. }
  1741. }
  1742.  
  1743. return users;
  1744. }
  1745.  
  1746. /// <summary>
  1747. /// 获取组的成员(仅用户),使用默认用户身份标识。
  1748. /// </summary>
  1749. /// <param name="groupPath">组DirectoryEntry的ADsPath。完全转义的。</param>
  1750. /// <returns></returns>
  1751. public static List<User> GetGroupUserMember(string groupPath)
  1752. {
  1753. return GetGroupUserMember(groupPath, null, null);
  1754. }
  1755.  
  1756. #endregion
  1757.  
  1758. #endregion
  1759.  
  1760. #region OU
  1761.  
  1762. #region Search
  1763.  
  1764. /// <summary>
  1765. /// 获取指定所有组织单位。
  1766. /// </summary>
  1767. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1768. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1769. /// <param name="password">用户身份标识--密码。</param>
  1770. /// <returns>如果不存在,返回null。</returns>
  1771. public static List<OU> GetOUAll(string rootPath, string userName, string password)
  1772. {
  1773. List<DirectoryEntry> entries = Search(null, "organizationalUnit", null, rootPath, SearchScope.Subtree, userName, password);
  1774. List<OU> ous = new List<OU>();
  1775. foreach (DirectoryEntry de in entries)
  1776. {
  1777. ous.Add(new OU(de));
  1778.  
  1779. de.Close();
  1780. de.Dispose();
  1781. }
  1782.  
  1783. return ous;
  1784. }
  1785.  
  1786. /// <summary>
  1787. /// 获取指定所有组织单位,使用默认用户身份标识。
  1788. /// </summary>
  1789. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1790. /// <returns>如果不存在,返回null。</returns>
  1791. public static List<OU> GetOUAll(string rootPath)
  1792. {
  1793. return GetOUAll(rootPath, null, null);
  1794. }
  1795.  
  1796. /// <summary>
  1797. /// 获取指定所有组织单位。
  1798. /// </summary>
  1799. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1800. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1801. /// <param name="password">用户身份标识--密码。</param>
  1802. /// <returns>如果不存在,返回null。</returns>
  1803. /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass</remarks>
  1804. public static List<String[]> GetOUAllSimple(string rootPath, string userName, string password)
  1805. {
  1806. return Search2(null, "organizationalUnit", null, rootPath, SearchScope.Subtree, userName, password);
  1807. }
  1808.  
  1809. /// <summary>
  1810. /// 获取指定所有组织单位,使用默认用户身份标识。
  1811. /// </summary>
  1812. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1813. /// <returns>如果不存在,返回null。</returns>
  1814. /// <remarks>包括distinguishedname,objectguid,name,description,adspath,objectcategory,objectclass</remarks>
  1815. public static List<String[]> GetOUAllSimple(string rootPath)
  1816. {
  1817. return GetOUAllSimple(rootPath, null, null);
  1818. }
  1819.  
  1820. /// <summary>
  1821. /// 获取指定所有组织单位。直接解析查询结果,速度较GetUserAll快。
  1822. /// </summary>
  1823. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1824. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1825. /// <param name="password">用户身份标识--密码。</param>
  1826. /// <returns>如果不存在,返回null。</returns>
  1827. public static List<OU> GetOUAllQuick(string rootPath, string userName, string password)
  1828. {
  1829. SearchResultCollection results = Search3(null, "organizationalUnit", null, rootPath, SearchScope.Subtree, userName, password);
  1830.  
  1831. List<OU> ous = new List<OU>();
  1832. foreach (SearchResult se in results)
  1833. {
  1834. ous.Add(new OU(se));
  1835. }
  1836.  
  1837. return ous;
  1838. }
  1839.  
  1840. /// <summary>
  1841. /// 获取指定所有组织单位,使用默认用户身份标识。直接解析查询结果,速度较GetUserAll快。
  1842. /// </summary>
  1843. /// <param name="rootPath">根对象ADsPath,null表示整个域。</param>
  1844. /// <returns>如果不存在,返回null。</returns>
  1845. public static List<OU> GetOUAllQuick(string rootPath)
  1846. {
  1847. return GetOUAllQuick(rootPath, null, null);
  1848. }
  1849.  
  1850. #endregion
  1851.  
  1852. #region Get
  1853.  
  1854. /// <summary>
  1855. /// 根据组织单位的Guid得到组织单位对象。
  1856. /// </summary>
  1857. /// <param name="guid">Guid</param>
  1858. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1859. /// <param name="password">用户身份标识--密码。</param>
  1860. /// <returns>如果不存在,返回null。</returns>
  1861. public static OU GetOUByGuid(Guid guid, string userName, string password)
  1862. {
  1863. return GetOUByPath(Utils.GenerateADsPath(guid), userName, password);
  1864. }
  1865.  
  1866. /// <summary>
  1867. /// 根据组织单位的Guid得到组织单位对象,使用默认用户身份标识。
  1868. /// </summary>
  1869. /// <param name="guid">Guid</param>
  1870. /// <returns>如果不存在,返回null。</returns>
  1871. public static OU GetOUByGuid(Guid guid)
  1872. {
  1873. return GetOUByGuid(guid, null, null);
  1874. }
  1875.  
  1876. /// <summary>
  1877. /// 根据组织单位的DN得到组织单位对象。
  1878. /// </summary>
  1879. /// <param name="dn">DN。完全转义过的。</param>
  1880. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1881. /// <param name="password">用户身份标识--密码。</param>
  1882. /// <returns>如果不存在,返回null。</returns>
  1883. public static OU GetOUByDN(string dn, string userName, string password)
  1884. {
  1885. return GetOUByPath(dn, userName, password);
  1886. }
  1887.  
  1888. /// <summary>
  1889. /// 根据组织单位的DN得到组织单位对象,使用默认用户身份标识。
  1890. /// </summary>
  1891. /// <param name="dn">DN。完全转义过的。</param>
  1892. /// <returns>如果不存在,返回null。</returns>
  1893. public static OU GetOUByDN(string dn)
  1894. {
  1895. return GetOUByDN(dn, null, null);
  1896. }
  1897.  
  1898. /// <summary>
  1899. /// 根据组织单位的ADsPath得到组织单位对象。
  1900. /// </summary>
  1901. /// <param name="path">ADsPath。完全转义过的。</param>
  1902. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1903. /// <param name="password">用户身份标识--密码。</param>
  1904. /// <returns>如果不存在,返回null。</returns>
  1905. public static OU GetOUByPath(string path, string userName, string password)
  1906. {
  1907. DirectoryEntry entry = GetByPath(path, userName, password);
  1908. if (entry != null)
  1909. {
  1910. OU ou = new OU(entry);
  1911. entry.Close();
  1912. entry.Dispose();
  1913.  
  1914. return ou;
  1915. }
  1916. else
  1917. return null;
  1918. }
  1919.  
  1920. /// <summary>
  1921. /// 根据组织单位的ADsPath得到组织单位对象,使用默认用户身份标识。
  1922. /// </summary>
  1923. /// <param name="path">ADsPath。完全转义过的。</param>
  1924. /// <returns>如果不存在,返回null。</returns>
  1925. public static OU GetOUByPath(string path)
  1926. {
  1927. return GetOUByPath(path, null, null);
  1928. }
  1929.  
  1930. #endregion
  1931.  
  1932. #region Rename
  1933.  
  1934. /// <summary>
  1935. /// 更改组织单位DirectoryEntry对象的名称。
  1936. /// </summary>
  1937. /// <param name="ouPath">组织单位DirectoryEntry的ADsPath。必须是DN形式,且完全转义。</param>
  1938. /// <param name="newName">该项的新名称。</param>
  1939. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1940. /// <param name="password">用户身份标识--密码。</param>
  1941. public static void RenameOU(string ouPath, string newName, string userName, string password)
  1942. {
  1943. DirectoryEntry de = GetByPath(ouPath, userName, password);
  1944.  
  1945. if (de == null)
  1946. throw new EntryNotExistException("组织单位对象不存在。");
  1947.  
  1948. if (de.SchemaClassName != SchemaClass.organizationalUnit.ToString("F"))
  1949. throw new SchemaClassException("对象类型不是" + SchemaClass.organizationalUnit.ToString("F") + "。");
  1950.  
  1951. string dn = Utils.EscapeDNBackslashedChar(de.Properties[BaseObject.PROPERTY_DN].Value.ToString());
  1952. string rdn = Utils.GenerateRDNOU(newName);
  1953. if (Exists(Utils.GenerateDN(rdn, Utils.GetParentDN(dn))))
  1954. throw new SameRDNException("已存在同名对象。");
  1955. try
  1956. {
  1957. de.Rename(rdn);
  1958.  
  1959. de.CommitChanges();
  1960. }
  1961. catch (DirectoryServicesCOMException dsce)
  1962. {
  1963. throw dsce;
  1964. }
  1965. finally
  1966. {
  1967. if (de != null)
  1968. {
  1969. de.Close();
  1970. de.Dispose();
  1971. }
  1972. }
  1973. }
  1974.  
  1975. /// <summary>
  1976. /// 更改组DirectoryEntry对象的名称,使用默认用户身份标识。
  1977. /// </summary>
  1978. /// <param name="ouPath">组织单位DirectoryEntry的ADsPath。必须是DN形式,且完全转义。</param>
  1979. /// <param name="newName">该项的新名称。</param>
  1980. public static void RenameOU(string ouPath, string newName)
  1981. {
  1982. RenameOU(ouPath, newName, null, null);
  1983. }
  1984.  
  1985. /// <summary>
  1986. /// 更改组织单位DirectoryEntry对象的名称。
  1987. /// </summary>
  1988. /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>
  1989. /// <param name="newName">该项的新名称。</param>
  1990. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  1991. /// <param name="password">用户身份标识--密码。</param>
  1992. public static void RenameOU(Guid ouGuid, string newName, string userName, string password)
  1993. {
  1994. RenameOU(TB.ADBlock.ADManager.GetOUByGuid(ouGuid).Dn, newName, userName, password);
  1995. }
  1996.  
  1997. /// <summary>
  1998. /// 更改组织单位DirectoryEntry对象的名称,使用默认用户身份标识。
  1999. /// </summary>
  2000. /// <param name="ouGuid">组织单位DirectoryEntry的ADsPath</param>
  2001. /// <param name="newName">该项的新名称。</param>
  2002. public static void RenameOU(Guid ouGuid, string newName)
  2003. {
  2004. RenameOU(Utils.GenerateADsPath(ouGuid), newName, null, null);
  2005. }
  2006.  
  2007. #endregion
  2008.  
  2009. #region Move
  2010.  
  2011. /// <summary>
  2012. /// 移动组织单位DirectoryEntry到指定位置。
  2013. /// </summary>
  2014. /// <param name="ouPath">要移动的组织单位DirectoryEntry的ADsPath。必须是DN形式,且完全转义。</param>
  2015. /// <param name="newLocationPath">移动到的位置的ADsPath。必须是DN形式,且完全转义。</param>
  2016. /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>
  2017. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  2018. /// <param name="password">用户身份标识--密码。</param>
  2019. public static void MoveOU(string ouPath, string newLocationPath, bool mustOU, string userName, string password)
  2020. {
  2021. if (!Exists(ouPath))
  2022. throw new EntryNotExistException("需要被移动的对象不存在。");
  2023.  
  2024. DirectoryEntry de = null;
  2025. try
  2026. {
  2027. de = GetByPath(ouPath, userName, password);
  2028.  
  2029. MoveOU(de, newLocationPath, mustOU, userName, password);
  2030. }
  2031. catch
  2032. {
  2033. throw;
  2034. }
  2035. finally
  2036. {
  2037. if (de != null)
  2038. {
  2039. de.Close();
  2040. de.Dispose();
  2041. }
  2042. }
  2043. }
  2044.  
  2045. /// <summary>
  2046. /// 移动组织单位DirectoryEntry到指定位置,使用默认用户身份标识。
  2047. /// </summary>
  2048. /// <param name="ouPath">要移动的组织单位DirectoryEntry的ADsPath</param>
  2049. /// <param name="newLocationPath">移动到的位置的ADsPath</param>
  2050. /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>
  2051. public static void MoveOU(string ouPath, string newLocationPath, bool mustOU)
  2052. {
  2053. MoveUser(ouPath, newLocationPath, mustOU, null, null);
  2054. }
  2055.  
  2056. /// <summary>
  2057. /// 移动组织单位DirectoryEntry到指定位置。
  2058. /// </summary>
  2059. /// <param name="ou">要移动的组织单位DirectoryEntry的Guid</param>
  2060. /// <param name="newLocation">移动到的位置的Guid</param>
  2061. /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>
  2062. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  2063. /// <param name="password">用户身份标识--密码。</param>
  2064. public static void MoveOU(Guid ou, Guid newLocation, bool mustOU, string userName, string password)
  2065. {
  2066. MoveUser(TB.ADBlock.ADManager.GetOUByGuid(ou).Dn,
  2067. TB.ADBlock.ADManager.GetOUByGuid(newLocation).Dn, mustOU, userName, password);
  2068. }
  2069.  
  2070. /// <summary>
  2071. /// 移动组织单位DirectoryEntry到指定位置,使用默认用户身份标识。
  2072. /// </summary>
  2073. /// <param name="ou">要移动的组织单位DirectoryEntry的Guid</param>
  2074. /// <param name="newLocationPath">移动到的位置的Guid</param>
  2075. /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>
  2076. public static void MoveOU(Guid ou, Guid newLocationPath, bool mustOU)
  2077. {
  2078. MoveUser(ou, newLocationPath, mustOU, null, null);
  2079. }
  2080.  
  2081. /// <summary>
  2082. /// 移动组织单位DirectoryEntry到指定位置。
  2083. /// </summary>
  2084. /// <param name="de">要移动的组织单位DirectoryEntry对象</param>
  2085. /// <param name="newLocationPath">移动到的位置的ADsPath</param>
  2086. /// <param name="mustOU">移动到的位置对应的DirectoryEntry是否必须是组织单位。</param>
  2087. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  2088. /// <param name="password">用户身份标识--密码。</param>
  2089. internal static void MoveOU(DirectoryEntry de, string newLocationPath, bool mustOU, string userName, string password)
  2090. {
  2091. if (!Exists(newLocationPath))
  2092. throw new EntryNotExistException("移动到的位置对象不存在。");
  2093.  
  2094. DirectoryEntry newLocation = null;
  2095. try
  2096. {
  2097. newLocation = GetByPath(newLocationPath, userName, password);
  2098.  
  2099. if (de.SchemaClassName != SchemaClass.organizationalUnit.ToString("F"))
  2100. throw new SchemaClassException("需要被移动的对象类型不是" + SchemaClass.organizationalUnit.ToString("F") + "。");
  2101.  
  2102. if (mustOU && newLocation.SchemaClassName != SchemaClass.organizationalUnit.ToString("F"))
  2103. throw new SchemaClassException("移动到的位置对象类型不是" + SchemaClass.organizationalUnit.ToString("F") + "。");
  2104.  
  2105. if (Exists(Utils.GetRDNValue(de.Properties[BaseObject.PROPERTY_DN].Value.ToString()) + "," +
  2106. newLocation.Properties[BaseObject.PROPERTY_DN].Value.ToString()))
  2107. throw new SameRDNException("移动到的位置下存在同名对象。");
  2108.  
  2109. de.MoveTo(newLocation);
  2110. de.CommitChanges();
  2111. }
  2112. catch (InvalidOperationException ioe) // 指定的 DirectoryEntry 不是容器。
  2113. {
  2114. throw new NotContainerException(ioe.Message, ioe);
  2115. }
  2116. catch (DirectoryServicesCOMException dsce)
  2117. {
  2118. throw dsce;
  2119. }
  2120. finally
  2121. {
  2122. if (newLocation != null)
  2123. {
  2124. newLocation.Close();
  2125. newLocation.Dispose();
  2126. }
  2127. }
  2128. }
  2129.  
  2130. #endregion
  2131.  
  2132. #region Structure
  2133.  
  2134. /// <summary>
  2135. /// 获取组织单位子树。
  2136. /// </summary>
  2137. /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>
  2138. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  2139. /// <param name="password">用户身份标识--密码。</param>
  2140. /// <returns></returns>
  2141. public OU GetOUSubTree(Guid ouGuid, string userName, string password)
  2142. {
  2143. OU ou = GetOUByGuid(ouGuid);
  2144.  
  2145. if (ou == null)
  2146. throw new EntryNotExistException("组织单位对象不存在。");
  2147.  
  2148. return ou.GetSubTree(userName, password);
  2149. }
  2150.  
  2151. /// <summary>
  2152. /// 获取组织单位子树,使用默认用户身份标识。
  2153. /// </summary>
  2154. /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>
  2155. /// <returns></returns>
  2156. public OU GetOUSubTree(Guid ouGuid)
  2157. {
  2158. return GetOUSubTree(ouGuid, null, null);
  2159. }
  2160.  
  2161. /// <summary>
  2162. /// 获取组织单位子组织单位。
  2163. /// </summary>
  2164. /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>
  2165. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  2166. /// <param name="password">用户身份标识--密码。</param>
  2167. /// <returns></returns>
  2168. public List<OU> GetOUChildren(Guid ouGuid, string userName, string password)
  2169. {
  2170. OU ou = GetOUByGuid(ouGuid);
  2171.  
  2172. if (ou == null)
  2173. throw new EntryNotExistException("组织单位对象不存在。");
  2174.  
  2175. return ou.GetChildren(userName, password);
  2176. }
  2177.  
  2178. /// <summary>
  2179. /// 获取组织单位子组织单位,使用默认用户身份标识。
  2180. /// </summary>
  2181. /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>
  2182. /// <returns></returns>
  2183. public List<OU> GetOUChildren(Guid ouGuid)
  2184. {
  2185. return GetOUChildren(ouGuid, null, null);
  2186. }
  2187.  
  2188. /// <summary>
  2189. /// 获取组织单位父组织单位。
  2190. /// </summary>
  2191. /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>
  2192. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  2193. /// <param name="password">用户身份标识--密码。</param>
  2194. /// <returns></returns>
  2195. public OU GetOUParent(Guid ouGuid, string userName, string password)
  2196. {
  2197. OU ou = GetOUByGuid(ouGuid);
  2198.  
  2199. if (ou == null)
  2200. throw new EntryNotExistException("组织单位对象不存在。");
  2201.  
  2202. return ou.GetParent(userName, password);
  2203. }
  2204.  
  2205. /// <summary>
  2206. /// 获取组织单位父组织单位,使用默认用户身份标识。
  2207. /// </summary>
  2208. /// <param name="ouGuid">组织单位DirectoryEntry的Guid</param>
  2209. /// <returns></returns>
  2210. public OU GetOUParent(Guid ouGuid)
  2211. {
  2212. return GetOUParent(ouGuid, null, null);
  2213. }
  2214.  
  2215. #endregion
  2216.  
  2217. #endregion
  2218.  
  2219. /// <summary>
  2220. /// 通过ADsPath获取对象。目前仅限User,OU和Group
  2221. /// </summary>
  2222. /// <param name="path">ADsPath。完全转义过的。</param>
  2223. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  2224. /// <param name="password">用户身份标识--密码。</param>
  2225. /// <returns>如果不存在,返回null。</returns>
  2226. public static BaseObject GetObjectByPath(string path, string userName, string password)
  2227. {
  2228. BaseObject baseObject = null;
  2229. DirectoryEntry entry = GetByPath(path, userName, password);
  2230. if (entry != null)
  2231. {
  2232. SchemaClass schema = SchemaClass.none;
  2233. try
  2234. {
  2235. schema = (SchemaClass)(Enum.Parse(typeof(SchemaClass), entry.SchemaClassName));
  2236. switch (schema)
  2237. {
  2238. case SchemaClass.user:
  2239. baseObject = new User(entry);
  2240. break;
  2241. case SchemaClass.group:
  2242. baseObject = new Group(entry);
  2243. break;
  2244. case SchemaClass.organizationalUnit:
  2245. baseObject = new OU(entry);
  2246. break;
  2247. }
  2248. }
  2249. catch
  2250. { }
  2251.  
  2252. entry.Close();
  2253. entry.Dispose();
  2254.  
  2255. return baseObject;
  2256. }
  2257. else
  2258. return null;
  2259. }
  2260.  
  2261. /// <summary>
  2262. /// 指定的SAMAccountName用户或组是否存在。
  2263. /// </summary>
  2264. /// <param name="sAMAccountName">sAMAccountName</param>
  2265. /// <param name="an">如果存在,对应的sAMAccountName。</param>
  2266. /// <param name="dn">如果存在,对应的DN。</param>
  2267. /// <param name="precision">true表示完全匹配,false表示前向匹配。</param>
  2268. /// <param name="userName">用户身份标识--用户名。为空时使用默认用户身份标识。</param>
  2269. /// <param name="password">用户身份标识--密码。</param>
  2270. /// <returns>如果不存在,返回false。</returns>
  2271. public static bool SAMAccountNameExists(string sAMAccountName, out string an, out string dn, bool precision,
  2272. string userName, string password)
  2273. {
  2274. an = null;
  2275. dn = null;
  2276. List<DirectoryEntry> entries = Search("sAMAccountName=" + Utils.Escape4Query(sAMAccountName) + "*", null, null, null, SearchScope.Subtree, userName, password);
  2277. if (entries.Count >= 1)
  2278. {
  2279. string schemaClassName = entries[0].SchemaClassName;
  2280. bool valid = ((schemaClassName == SchemaClass.group.ToString("F")) || (schemaClassName == SchemaClass.user.ToString("F")));
  2281.  
  2282. if (valid)
  2283. {
  2284. an = entries[0].Properties["sAMAccountName"].Value.ToString();
  2285. if ((precision && (an == sAMAccountName)) || (!precision))
  2286. {
  2287. dn = Utils.EscapeDNBackslashedChar(entries[0].Properties[BaseObject.PROPERTY_DN].Value.ToString());
  2288. }
  2289. else
  2290. {
  2291. an = null;
  2292. valid = false;
  2293. }
  2294.  
  2295. }
  2296.  
  2297. entries[0].Close();
  2298. entries[0].Dispose();
  2299.  
  2300. return valid;
  2301. }
  2302.  
  2303. return false;
  2304. }
  2305.  
  2306. }
  2307. }

操作Active Directory C#的更多相关文章

  1. C#操作Active Directory(AD)详解

    1. LDAP简介 LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是实现提供被称为目录服务的信息服务.目录服务是一种特殊的数据库系统,其专门 ...

  2. Active Directory组织单位(Organizational Unit)操作汇总

    前言 本章聊Active Directory的组织单位(OU)的新增.修改.移动等操作,使用.NET Framework 为我们提供的System.DirectoryServices程序集. 不积跬步 ...

  3. PHP 通过LDAP协议,操作Windows Active Directory

    原文地址:http://hi.baidu.com/lllangxx/item/3ccb7cdfa13b56eb3dc2cb39 一.学习如何管理Active Directory Active Dire ...

  4. Windows Azure Active Directory (3) China Azure AD增加新用户

    <Windows Azure Platform 系列文章目录> 本文介绍的是国内由世纪互联运维的China Azure. 本文是对笔者之前的文档:Windows Azure Active ...

  5. DNS笔记 DNS区域集成到 Active Directory

    可以将 DNS 区域集成到 Active Directory 中以提供增强的容错功能和安全性.OpenDNS   Google Public DNS往返时间 (RTT) 远程访问服务 (RAS)域名与 ...

  6. install Active Directory域控制器

    设置Active Directory域控制器 正如我们在网络与系统配置专题文章中所提到的那样,我们已将两部服务器设置为对应于内部域“intdomain.com”的Active Directory域控制 ...

  7. 移动服务和 Azure Active Directory 中基于角色的访问控制

    编辑人员注释:本文章由 Matthew Henderson撰写 去年 11月,我们发布了 Azure Active Directory (AAD) 预览版作为移动服务身份提供程序.此举旨在为企业开 ...

  8. 宣布正式发布 Biz Talk Services、Azure Active Directory 和 Traffic Manager, 同时发布 Azure Active Directory 高级版预览

    除经济优势之外,云计算还在可转化为竞争优势的应用程序开发方面提供了更大的灵活性.我们很高兴看到每天创建的新 Windows Azure 订阅超过 1000 个,更令人兴奋的是,有一半客户使用价值更高的 ...

  9. PowerShell 批量导入/导出Active Directory

    PowerShell 批量导入/导出Active Directory         近期由于公司要求,须要导入20个供应商.20个客户到AD域中,刚開始手动添�了2个供应商,2个客户.可是感觉费时费 ...

随机推荐

  1. Docker Run 设置环境变量

    Docker Run We can then override the environment variables set in the Docker file when running the im ...

  2. leetcode 283 Move Zeros; 27 Remove Elements; 26 Remove Duplicated from Sorted Array;

    ,,,,}; //把数组的值赋给vector vector<int> vec(arr, arr+sizeof(arr)/sizeof(int)); 解法一: 时间复杂度O(n) 空间复杂度 ...

  3. Python- sort()/sorted()

    Python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列. sorted(iterable,key=None,revers ...

  4. bzoj 1189 二分+最大流

    题目传送门 思路: 先预处理出每个人到每扇门的时间,用门作为起点进行bfs处理. 然后二分时间,假设时间为x,将每扇门拆成1到x,x个时间点,表示这扇门有几个时间点是可以出去的.对于一扇门,每个时间点 ...

  5. C# 判断两个集合(List)是否相等

    1.两个list如果有重复元素(如List1: a,b,a  List2: b,b,a) 是无法通过包含关系来判断是否相等的. 有两个办法,其一是两个List排序后再按顺序比较.另一个办法就是计算各元 ...

  6. 2019.3.28 JDBC相关

    JDBC(Java Data Base Connectivity) JDBC是一组用Java编写的类和接口 使用JDBC的好处: 1.Java的开发人员完全不需要关心数据库的连接方式和实现手段 2.提 ...

  7. MYSQL分区表详解

    分区表对用户来说是一个独立的逻辑表,但是底层是多个物理字表组成的.分区代码实际上是对一组底层表的句柄对象封装.对分区表的请求,都会通过句柄对象转化成储存引擎的接口调用.所以分区对于SQL层来说是一个完 ...

  8. TabLayout实现底部导航栏(2)

    TabLayout是android.support.design里的一个控件,使用它可以很方便的做出顶部导航和底部导航.类似于这样的,能设置选中时字体的颜色和选中时的图片. 效果如图: 首先我们在 b ...

  9. C#知识点提要

    本篇博文主要对asp.net mvc开发需要撑握的C#语言知识点进行简单回顾,尤其是C# 3.0才有的一些C#语言特性.对于正在学asp.net mvc的童鞋,不防花个几分钟浏览一下.本文要回顾的C# ...

  10. 牛客网Java刷题知识点之HashMap的实现原理、HashMap的存储结构、HashMap在JDK1.6、JDK1.7、JDK1.8之间的差异以及带来的性能影响

    不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑          ...