.NET通过PowerShell操作ExChange为用户开通邮箱账号
最近工作中一个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:\ProgramFiles\ReferenceAssemblies\Microsoft\WindowsPowerShell\v1.\System.Management.Automation.dll
64位系统
C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.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 > );
}
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 > );
}
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);
.NET通过PowerShell操作ExChange为用户开通邮箱账号的更多相关文章
- .NET通过PowerShell操作ExChange为用户开通邮箱教程
转:http://www.cnblogs.com/gongguo/archive/2012/03/12/2392049.html =================================== ...
- C#使用PowerShell 操作Exchange
先介绍一篇文章来参考一下 点开文章 该文章的最后使用了SSL来保证账户在连接服务器的时候不发生账户认证错误,但是我经过测试发现这个是不可行的,有一种更为简单的方法 首先要对服务器进行winrm设置 就 ...
- 一种读取Exchange的用户未读邮件数方法!
已好几个月没写博客了,由于之前忙于开发基于Sharepoint上的移动OA(AgilePoint)和采用混合移动开发技术开发一个安卓版的企业通讯录APP(数据与lync一致),并于1月初正式上线.马年 ...
- PowerShell管理Exchange
#添加Exchange管理单元get-pssnapin -registeredadd-pssnapin microsoft.exchange* #启用邮箱账号(需要域管理员权限,因为需要将某些属性写入 ...
- 模拟开户接口,使用python脚本实现批量用户开通
1.目的 通过模拟接口方法,实现批量用户开通 2.分析 A.接口含body和head部分,其中body中的某些变量为必填字段,包含用户的信息. B.用户信息清单可以整理成ott_after_check ...
- 模拟开户接口,使用shell脚本实现批量用户开通
1.目的 通过模拟接口方法,实现批量用户开通 2.分析 A.接口含body和head部分,其中body中的某些变量为必填字段,包含用户的信息,接口可整理成body.xml.head.xml文件. B. ...
- jQuery 操作cookie保存用户浏览信息
使用jQuery操作cookie之前需要引入jQuery的一个cookie小组件js,代码如下: /* jQuery cookie plugins */jQuery.cookie ...
- 安全错误使用CORS在IE10与Node和Express及XMLHttpRequest: 网络错误 0x4c7, 操作已被用户取消
在IE下:VUE项目,后台替换为https请求之后,vue热更新请求挂起,控制台报错:XMLHttpRequest: 网络错误 0x4c7, 操作已被用户取消.但是chrome与Firefox正常 当 ...
- loadRunner之参数化,对用户名和密码进行参数化,并打印输出---实际操作:用户登录的账号用随机值来登录
录制脚本,对用户名和密码进行参数化: Action() { web_url("WebTours", "URL=http://127.0.0.1:1080/WebTours ...
随机推荐
- [LeetCode]题解(python):134-Gas Station
题目来源: https://leetcode.com/problems/gas-station/ 题意分析: 在一个圈子路线里面有N个汽油站,i站的汽油有gas[i]汽油.现在有一辆无限容量的车,它从 ...
- Loadrunner11点击录制脚本无响应,IE页面弹不出——解决方案汇总
以前用Loadrunner的时候都没有遇到过这个问题,后来将服务器重装系统(win7)后,重新安装Loadrunner11,浏览器版本刚开始为IE11,后来降为IE8,IE访问部署在虚拟机里的平台能正 ...
- LintCode- 删除排序数组中的重复数字
题目描述: 给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度. 不要使用额外的数组空间,必须在原地没有额外空间的条件下完成. 样例 给出数组A =[1,1 ...
- 转:基于node的web开发框架Express入门
JavaScript 标准参考教程(alpha) 草稿二:Node.js Express框架 GitHub TOP Express框架 来自<JavaScript 标准参考教程(alpha)&g ...
- mrtg监控网络流量简单配置
Mrtg服务器搭建(监控网络流量) [日期:2012-07-03] 来源:Linux社区 作者:split_two [字体:大 中 小] [实验环境] 监控机:Red Hat linux 5.3 ...
- Oracle 快照及 dblink使用 (两台服务器数据同步)
/*一.创建dblink:*/ --1.在目的数据库上,创建dblin drop database link dblink_anson; Create public database link dbl ...
- CSS3阴影 box-shadow的使用和技巧总结[转]
text-shadow是给文本添加阴影效果,box-shadow是给元素块添加周边阴影效果.随着html5和CSS3的普及,这一特殊效果使用越来越普遍. 基本语法是{box-shadow:[inset ...
- wpf全局异常
在App.xaml文件中 添加DispatcherUnhandledExceptionEventArgs 新增对应事件
- 比赛F-F Perpetuum Mobile
比赛F-F Perpetuum Mobile 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=86640#problem/ ...
- ThinkPHP第八天(U函数放置在外部JS不会被解析,错误界面定制,错误信息变量)
1.JS外部文件中U函数不会被解析,内部JS代码可以被解析. 2.halt. _404可以定制错误模板,在配置文件中配置 TMPL_EXCEPTION_FILE =>'./Public/Tpl/ ...