【转】 如何利用C#代码来进行操作AD

摘要:
如果只需要查询或更改AD组织单位、组和用户的属性,则可以使用以上两个类。值得注意的是,在AD中,某些属性被拒绝修改。一旦修改了不允许修改的属性,它将被服务器拒绝,或者服务器将不执行操作异常。
要用代码访问 Active Directory域服务,需引用System.DirectoryServices命名空间,该命名空间包含两个组件类,DirectoryEntry和 DirectorySearcher。DirectoryEntry类可封装 ActiveDirectory域服务层次结构中的节点或对象,使用此类绑定到对象、读取属性和更新特性;使用DirectorySearcher类可对 Active Directory域服务层次结构执行查询。

如果仅要对AD的组织单元,群组和用户进行查询或者更改属性,使用上述两个类即可。下面给出的是查询在AD中某个组织单元下的所有用户部分代码:

DirectoryEntry objDE = new DirectoryEntry(strADRootPath, strADAccount, strADPassword);  
string strFilter = "(&(objectCategory=person)(objectClass=user))";  
DirectorySearcher objSearcher = new DirectorySearcher(objDE, strFilter);  
//排序  
objSearcher.Sort = new SortOption("name", SortDirection.Ascending);  
SearchResultCollection src = objSearcher.FindAll();

其中ADPath是要查询组织单元的所在的LDAP,其格式为:LDAP:\ OU=XX部门,OU=XX公司,DC=域名,DC=COM,如果连接到的AD是在服务器上那么格式写成LDAP:\XX.XX.XX.XX OU=XX部门,OU=XX公司,DC=域名,DC=COM(XX.XX.XX.XX为服务器IP);ADAccount和ADPwd为AD用户的账户和密码,如果是管理员则可以进行任何操作,普通只能进行查询操作。

执行上述代码即可获取到在某个指定组织单元的所有用户,搜索结果存放在src中,要读取用户属性值可使用下面代码:

//获取用户的名称和账户  
foreach (SearchResult sr in src)  
{  
  strUserName=sr.Properties["name"][0].ToString();  
  strUserName= sr.Properties["userPrincipalName"][0].ToString();  
}  

值得注意的是因为在创建AD用户的时候填写的用户信息不同,每个AD用户所具有的属性都不一定相同,建议使用如下方法进行取值:

if (sr.Properties.Contains("sn"))  
{  
    strFirstName = sr.Properties["sn"][0].ToString();//
}  
if (sr.Properties.Contains("givenName"))  
{  
    strLastName = sr.Properties["givenName"][0].ToString();//
}  

要知道一个用户的所有属性可使用如下代码:

foreach (string strPropNamein sr.Properties.PropertyNames)  
{  
    Console.WriteLine(strPropName);  
}  

还有一种读取AD用户属性字段值的方法:

foreach (SearchResult sr in src)  
{  
    DirectoryEntry myde = sr.GetDirectoryEntry();  
    strGuid = myde.Guid.ToString();//用户Guid,创建用户时由系统自动生成  
    strParentGuid = myde.Parent.Guid.ToString();//用户所在组织单元的Guid  
    myde.Properties["name"][0].ToString();//用户名称  
}  

同样的,如果要得到是AD组织单元或者群组的话也是这么做,对应于组织单元筛选字符串可以这么写:

//字符筛选器,筛选类型为OU的对象  
string strFilter = "(&(objectCategory=organizationalUnit)(objectClass=organizationalUnit))";  

群组的筛选字符串:

string strFilter = "(&(objectCategory=group)(objectClass=group))";  

 上面是对AD的查询操作,如果查询之后需要修改,仅需要做些许变动,下面是修改用户属性部分代码:

foreach (SearchResult sr in src)  
{  
    string strUserName = sr.Properties["name"][0].ToString();  
    //targetUserName:要修改用户名称  
    if (strUserName.Equals(targetUserName))  
    {  
        DirectoryEntryde = sr.GetDirectoryEntry();  
        de.Properties["sn"].Value = m_User.FirstName;//
        de.Properties["givenName"].Value = m_User.LastName;//
        de.Properties["mobile"].Value = m_User.Mobile;//移动电话                      
        de.CommitChanges();  
    }  
}  

 修改AD组织单元或者群组也是用类似的方法。值得注意的是,在AD中有些属性是拒绝修改的,一旦修改了不允许修改的属性,会被服务器拒绝或者出现服务器不愿意执行该操作异常。

若要向AD中添加用户,组织单元或者群组的话也是需要通过DirectoryEntry来添加,如下是向AD的指定路径添加一个用户:

