转:http://www.cnblogs.com/gongguo/archive/2012/03/12/2392049.html
==============================================================================
要使.NET调用PowerShell组建能够管理Exchange必须在调用的时候加载管理模块,否则和Exchange相关的指令就不被支持。虽然并不是很明白这两种加载模块方式的具体区别,但是由于手动加载Exchange管理模块有两种方式,.NET(或者直接说C#)管理Exchange就有2种方式。第一种方式是将代码编译成COM+组建,注册到COM+应用程序中,以供客户机代码调用,第二种方式不需要注册COM+组建,更大程度得益于“远程管理”,第二种的调用方式五花八门,详情可以参考Exchange小组的技术博客
1.COM+:要求部署在Exchange服务器上(因为有PowerShell Modules),一般选用CAS服务器。另外COM+应用程序在没有使用的情况下会自动关闭,一有请求又开启,所以第一次调用会显得有点慢。
2.远程调用。主要是要基于Kerberos的身份验证,使用SSL加密模式也可以,但是就要配置证书,所以目前我使用的都是Kerberos模式的身份验证。可以在同一个AD上部署,或者在建立了信任关系的其他AD中部署。相比第一种来说灵活(差别不大),也干净一点。但是我尚未测试使用WEB调用的情况,所以有没有其他问题尚未明确。
主要原理是:(这个原理是我猜的,因为我也不太懂ExChange以及COM组件这方面的知识)
直接用C#代码访问ExChange是不行的
微软出了一个PowerShell的命令行工具 能够用命令行来操作ExChange
可以通过把.Net类注册成COM+组件的方式来操作PowerShell
所以我的流程就是
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)拷贝下面的方法到类中
1 #region 根据登录名判断是否存在邮箱 2 3 public bool IsExistMailBox(string identity) 4 5 { 6 7 try 8 9 { 10 11 PSSnapInException PSException = null; 12 13 RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create(); 14 15 runspaceConf.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out PSException); 16 17 Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf); 18 19 runspace.Open(); 20 21 22 23 Pipeline pipeline = runspace.CreatePipeline(); 24 25 Command command = new Command("Get-Mailbox"); 26 27 command.Parameters.Add("identity", identity); 28 29 pipeline.Commands.Add(command); 30 31 Collection<PSObject> result = pipeline.Invoke(); 32 33 34 35 runspace.Close(); 36 37 38 39 return (result != null && result.Count > 0); 40 41 } 42 43 catch (System.Exception ex) 44 45 { 46 47 throw ex; 48 49 } 50 51 } 52 53 #endregion 54 55 56 57 #region 创建邮箱账号 58 59 public bool NewMailbox(string name, string accountName, string pwd, string emailDomain, string organizationalUnit, string database) 60 61 { 62 63 string emailAdd = accountName + emailDomain; 64 65 66 67 if (this.IsExistMailBox(emailAdd)) 68 69 { 70 71 throw new Exception("已经存在同名的邮箱"); 72 73 } 74 75 try 76 77 { 78 79 PSSnapInException PSException = null; 80 81 RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create(); 82 83 runspaceConf.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out PSException); 84 85 Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf); 86 87 runspace.Open(); 88 89 Pipeline pipeline = runspace.CreatePipeline(); 90 91 92 93 Command command = new Command("New-Mailbox"); 94 95 char[] passwordChars = pwd.ToCharArray(); 96 97 SecureString password = new SecureString(); 98 99 foreach (char c in passwordChars) 100 101 { 102 103 password.AppendChar(c); 104 105 } 106 107 108 109 command.Parameters.Add("Name", name);//姓名 110 111 112 113 command.Parameters.Add("UserPrincipalName", emailAdd);//邮箱地址 114 115 command.Parameters.Add("SamAccountName", accountName);//登录名 116 117 118 119 command.Parameters.Add("Password", password);//密码 120 121 122 123 command.Parameters.Add("OrganizationalUnit", organizationalUnit);//组织单元 124 125 command.Parameters.Add("Database", database);//数据库 126 127 128 129 pipeline.Commands.Add(command); 130 131 Collection<PSObject> result = pipeline.Invoke(); 132 133 runspace.Close(); 134 135 136 137 return this.IsExistMailBox(emailAdd); 138 139 } 140 141 catch (Exception ex) 142 143 { 144 145 throw ex; 146 147 } 148 149 } 150 151 #endregion 152 153 154 155 #region 删除邮箱账号(控制台和域都删除) 156 157 158 159 public bool RemoveMailbox(string identity) 160 161 { 162 163 164 165 try 166 167 { 168 169 PSSnapInException PSException = null; 170 171 RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create(); 172 173 runspaceConf.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out PSException); 174 175 Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf); 176 177 runspace.Open(); 178 179 Pipeline pipeline = runspace.CreatePipeline(); 180 181 182 183 Command command = new Command("Remove-Mailbox"); 184 185 command.Parameters.Add("Identity", identity); 186 187 command.Parameters.Add("Confirm", false); 188 189 pipeline.Commands.Add(command); 190 191 Collection<PSObject> result = pipeline.Invoke(); 192 193 runspace.Close(); 194 195 196 197 return !this.IsExistMailBox(identity); 198 199 } 200 201 catch (System.Exception ex) 202 203 { 204 205 throw ex; 206 207 } 208 209 } 210 211 #endregion 212 213 214 215 #region 启用邮箱账号 216 217 public bool EnableMailbox(string identity) 218 219 { 220 221 try 222 223 { 224 225 PSSnapInException PSException = null; 226 227 RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create(); 228 229 runspaceConf.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out PSException); 230 231 Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf); 232 233 runspace.Open(); 234 235 Pipeline pipeline = runspace.CreatePipeline(); 236 237 238 239 Command command = new Command("Enable-Mailbox"); 240 241 command.Parameters.Add("Identity", identity); 242 243 command.Parameters.Add("Confirm", false); 244 245 pipeline.Commands.Add(command); 246 247 Collection<PSObject> result = pipeline.Invoke(); 248 249 runspace.Close(); 250 251 return this.IsExistMailBox(identity); 252 253 } 254 255 catch (Exception ex) 256 257 { 258 259 throw ex; 260 261 } 262 263 } 264 265 #endregion 266 267 268 269 #region 禁用邮箱账号 270 271 public bool DisableMailbox(string identity) 272 273 { 274 275 try 276 277 { 278 279 PSSnapInException PSException = null; 280 281 RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create(); 282 283 runspaceConf.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out PSException); 284 285 Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf); 286 287 runspace.Open(); 288 289 290 291 Pipeline pipeline = runspace.CreatePipeline(); 292 293 Command command = new Command("Disable-Mailbox"); 294 295 command.Parameters.Add("Identity", identity); 296 297 command.Parameters.Add("Confirm", false); 298 299 pipeline.Commands.Add(command); 300 301 Collection<PSObject> result = pipeline.Invoke(); 302 303 runspace.Close(); 304 305 return !this.IsExistMailBox(identity); 306 307 } 308 309 catch (Exception ex) 310 311 { 312 313 throw ex; 314 315 } 316 317 } 318 319 #endregion 320 321 322 323 #region 判断是否存在通讯组 324 325 public bool IsExistGroup(string identity) 326 327 { 328 329 try 330 331 { 332 333 PSSnapInException PSException = null; 334 335 RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create(); 336 337 runspaceConf.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out PSException); 338 339 Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf); 340 341 runspace.Open(); 342 343 344 345 Pipeline pipeline = runspace.CreatePipeline(); 346 347 Command command = new Command("Get-DistributionGroup"); 348 349 command.Parameters.Add("identity", identity); 350 351 pipeline.Commands.Add(command); 352 353 Collection<PSObject> result = pipeline.Invoke(); 354 355 356 357 runspace.Close(); 358 359 360 361 return (result != null && result.Count > 0); 362 363 } 364 365 catch (System.Exception ex) 366 367 { 368 369 throw ex; 370 371 } 372 373 } 374 375 #endregion 376 377 378 379 #region 创建通讯组 380 381 public bool NewGroup(string name) 382 383 { 384 385 if (this.IsExistGroup(name)) 386 387 { 388 389 throw new Exception("已经存在相同的通讯组"); 390 391 } 392 393 try 394 395 { 396 397 PSSnapInException PSException = null; 398 399 RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create(); 400 401 runspaceConf.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out PSException); 402 403 Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf); 404 405 runspace.Open(); 406 407 408 409 Pipeline pipeline = runspace.CreatePipeline(); 410 411 Command command = new Command("New-DistributionGroup"); 412 413 command.Parameters.Add("Name", name); 414 415 pipeline.Commands.Add(command); 416 417 Collection<PSObject> result = pipeline.Invoke(); 418 419 runspace.Close(); 420 421 return this.IsExistGroup(name); 422 423 } 424 425 catch (Exception ex) 426 427 { 428 429 throw ex; 430 431 } 432 433 } 434 435 436 437 #endregion 438 439 440 441 #region 删除通讯组 442 443 public bool RemoveGroup(string identity) 444 445 { 446 447 try 448 449 { 450 451 PSSnapInException PSException = null; 452 453 RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create(); 454 455 runspaceConf.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out PSException); 456 457 Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf); 458 459 runspace.Open(); 460 461 462 463 Pipeline pipeline = runspace.CreatePipeline(); 464 465 Command command = new Command("Remove-DistributionGroup"); 466 467 command.Parameters.Add("Identity", identity); 468 469 command.Parameters.Add("Confirm", false); 470 471 pipeline.Commands.Add(command); 472 473 Collection<PSObject> result = pipeline.Invoke(); 474 475 runspace.Close(); 476 477 return !this.IsExistGroup(identity); 478 479 } 480 481 catch (Exception ex) 482 483 { 484 485 throw ex; 486 487 } 488 489 } 490 491 #endregion 492 493 494 495 #region 添加通讯组成员 496 497 public bool AddGroupMember(string groupIdentity, string mailIdentity) 498 499 { 500 501 try 502 503 { 504 505 PSSnapInException PSException = null; 506 507 RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create(); 508 509 runspaceConf.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out PSException); 510 511 Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf); 512 513 runspace.Open(); 514 515 516 517 Pipeline pipeline = runspace.CreatePipeline(); 518 519 Command command = new Command("Add-DistributionGroupMember"); 520 521 command.Parameters.Add("Identity", groupIdentity); 522 523 command.Parameters.Add("Member", mailIdentity); 524 525 pipeline.Commands.Add(command); 526 527 Collection<PSObject> result = pipeline.Invoke(); 528 529 runspace.Close(); 530 531 return true; 532 533 } 534 535 catch (Exception ex) 536 537 { 538 539 throw ex; 540 541 } 542 543 } 544 545 #endregion 546 547 548 549 #region 删除通讯组成员 550 551 public bool RemoveGroupMember(string groupIdentity, string mailIdentity) 552 553 { 554 555 try 556 557 { 558 559 PSSnapInException PSException = null; 560 561 RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create(); 562 563 runspaceConf.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out PSException); 564 565 Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf); 566 567 runspace.Open(); 568 569 570 571 Pipeline pipeline = runspace.CreatePipeline(); 572 573 Command command = new Command("Remove-DistributionGroupMember"); 574 575 command.Parameters.Add("Identity", groupIdentity); 576 577 command.Parameters.Add("Member", mailIdentity); 578 579 command.Parameters.Add("Confirm", false); 580 581 pipeline.Commands.Add(command); 582 583 Collection<PSObject> result = pipeline.Invoke(); 584 585 runspace.Close(); 586 587 return true; 588 589 } 590 591 catch (Exception ex) 592 593 { 594 595 throw ex; 596 597 } 598 599 } 600 601 #endregion 602 603