• 热门专题

.NET通过PowerShell操作ExChange为用户开通邮箱账号

作者:opps  发布日期:2014-06-17 21:18:54
Tag标签:账号  邮箱  用户  
  • 最近工作中一个web项目需要集成exchange邮箱服务,注册用户时需要动态创建邮箱用户,终于在http://www.cnblogs.com/gongguo/archive/2012/03/12/2392049.html中找到了解决方案。但在实现的过程中还是出现了些问题,经过几次尝试终于成功调用。

    就自己碰到的问题记录下来共勉。

    直接用C#代码访问ExChange不会报错,但不会成功创建邮箱用户,主要是因为权限不足导致。

    微软出了一个PowerShell的命令行工具 能够用命令行来操作ExChange,创建邮箱账号的命令是 new-mailbox

    可以通过把.Net类注册成COM+组件的方式来操作PowerShell。

    这里需要注意的是, 当你的调试环境和exchange服务器环境不一样时(比如调试环境是win7 64,exchange服务器是winserver2008 64),将编译的64位dll放在web项目里会报错,此时你可以忽略这个错误,只有放到exchange服务器后才会成功,所以最好调试环境和exchange服务器一致。

     转==============================================================================

    我的流程就是

    WebService->.NET写的PowerShell操作类注册成的COM+组件->ExChange

    环境是:

    VS2010 + ExChange2010 + Windows Server 2008 64位版 + IIS7.0 

    ps:这个COM+组件只能运行在安装ExChange的服务器上

    公司的环境用的是ExChange2010, ExChange2010好像只有64位版的 只能安装在64位的系统上

    所以下面会说到把COM+组件编译成64位的问题

    ==============================================================================

    1 首先先创建com组件并注册

    1)启动Visual Studio 2010

    2)选择File ->“新建->”项目...

    3)选择Windows

    4)选择“类库”

    5)在名称框中键入“PowerShellComponent “

    6)点击确定。

    7)添加下列引用

    System.EnterpriseServices

    System.DirectoryServices

    System.Management.Automation 路径:

    32位系统:

    C:ProgramFilesReferenceAssembliesMicrosoftWindowsPowerShell 1.System.Management.Automation.dll

    64位系统

    C:Program Files (x86)Reference AssembliesMicrosoftWindowsPowerShell 1.0System.Management.Automation.dll

    接下来有关程序集的操作

    1)在解决方案资源管理器,右键单击PowerShellComponent项目,选择属性,点击签名选项,选中'为程序集签名',并创建一个新的强名称密钥称为“PowerShellComponent.snk” , 不用设置密码。如下图

    2)还是在项目属性窗口中,选择'应用程序'选项卡,然后点击“程序集信息...”,检查框,选中'使程序集COM可见'。如图

    PS:如果运行这个com组件的机器是64位系统(32位的没试过),这里需要再加一步:

    把项目的运行平台设置成64位的

    还是在项目属性窗口中:

    '生成'选项卡->目标平台->64位

     

        ->   

    3)打开AssemblyInfo.cs中,并添加“using System.EnterpriseServices;”,并添加

    [assembly: ApplicationActivation(ActivationOption.Server)] 
    [assembly: ApplicationName('PowerShellComponent')] 
    [assembly: Description('Simple PowerShell Component Sample')] 
    [assembly: ApplicationAccessControl( 
               false, 
               AccessChecksLevel = AccessChecksLevelOption.Application, 
               Authentication = AuthenticationOption.None, 
               ImpersonationLevel = ImpersonationLevelOption.Identify)]

    然后添加ManagementCommands类...

    1)选择“解决方案资源管理器”查看选项卡。将Class1.cs文件重命名为“ManagementCommands.cs”。

    类需要继承System.EnterpriseServices.ServicedComponent,否则不能被编译成COM+组件

    2)添加引用如图并using

    using System.EnterpriseServices;
    using System.Security;
    using System.Security.Principal;
    using System.Runtime.InteropServices;
    using System.Collections.ObjectModel;
    using System.Management.Automation;
    using System.Management.Automation.Host;
    using System.Management.Automation.Runspaces;
    using System.DirectoryServices;
    using Microsoft.PowerShell.Commands;
    using System.Collections;

    3)拷贝下面的方法到类中


    #region 根据登录名判断是否存在邮箱
    
            public bool IsExistMailBox(string identity)
    
            {
    
                try
    
                {
    
                    PSSnapInException PSException = null;
    
                    RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create();
    
                    runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.E2010', out PSException);
    
                    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf);
    
                    runspace.Open();
    
    
    
                    Pipeline pipeline = runspace.CreatePipeline();
    
                    Command command = new Command('Get-Mailbox');
    
                    command.Parameters.Add('identity', identity);
    
                    pipeline.Commands.Add(command);
    
                    Collection<PSObject> result = pipeline.Invoke();
    
    
    
                    runspace.Close();
    
    
    
                    return (result != null && result.Count > 0);
    
                }
    
                catch (System.Exception ex)
    
                {
    
                    throw ex;
    
                }
    
            }
    
            #endregion
    
    
    
            #region 创建邮箱账号
    
            public bool NewMailbox(string name, string accountName, string pwd, string emailDomain, string organizationalUnit, string database)
    
            {
    
                string emailAdd = accountName + emailDomain;
    
    
    
                if (this.IsExistMailBox(emailAdd))
    
                {
    
                    throw new Exception('已经存在同名的邮箱'); 
    
                }
    
                try
    
                {
    
                    PSSnapInException PSException = null;
    
                    RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create();
    
                    runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.E2010', out PSException);
    
                    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf);
    
                    runspace.Open();
    
                    Pipeline pipeline = runspace.CreatePipeline();
    
    
    
                    Command command = new Command('New-Mailbox');
    
                    char[] passwordChars = pwd.ToCharArray();
    
                    SecureString password = new SecureString();
    
                    foreach (char c in passwordChars)
    
                    {
    
                        password.AppendChar(c);
    
                    }
    
    
    
                    command.Parameters.Add('Name', name);//姓名 
    
    
    
                    command.Parameters.Add('UserPrincipalName', emailAdd);//邮箱地址
    
                    command.Parameters.Add('SamAccountName', accountName);//登录名
    
    
    
                    command.Parameters.Add('Password', password);//密码
    
    
    
                    command.Parameters.Add('OrganizationalUnit', organizationalUnit);//组织单元
    
                    command.Parameters.Add('Database', database);//数据库 
    
    
    
                    pipeline.Commands.Add(command);
    
                    Collection<PSObject> result = pipeline.Invoke();
    
                    runspace.Close();
    
    
    
                    return this.IsExistMailBox(emailAdd);
    
                }
    
                catch (Exception ex)
    
                {
    
                    throw ex;
    
                }
    
            }
    
            #endregion
    
    
    
            #region 删除邮箱账号(控制台和域都删除)
    
    
    
            public bool RemoveMailbox(string identity)
    
            {
    
    
    
                try
    
                {
    
                    PSSnapInException PSException = null;
    
                    RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create();
    
                    runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.E2010', out PSException);
    
                    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf);
    
                    runspace.Open();
    
                    Pipeline pipeline = runspace.CreatePipeline();
    
    
    
                    Command command = new Command('Remove-Mailbox');
    
                    command.Parameters.Add('Identity', identity);
    
                    command.Parameters.Add('Confirm', false);
    
                    pipeline.Commands.Add(command);
    
                    Collection<PSObject> result = pipeline.Invoke();
    
                    runspace.Close();
    
    
    
                    return !this.IsExistMailBox(identity);
    
                }
    
                catch (System.Exception ex)
    
                {
    
                    throw ex;
    
                }
    
            }
    
            #endregion
    
    
    
            #region 启用邮箱账号
    
            public bool EnableMailbox(string identity)
    
            {
    
                try
    
                {
    
                    PSSnapInException PSException = null;
    
                    RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create();
    
                    runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.E2010', out PSException);
    
                    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf);
    
                    runspace.Open();
    
                    Pipeline pipeline = runspace.CreatePipeline();
    
    
    
                    Command command = new Command('Enable-Mailbox');
    
                    command.Parameters.Add('Identity', identity);
    
                    command.Parameters.Add('Confirm', false);
    
                    pipeline.Commands.Add(command);
    
                    Collection<PSObject> result = pipeline.Invoke();
    
                    runspace.Close();
    
                    return this.IsExistMailBox(identity);
    
                }
    
                catch (Exception ex)
    
                {
    
                    throw ex;
    
                }
    
            }
    
            #endregion
    
    
    
            #region 禁用邮箱账号
    
            public bool DisableMailbox(string identity)
    
            {
    
                try
    
                {
    
                    PSSnapInException PSException = null;
    
                    RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create();
    
                    runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.E2010', out PSException);
    
                    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf);
    
                    runspace.Open();
    
    
    
                    Pipeline pipeline = runspace.CreatePipeline();
    
                    Command command = new Command('Disable-Mailbox');
    
                    command.Parameters.Add('Identity', identity);
    
                    command.Parameters.Add('Confirm', false);
    
                    pipeline.Commands.Add(command);
    
                    Collection<PSObject> result = pipeline.Invoke();
    
                    runspace.Close();
    
                    return !this.IsExistMailBox(identity);
    
                }
    
                catch (Exception ex)
    
                {
    
                    throw ex;
    
                }
    
            }
    
            #endregion
    
    
    
            #region 判断是否存在通讯组
    
            public bool IsExistGroup(string identity)
    
            {
    
                try
    
                {
    
                    PSSnapInException PSException = null;
    
                    RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create();
    
                    runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.E2010', out PSException);
    
                    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf);
    
                    runspace.Open();
    
    
    
                    Pipeline pipeline = runspace.CreatePipeline();
    
                    Command command = new Command('Get-DistributionGroup');
    
                    command.Parameters.Add('identity', identity);
    
                    pipeline.Commands.Add(command);
    
                    Collection<PSObject> result = pipeline.Invoke();
    
    
    
                    runspace.Close();
    
    
    
                    return (result != null && result.Count > 0);
    
                }
    
                catch (System.Exception ex)
    
                {
    
                    throw ex;
    
                }
    
            }
    
            #endregion
    
    
    
            #region 创建通讯组
    
            public bool NewGroup(string name)
    
            {
    
                if (this.IsExistGroup(name))
    
                {
    
                    throw new Exception('已经存在相同的通讯组'); 
    
                }
    
                try
    
                {
    
                    PSSnapInException PSException = null;
    
                    RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create();
    
                    runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.E2010', out PSException);
    
                    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf);
    
                    runspace.Open();
    
    
    
                    Pipeline pipeline = runspace.CreatePipeline();
    
                    Command command = new Command('New-DistributionGroup');
    
                    command.Parameters.Add('Name', name);
    
                    pipeline.Commands.Add(command);
    
                    Collection<PSObject> result = pipeline.Invoke();
    
                    runspace.Close(); 
    
                    return this.IsExistGroup(name);
    
                }
    
                catch (Exception ex)
    
                {
    
                    throw ex;
    
                }
    
            }
    
    
    
            #endregion
    
    
    
            #region 删除通讯组
    
            public bool RemoveGroup(string identity)
    
            {
    
                try
    
                {
    
                    PSSnapInException PSException = null;
    
                    RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create();
    
                    runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.E2010', out PSException);
    
                    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf);
    
                    runspace.Open();
    
    
    
                    Pipeline pipeline = runspace.CreatePipeline();
    
                    Command command = new Command('Remove-DistributionGroup');
    
                    command.Parameters.Add('Identity', identity);
    
                    command.Parameters.Add('Confirm', false);
    
                    pipeline.Commands.Add(command);
    
                    Collection<PSObject> result = pipeline.Invoke();
    
                    runspace.Close();
    
                    return !this.IsExistGroup(identity); 
    
                }
    
                catch (Exception ex)
    
                {
    
                    throw ex;
    
                } 
    
            }
    
            #endregion
    
    
    
            #region 添加通讯组成员
    
            public bool AddGroupMember(string groupIdentity, string mailIdentity)
    
            {
    
                try
    
                {
    
                    PSSnapInException PSException = null;
    
                    RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create();
    
                    runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.E2010', out PSException);
    
                    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf);
    
                    runspace.Open();
    
    
    
                    Pipeline pipeline = runspace.CreatePipeline();
    
                    Command command = new Command('Add-DistributionGroupMember');
    
                    command.Parameters.Add('Identity', groupIdentity);
    
                    command.Parameters.Add('Member', mailIdentity);
    
                    pipeline.Commands.Add(command);
    
                    Collection<PSObject> result = pipeline.Invoke();
    
                    runspace.Close();
    
                    return true;
    
                }
    
                catch (Exception ex)
    
                {
    
                    throw ex;
    
                }
    
            }
    
            #endregion
    
             
    
            #region 删除通讯组成员
    
            public bool RemoveGroupMember(string groupIdentity, string mailIdentity)
    
            {
    
                try
    
                {
    
                    PSSnapInException PSException = null;
    
                    RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create();
    
                    runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.E2010', out PSException);
    
                    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf);
    
                    runspace.Open();
    
    
    
                    Pipeline pipeline = runspace.CreatePipeline();
    
                    Command command = new Command('Remove-DistributionGroupMember');
    
                    command.Parameters.Add('Identity', groupIdentity);
    
                    command.Parameters.Add('Member', mailIdentity);
    
                    command.Parameters.Add('Confirm', false);
    
                    pipeline.Commands.Add(command);
    
                    Collection<PSObject> result = pipeline.Invoke();
    
                    runspace.Close();
    
                    return true;
    
                }
    
                catch (Exception ex)
    
                {
    
                    throw ex;
    
                }
    
            }
    
            #endregion

    PS: 这些都是ExChange的命令,暂时只封装了这么多,如果想实现更多的功能,只需要照着上面的例子把实现相应的ExChange命令就行了

    在微软的官网上有ExChange的命令文档 http://msdn.microsoft.com/zh-cn/library/aa997174.aspx

    最后运行生成项目,得到PowerShellComponent.dll,COM组件就创建好了。

    接下来就是注册这个组件了:  

    步骤一:
    【控制面板】→【管理工具】→【组件服务】

     

     步骤二:
    出现窗口后,【组件服务】→【计算机】→【我的电脑】→【COM+ 应用程序】单击右键 →新建→ 应用程序→安装向导下一步→创建空应用程序→输入空应用程序名称:PowerShellComponent,并选择激活类型为服务器应用程序→设置应用程序标示(账号选择下列用户 账号和密码是该服务器登录用户名和密码)→完成。

    右键单击创建出来的PowerShellComoponent,选择属性,找到'标志'选项卡,选择 ”下列用户“ 填入计算机的登录用户名和密码,确定 

     步骤三:
    创建好应用程序后 打开PowerShellComponent 出现 【组件】【旧版组件】【角色】 在【组件】上单击右键  →新建→组件


     步骤三:
    点下一步,出现如下窗口,选择【安装新组件】:



    选择前面项目生成的PowerShellComponent.dll文件→【打开】点下一步,选择完成。

     步骤四:

    为刚刚注册的PowerShellComponent组件添加用户权限

    打开PowerShellComponent 下面的【角色】-【CreatorOwner】-【用户】右键  【新建】 - 【用户】

     

    在出来的窗口点[高级]-[位置]-选择[整个目录]-[立即查找]

    因为WebServicce是发布在IIS上面的 所以我的IIS需要有权限来操作这个COM组件 所以我添加的是IIS的用户

    在搜索出来的结果里面 选择IIS_IUSRS并添加,  如果是用winform来调用这个COM+组件 则应该要添加管理员帐号Administrator

     

    用户添加完了  组件就注册成功了。

    把PowerShellComponent.dll拷到测试项目中 

    测试项目添加对 PowerShellComponent.dll 的引用   就能被调用了

      

    如果你的COM+组件被启用了 在调试过程中如果你需要重新编译你的DLL文件 那么需要先关闭COM+组件  dll才能被重新编译

     

    如果在调用的过程中发生异常,可能是两个方面的原因:

    1  如果com+组件在64位的环境下运行 是否有被编译成64位

    2 权限问题

    还有一个 

    因为操作的是ExChange2010  所以代码中是

    PSSnapInInfo info = runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.E2010', out PSException);


     

    如果你的ExChange是2007的  那么这行代码可能需要被改成

     
    PSSnapInInfo info = runspaceConf.AddPSSnapIn('Microsoft.Exchange.Management.PowerShell.Admin', out PSException);

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规