public bool AddUser2AD(string strUserName, string strSAMAccountname,  
                        string strPassword, string strPath)  
{  
    string strname = "CN=" + strUserName;  
    try  
    {  
        // strADAccount ,strADPassword为AD管理员账户和密码  
        DirectoryEntry objDE = new DirectoryEntry(strPath, strADAccount, strADPassword);  
        DirectoryEntries objDES = objDE.Children;  
        DirectoryEntry myDE = objDES.Add(strname, "User");  
        myDE.Properties["userPrincipalName"].Value = strSAMAccountname;  
        myDE.Properties["name"].Value = strUserName;  
        myDE.Properties["sAMAccountName"].Value = strSAMAccountname;  
        myDE.CommitChanges();  
  
        //设置密码                
        IADsUser objUser = myDE.NativeObject as IADsUser;  
        objUser.SetPassword(strPassword);  
        //设置用户状态:密码永不过期(65536)+用户正常(512)= 66048  
        objUser.Put("userAccountControl", 66048);  
        objUser.SetInfo();  
    }  
    catch  
    {  
        return false;  
    }  
    return true;  
}  

特别要注意最后几行设置用户密码和账户状态代码。如果myDE.CommitChanges()后面的代码没有;,那么在AD里面创建的用户是禁用状态,并且密码为空。如果在AD中直接写:

myDE.Password = strPassword;  
myDE.Properties["userAccountControl"].Value = 66048;  

是会失败的。这里我们可以利用ActiveDs.dll。ActiveDs是一个AD服务相关应用程序COM接口,里面提供了设置密码,修改密码,获取属性值的一些方法。按照如上写法即可创建正常的AD用户,切用户密码永不过期。

解释一下userAccountControl,该属性记录了用户的AD账号信息,是一组16进制数,该属性标志是累积性的。若要禁用用户的帐户,将userAccountControl属性设置为 0x0202 (0x002 + 0x0200)。在十进制中,它是 514 (2 + 512);若要启用账户且密码永不过期,请将 userAccountControl属性设置为 0x10200 (0x10000 + 0x0200),十进制为66048。

若想要修改用户密码的话也可以使用ActiveDs提供的方法:

DirectoryEntry obj = sr.GetDirectoryEntry();  
IADsUser objUser = obj.NativeObject as IADsUser;  
objUser.ChangePassword(strOldPassword, strNewPassword);  
objUser.SetInfo();  

最后提供一个验证AD用户身份的方法以资参考:

/// <summary>  
 ///验证用户登录  
 ///</summary>  
 ///<param name="strUserAccount">用户账户</param>  
 ///<param name="strPassword">用户密码</param>  
 ///<returns>验证通过则返回true,否则返回false</returns>  
public static bool VerifyUserLogin(string strUserAccount, stringstrPassword)  
 {  
    try  
    {  
        // strADRootPath为该组织单元路径  
        DirectoryEntry objDE = newDirectoryEntry(strADRootPath, strUserAccount, strPassword);                  
        DirectorySearcher objSerach = new DirectorySearcher(objDE);  
        SearchResult sr = objSerach.FindOne();  
        return true;  
    }  
    catch  
    {  
        return false;  
    }  
 } 

原文地址:http://blog.csdn.net/dl020840504/article/details/10200227

其他文章推荐:http://www.cnblogs.com/springyangwc/archive/2012/02/07/2340987.html

免责声明:文章转载自《【转】 如何利用C#代码来进行操作AD》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇查询条件(规约模式应用)Java中取一个随机数-Random类的使用注意下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C#调用WPS将文档转换成pdf进行预览

vs启动项目可以生成wps实例 本地iis部署的站点却不行 原因是vs是管理员权限,而iis没有权限 解决方法 启动IIS,应用程序池-“选定的应用程序池”-高级设置-进程模型-标识:设置为管理员账号administrator     代码 1.安装WPS 2016 专业版 2.方法一:在项目中引用etapi.dll,wpsapi.dll,wpp...

JSSDK实现微信自定义分享---java 后端获取签名信息

一、首先说下关于微信Access_token的问题,微信Access_token分为2中: 1.授权token获取方式: 这种token需要code值(如何获取code值查看官方文档) 1 "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret="...

string替换所有指定字符串(C++)

C++的string提供了replace方法来实现字符串的替换,但是对于将字符串中某个字符串全部替换这个功能,string并没有实现,我们今天来做的就是这件事。 首先明白一个概念,即string替换所有字符串,将"12212"这个字符串的所有"12"都替换成"21",结果是什么? 可以是22211,也可以是21221,有时候应用的场景不同,就会希望得到不同...

使用javaMail接收邮件(比较全)

package org.davidfang.mail;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutpu...

Kafka入门教程(转)

原文:https://www.aboutyun.com//forum.php/?mod=viewthread&tid=12882&extra=page%3D1&page=1& 1.Kafka独特设计在什么地方?2.Kafka如何搭建及创建topic、发送消息、消费消息?3.如何书写Kafka程序?4.数据传输的事务定义有哪三...

java生成解析xml的另外两种方法JAXB

   JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示...