如何使用Exchange Powershell从C#中的Cmdlet读取详细输出

时间:2010-12-20 01:53:52

标签: c# powershell exchange-server

环境:Exchange 2007 sp3(2003 sp2混合模式)

Visual Studio 2008,.Net 3.5


我正在使用Exchange PowerShell移动邮箱cmdlet并注意到当我从Exchange管理外壳执行此操作时(使用详细开关),提供了大量实时信息。

为了提供一些上下文,我正在尝试创建一个UI应用程序,它类似于Exchange管理控制台移动邮箱,但希望支持每个条目(和线程)的输入文件和特定服务器/数据库目标。

这大致是我现在的情况,但我不确定是否有需要注册的事件或者是什么......而且要清楚,我希望能够实时获取这些信息,以便我可以更新我的UI反映适当用户的移动顺序中发生的事情(非常类似于管理控制台中提供的本机功能)。如果你想知道,我不满足于管理控制台功能的原因是,我有一个算法,我用它来平衡用户,具体取决于存储限制,黑莓使用,日记,异常邮箱大小等要求用户被映射到特定位置...并且我不希望为每个公共目标创建多个/多个移动组,或者通过管理控制台UI单独搜索用户列表。

我似乎无法找到任何好的文档或示例,说明如何使用C#阅读控制台中提供的详细消息(我看到能够在许多不同场景中读取此类信息的价值)。

我已经探索了Invoke和InvokeAsync方法以及StateChanged& DataReady事件,但这些事件似乎都没有提供我所追求的信息(详细评论)。

非常感谢任何可以提供的方向或示例!

一个代码示例,它比我通常调用任何其他powershell命令的代码更多:

// config to use ExMgmt shell, create runspace and open it
RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();

PSSnapInException snapInException = null;
PSSnapInInfo info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", out snapInException);

if (snapInException != null) throw snapInException;

Runspace runspace = RunspaceFactory.CreateRunspace(rsConfig);

try
{
  runspace.Open();

  // create a pipeline and feed script text
  Pipeline pipeline = runspace.CreatePipeline();

  string targetDatabase = @"myServer\myStorageGroup\myDB";
  string mbxOwner = "user@company.com";

  Command myMoveMailbox = new Command("Move-Mailbox", false, false);
  myMoveMailbox.Parameters.Add("Identity", mbxOwner);
  myMoveMailbox.Parameters.Add("TargetDatabase", targetDatabase);
  myMoveMailbox.Parameters.Add("Verbose");
  myMoveMailbox.Parameters.Add("ValidateOnly");
  myMoveMailbox.Parameters.Add("Confirm", false);
  pipeline.Commands.Add(myMoveMailbox);

  System.Collections.ObjectModel.Collection<PSObject> output = null;

  // these next few lines that are commented out are where I've tried
  // registering for events and calling asynchronously but this doesn't 
  // seem to get me anywhere closer
  //
  //pipeline.StateChanged += new EventHandler<PipelineStateEventArgs>(pipeline_StateChanged);
  //pipeline.Output.DataReady += new EventHandler(Output_DataReady);
  //pipeline.InvokeAsync();
  //pipeline.Input.Close();
  //return; tried these variations that are commented out but none seem to be useful

  output = pipeline.Invoke();

  // Check for errors in the pipeline and throw an exception if necessary
  if (pipeline.Error != null && pipeline.Error.Count > 0)
  {
     StringBuilder pipelineError = new StringBuilder();
     pipelineError.AppendFormat("Error calling Test() Cmdlet.  ");
     foreach (object item in pipeline.Error.ReadToEnd())
       pipelineError.AppendFormat("{0}\n", item.ToString());

     throw new Exception(pipelineError.ToString());
   }

   foreach (PSObject psObject in output)
   {
     // blah, blah, blah
     // this is normally where I would read details about a particular PS command
     // but really pertains to a command once it finishes and has nothing to do with
     // the verbose messages that I'm after... since this part of the methods pertains
     // to the after-effects of a command having run, I'm suspecting I need to look to
     // the asynch invoke method but am not certain or knowing how.
   }
}
finally
{
  runspace.Close();
}

2 个答案:

答案 0 :(得分:2)

看一下PowerShell课程。它具有Streams属性,允许您访问Verbose流的内容。请注意,PowerShell类是在PowerShell 2.0中引入的,但可能是您在托管应用程序中嵌入PowerShell时要使用的类。事实上,文档说:

  

提供用于的方法   创建一个命令和管道   也可以调用这些命令   内部同步或异步   一个运行空间。这门课也提供   访问输出流   包含生成时的数据   命令被调用。 这堂课   主要用于主机   以编程方式使用的应用程序   Windows PowerShell执行任务。   此类是在Windows中引入的   PowerShell 2.0。

答案 1 :(得分:0)

我已经在网站上创建了一个帐户,所以我可以进行互动......我就是那个提出这个问题的人。

非常感谢您提供的信息和链接。正如您已经指出的那样,我注意到我必须升级到PS 2.0才能“看到”这个Powershell类(由于某种原因,它已经证明了一些苦差事。)

现在我明白将PS类与streams属性一起使用,我希望我能够像以前那样添加类似于以前的Exchange管理单元,我应该在路上。< / p>

感谢您指出我正确的方向,这似乎正是我所需要的!

此致 基思