Exchange服务器之C#操作AD及Exchange Server总结
白羽 2018-07-25 来源 :网络 阅读 1197 评论 0

摘要:本文将带你了解Exchange服务器之C#操作AD及Exchange Server总结,希望本文对大家学Exchange有所帮助

总结对AD及Exchange Server的操作,包括新建AD用户,设置密码,为AD用户创建邮箱等。

文档目录:
测试环境及需求简述对AD操作
引入DLL及方法简述新增OU或Security Group新建AD User添加用户到组或从组中删除用户用户信息更新Enable/Disable用户账号对Exchange Server操作
为AD用户新建邮箱配置客户端和服务器总结归纳一、测试环境及需求简述
1、测试环境
服务器:windows server 2008R2
Exchange:Exchange Server 2010 sp1
开发工具:Visual Studio 2010
一台exchange服务器+一台AD服务器+一台承载测试程序的服务器
2、需求简述
根据提供的信息创建对应的OU根据提供的用户信息新建AD用户根据提供的信息修改AD用户为AD用户二、AD操作
1、引入DLL及方法简述
MS提供了远程操作AD的DLL:System.DirectoryServices(添加引用中有);
其中,我们使用LDAP协议访问AD,LDAP翻译为轻量目录访问协议。
在使用的时候,需要注意一些问题:
如果在WEB应用中使用,在数据量大的时候回产生超时的问题,建议采取其他方式如MS MQ等方式处理信息,避免超时的问题。使用LDAP会有安全风险,毕竟通过网络传输用户凭证并不是很安全,最好是运行在企业内网。DirectoryServices其实提供了其他很多操作,如对IIS的操作,对本地用户的操作,有兴趣的可以了解下。
2、新增OU或Security Group
 首先新建一个控制台应用程序

添加服务引用:

在项目中新建一个ADHelper.cs用来提供AD操作的公用方法


public class ADHelper
    {
        /// <summary>
        /// 创建连接
        /// </summary>
        /// <returns></returns>
        public static DirectoryEntry GetDirectoryEntry()
        {
            DirectoryEntry de = new DirectoryEntry();
            de.Path = "LDAP://AD服务器地址/OU=CompanyA,DC=contoso,DC=com";
            de.Username = @"contoso\管理员账号";
            de.Password = "管理员密码";
            return de;
        }

        /// <summary>
        /// 带有一个参数的创建连接重载
        /// </summary>
        /// <param name="DomainReference"></param>
        /// <returns></returns>
        public static DirectoryEntry GetDirectoryEntry(string DomainReference)
        {
            DirectoryEntry entry = new DirectoryEntry(DomainReference, "管理员账号", "管理员密码", AuthenticationTypes.Secure);
            return entry;
        }
    }


ADHelper
 ADHelper代码解释:
新建一个DirectoryEntry类,也就是活动目录的入口类指定要连接到的Path,在稍后的新建OU实例中会详细解释Path的组成用来连接AD的管理员账号,此管理员账号必须有操作AD的权限管理员的密码,同样是为了连接AD重载的GetDirectoryEntry是为了根据输入的路径引用此路径的入口,稍后会用到 新建一个ADManage.cs操作类,用来定义具体的操作方法:


/// <summary>
        /// 新建OU
        /// </summary>
        /// <param name="path"></param>
        public void CreateOU(string name)
        {
            if (!ObjectExists(name, "OU"))
            {
                DirectoryEntry dse = ADHelper.GetDirectoryEntry();
                DirectoryEntries ous = dse.Children;
                DirectoryEntry newou = ous.Add("OU=" + name, "OrganizationalUnit");
                newou.CommitChanges();
                newou.Close();
                dse.Close();
            }
            else
            {
                Console.WriteLine("OU已存在");
            }
        }


