none
.Net中调用PowerShell RRS feed

  • 问题

  • RT,

    使用C#调用PowerShell来访问MailboxDatabase的Mouted属性。

    但是得到的对象和PowerShell中对象有出入,在PowerShell中可以访问其Mouted属性,但是在.NET中得到的对象为null。

    注意,两种方式都是使用了PSSession的,也就是在同一台机子上访问了Exchange服务器。

    为什么会出现这种不同呢?


    On Learning Csharp.

    这里详细说明下:

    是这样的,前段时间我用PowerShell写了一个脚本来轮询Exchange数据库的状态,在数据库dismount的时候给指定的邮箱发一封邮件提醒。脚本运行的还行,只不过有一些不方便,因为每次执行都要提供凭证,虽然可以加密密码然后序列化,但总有点不安全;而且运行的时候会有窗口。
    所以这几天趁项目空挡,我想把这个功能写成一个服务(Windows Service)。这么做的话,就要用C#调用PowerShell。我分几步测试过,发现这个想法可行。但是在一个细节上出了点问题:
     
    主要和Exchange的一个指令有关,Get-Mailboxdatabase
    [-Status]。这个cmdlet命令会返回一个集合,包含所有的Exchange数据库信息,可选参数指示,如果指定了这个参数,则返回额外的信息,其中就包含有Mouted属性。问题是,我在PowerShell中调用这个的时候,返回的Mouted属性是有值的(true或false),但是在.net中调用的时候,尽管我已经指定了-Status(我是通过[Command]
    command.Parameters.Add(string
    name)方法指定的,因为这个参数不需要指定值),返回的Mouted属性始终为null。另外,其他几个应该返回值得属性也没有返回值。
    2012年10月19日 7:35

答案

  • OK,看来坚持是会得到回报的。今天我把代码在本机和服务器上都部署了一份,发现服务器上的代码竟然返回结果!然后我检查了服务器上的程序集,发现System.Management.Automation.dll竟然是在v3.0目录下的。然后我讲这个文件拷贝了一份在本机上引用,结果一切工作正常了!

    嗯,这是个漫长而无聊的故事。


    On Learning Csharp.

    2012年10月25日 10:28

全部回复

  • 给一个思路

    如果只是监控数据库是否dismount,能否直接通过程序连接数据库,然后检查数据库状态呢?

    这样你只需要一个sql就能得到结果,剩下的事情就简单了。

    另外,给你一个demo,调用命令的,你参考一下。

     System.Diagnostics.Process proc = new System.Diagnostics.Process();
                proc.StartInfo.FileName = "net";
                proc.StartInfo.Arguments = "stop " + serviceName;

                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.RedirectStandardOutput = true;

                proc.Start();
                Console.WriteLine(proc.StandardOutput.ReadToEnd());
                proc.WaitForExit();


    family as water

    2012年10月22日 7:42
  • 谢谢你的回复。

    但是,对我而言,这个的意义并不局限于判断一个数据库是不是正常,而是——PowerShell和.NET是不是无缝的。

    到目前为止,我使用了两种方式来通过.net调用PowerShell。除了使用远程指令(PSSession)外,我还通过将程序集编译成COM+,然后注册为COM+组件来完成任务。通过这种方式,就可以完成Exchange的管理工作,比如通过一个WEB APP 添加/删除/修改/查询用户。配合Exchange的一些工作方式,可以完成简单的负载均衡检测,并绘制相对不错的报表等等...这使得我觉得这些内容很有趣。PowerShell监控Exchange的内容,参照网友博客:http://msroger.blog.51cto.com/3571749/806362#comment,我现在只是想用.net来调用,那样对数据的处理会更方便。

    我刚刚测试了COM+的方式,发现可以返回结果。然而使用这种方式有点问题,COM+进程在不被调用的时候会自动关闭,然后再被调用的时候又启动(我不知为何)。另外,COM+组件必须被部署在装有Exchange软件的服务器上。而使用PSSession就灵活很多,而且可以省去COM+这个环节,所以显得干净很多。所以我很希望有人能帮我解决“Get-Mailboxdtabase”这个具体的cmdlet指令的问题,因为在后面的进行中,可能会碰到很多这种“指定参数才返回额外信息”的cmdlet。而且,如果能够顺利解决这个问题,我就不需要考虑维护两种方式。

    其实我也考虑过,是不是由于序列化的问题。既然是远程执行指令,那么久传输的数据必然是序列化的。由于调用这个远程指令的机器上没有相应类型的信息,或者,由于“这些属性是‘动态’的(指定参数才返回内容这点似乎可以说明。)”,所以导致了这个问题。我想继续在装有Exchange的服务器上进行进一步的测试以明确问题的缘由。

    嗯,好像说了很多废话。还是很感谢你的回复。:)


    On Learning Csharp.

    2012年10月22日 8:32
  • OK,看来坚持是会得到回报的。今天我把代码在本机和服务器上都部署了一份,发现服务器上的代码竟然返回结果!然后我检查了服务器上的程序集,发现System.Management.Automation.dll竟然是在v3.0目录下的。然后我讲这个文件拷贝了一份在本机上引用,结果一切工作正常了!

    嗯,这是个漫长而无聊的故事。


    On Learning Csharp.

    2012年10月25日 10:28