CreateOU
新建OU代码解释:
ObjectExists方法判断新增的OU是否已经存在,代码下面会附上利用ADHelper生成目录入口,本例是在一个测试的CompanyA OU中Children属性获取所有子项,并使用Add方法添加OU提交更改,发回服务器

 /// <summary>
        /// 新建Security Group
        /// </summary>
        /// <param name="path"></param>
        public void CreateGroup(string name)
        {
            if (!ObjectExists(name, "Group"))
            {
                DirectoryEntry dse = ADHelper.GetDirectoryEntry();
                DirectoryEntries Groups = dse.Children;
                DirectoryEntry newgroup = Groups.Add("CN=" + name, "group");
                newgroup.CommitChanges();
                newgroup.Close();
                dse.Close();
            }
            else
            {
                Console.WriteLine("用户组已存在");
            }
        }


CreateGroup


/// <summary>
       /// 判断是否存在
       /// </summary>
       /// <param name="objectName"></param>
       /// <param name="catalog"></param>
       /// <returns></returns>
        public bool ObjectExists(string objectName, string catalog)
        {
            DirectoryEntry de = ADHelper.GetDirectoryEntry();
            DirectorySearcher deSearch = new DirectorySearcher();
            deSearch.SearchRoot = de;
            switch (catalog)
            {
                case "User": deSearch.Filter = "(&(objectClass=user) (cn=" + objectName + "))"; break;
                case "Group": deSearch.Filter = "(&(objectClass=group) (cn=" + objectName + "))"; break;
                case "OU": deSearch.Filter = "(&(objectClass=OrganizationalUnit) (OU=" + objectName + "))"; break;
                default: break;
            }
            SearchResultCollection results = deSearch.FindAll();
            if (results.Count == 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }


ObjectExists
操作方法写好后,我们就来测试一下
在Program中写测试代码:


static void Main(string[] args)
        {
            ADManage manage=new ADManage();
            //Test create ou
            Console.WriteLine("Create OU Start...");
            try
            {
                manage.CreateOU("NewOU01");
                Console.WriteLine("Create OU Finish...");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Create OU Error...");
                Console.WriteLine(ex);
                Console.ReadLine();
            }

            //Test create group
            Console.WriteLine("Create Group Start...");
            try
            {
                manage.CreateGroup("NewGroup01");
                Console.WriteLine("Create Group Finish...");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Create Group Error...");
                Console.WriteLine(ex);
                Console.ReadLine();
            }
        }


测试代码
运行代码
 
域控中查看结果:

补充:
如何在多层OU下创建新的OU?
OU类似于文件夹,在不同的目录中可以有相同名字的OU,想要在多层OU下创建OU,首先要确认路径Path
假设有一个OU,path为:
CompanyA
BranchB
DepartmentC
则GetDirectoryEntry实例中的path属性应该修改为:
“LDAP://AD服务器地址/OU=DepartmentC,OU=BranchB,OU=CompanyA,DC=contoso,DC=com”,这样新建的OU就会在DepartmentC目录下。
3、新建AD User
新建User与新建OU或组有一些不同,先看代码:


/// <summary>
        /// 新建用户
        /// </summary>
        /// <param name="name"></param>
        /// <param name="login"></param>
        public void CreateUser(string name, string login)
        {
            if (ObjectExists(login, "User"))
            {
                Console.WriteLine("用户已存在");
                Console.ReadLine();
                return;
            }
            DirectoryEntry de = ADHelper.GetDirectoryEntry();
            DirectoryEntries users = de.Children;
            DirectoryEntry newuser = users.Add("CN=" + login, "user");
            SetProperty(newuser, "givenname", name);
            SetProperty(newuser, "SAMAccountName", login);
            SetProperty(newuser, "userPrincipalName", login + "@contoso.com");
            newuser.CommitChanges();
            SetPassword(newuser.Path);
            newuser.CommitChanges();     
            newuser.Close();
            de.Close();
        }

        /// <summary>
        /// 属性设置
        /// </summary>
        /// <param name="de"></param>
        /// <param name="PropertyName"></param>
        /// <param name="PropertyValue"></param>
        public static void SetProperty(DirectoryEntry de, string PropertyName, string PropertyValue)
        {
            if (PropertyValue != null)
            {
                if (de.Properties.Contains(PropertyName))
                {
                    de.Properties[PropertyName][0] = PropertyValue;
                }
                else
                {
                    de.Properties[PropertyName].Add(PropertyValue);
                }
            }
        }

        /// <summary>
        /// 密码设置
        /// </summary>
        /// <param name="path"></param>
        public void SetPassword(string path)
        {
            DirectoryEntry user = new DirectoryEntry();
            user.Path = path;
            user.AuthenticationType = AuthenticationTypes.Secure;
            object ret = user.Invoke("SetPassword",new object[] {"Password01!"});
            user.CommitChanges();
            user.Close();
        }


CreateUser
新建用户代码解释:
利用ObjectExists判断用户是否存在,如果存在则提示用户已存在新建入口类实例,Add方法新增用户SetProperty设置新用户的属性(显示名、Pre-Windows 2000登录名、登录名),并提交更改SetPassword设置用户初始密码,提交更改,关闭连接编写测试代码:


static void Main(string[] args)
        {
            ADManage manage=new ADManage();
            Console.WriteLine("Create User Start...");
            try
            {
                manage.CreateUser("Employee John", "Employee01");
                Console.WriteLine("Create User Finish...");
                Console.ReadLine();
            }
            catch (System.DirectoryServices.DirectoryServicesCOMException ex)
            {
                Console.WriteLine("Create User Error...");
                Console.WriteLine(ex);
                Console.ReadLine();
            }
        }


测试代码
测试结果:


注意:此时新建的账户是停用状态,后面的章节会介绍如何启用/停用
 4、添加用户到组或从组中删除用户
 在组中添加/删除用户使用到DirectorySearcher,用来查找组,见代码:


 /// <summary>
        /// 添加用户到组
        /// </summary>
        /// <param name="de"></param>
        /// <param name="userDn"></param>
        /// <param name="GroupName"></param>
        public void AddUserToGroup(DirectoryEntry de, string userDn, string GroupName)
        {
            DirectorySearcher deSearch = new DirectorySearcher();
            deSearch.SearchRoot = de;
            deSearch.Filter = "(&(objectClass=group) (cn=" + GroupName + "))";
            SearchResult Groupresult = deSearch.FindOne();
            if (Groupresult != null)
            {
                DirectoryEntry user = ADHelper.GetDirectoryEntry("LDAP://AD服务器/" + userDn);
                if (user != null)
                {
                    DirectoryEntry dirEntry = Groupresult.GetDirectoryEntry();
                    if (dirEntry.Properties["member"].Contains(userDn))
                    {
                        Console.WriteLine("用户组中已存在该用户,即将移除");
                        dirEntry.Properties["member"].Remove(userDn);
                        Console.WriteLine("用户已从组中移除");
                    }
                    else
                    {
                        dirEntry.Properties["member"].Add(userDn);
                        Console.WriteLine("添加成功,用户已添加到组");
                    }
                    dirEntry.CommitChanges();
                    dirEntry.Close();
                }
                else
                {
                    Console.WriteLine("用户不存在");
                }
                user.Close();
            }
            else
            {
                Console.WriteLine("用户组不存在");
            }
            return;
        }


AddUserToGroup
代码解释:
新建DirectorySearcher实例,为Filter赋值,根据传入的参数de目录查找该安全组(注意:此组需要包含在DirectoryEntry中)根据参数userDn判断用户是否存在(userDn是用户的标识名如:“CN=Employee01,OU=CompanyA,DC=rzh,DC=com”)dirEntry.Properties["member"].Contains(userDn)判断组中是否存在该用户如果该组不存在该用户,则添加用户到组。如果该组中存在该用户,则将该用户从组中移除测试一下,这里只测试添加,移除操作请自行测试:


class Program
    {
        static void Main(string[] args)
        {
            ADManage manage=new ADManage();
            Console.WriteLine("Add user to group Start...");
            try
            {
                manage.AddUserToGroup(ADHelper.GetDirectoryEntry(), "CN=Employee01,OU=CompanyA,DC=contoso,DC=com", "NewGroup01");
                Console.WriteLine("Add user to group Finish...");
                Console.ReadLine();
            }
            catch (System.DirectoryServices.DirectoryServicesCOMException ex)
            {
                Console.WriteLine("Add user to group Error...");
                Console.WriteLine(ex);
                Console.ReadLine();
            }
        }
    }


测试代码
测试结果:


5、用户信息更新
用户信息更新也比较简单,直接上示例代码+测试代码,如果有疑问,随时联系:


 public void ModifyUser(DirectoryEntry de,string UserName,string company)
        {
            DirectorySearcher deSearch = new DirectorySearcher();
            deSearch.SearchRoot = de;
            deSearch.Filter = "(&(objectClass=user) (cn=" + UserName + "))";
            SearchResult result = deSearch.FindOne();
            if (result != null)
            {
                DirectoryEntry dey = ADHelper.GetDirectoryEntry(result.Path);
                SetProperty(dey, "company", company);
                dey.CommitChanges();
                dey.Close();
            }
            de.Close();
        }


ModifyUser


 static void Main(string[] args)
        {
            ADManage manage=new ADManage();
            Console.WriteLine("Modify user info Start...");
            try
            {
                manage.ModifyUser(ADHelper.GetDirectoryEntry(), "Employee01", "CompanyA");
                Console.WriteLine("Modify user info Finish...");
                Console.ReadLine();
            }
            catch (System.DirectoryServices.DirectoryServicesCOMException ex)
            {
                Console.WriteLine("Modify user info Error...");
                Console.WriteLine(ex);
                Console.ReadLine();
            }
        }


测试代码
6、Enable/Disable用户账号
 Enable/Disable用户账号用到了新的属性userAccountControl,可以对账号密码的是否过期,账号是否可用等进行设置。
以下是设置userAccountControl时会用到值


        SCRIPT 0x0001
        ACCOUNTDISABLE 0x0002
        HOMEDIR_REQUIRED 0x0008
        LOCKOUT 0x0010
        PASSWD_NOTREQD 0x0020
        PASSWD_CANT_CHANGE 0x0040
        ENCRYPTED_TEXT_PWD_ALLOWED 0x0080
        TEMP_DUPLICATE_ACCOUNT 0x0100
        NORMAL_ACCOUNT 0x0200
        INTERDOMAIN_TRUST_ACCOUNT 0x0800
        WORKSTATION_TRUST_ACCOUNT 0x1000
        SERVER_TRUST_ACCOUNT 0x2000
        DONT_EXPIRE_PASSWORD 0x10000
        MNS_LOGON_ACCOUNT 0x20000
        SMARTCARD_REQUIRED 0x40000
        TRUSTED_FOR_DELEGATION 0x80000
        NOT_DELEGATED 0x100000
        USE_DES_KEY_ONLY 0x200000
        DONT_REQ_PREAUTH 0x400000
        PASSWORD_EXPIRED 0x800000
        TRUSTED_TO_AUTH_FOR_DELEGATION 0x1000000


UserAccountControl
具体代码如下:


 /// <summary>
        /// 启用账号
        /// </summary>
        /// <param name="de"></param>
        public void EnableAccount(DirectoryEntry de)
        {
            //设置账号密码不过期
            int exp = (int)de.Properties["userAccountControl"].Value;
            de.Properties["userAccountControl"].Value = exp | 0x10000;
            de.CommitChanges();
            //启用账号
            int val = (int)de.Properties["userAccountControl"].Value;
            de.Properties["userAccountControl"].Value = val & ~0x0002;
            de.CommitChanges();
        }


EnableAccount


/// <summary>
        /// 停用账号
        /// </summary>
        /// <param name="de"></param>
        public void DisableAccount(DirectoryEntry de)
        {
            //启用账号
            int val = (int)de.Properties["userAccountControl"].Value;
            de.Properties["userAccountControl"].Value = val | 0x0002;
            de.CommitChanges();
        }


DisableAccount

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标系统运维之Exchange频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程