您的位置:首页 > 运维架构 > Shell

用C# 调用PowerShell 3.0

2015-07-12 23:01 681 查看
最近,随着System Center Virtual Machine Management 2012 SP1 的发布,越来越多的人,加入到私有云的开发中来,特别是,开发测试云,但国内的技术文档及资料相当匮乏。前几天,一个外地的同事在问 “怎么用C# 调用PowerShell并且取得返回值”的问题。

解决方案如下:

调用系统的PowerShell,可以用:

/// <summary>
/// invoke system powershell
/// </summary>
/// <param name="cmd"></param>
public static void InvokeSystemPS(string cmd)
{
List<string> ps = new List<string>();
ps.Add("Set-ExecutionPolicy RemoteSigned");
ps.Add("Set-ExecutionPolicy -ExecutionPolicy Unrestricted");
ps.Add("& " + cmd);
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
foreach (var scr in ps)
{
pipeline.Commands.AddScript(scr);
}
pipeline.Invoke();//Execute the ps script
runspace.Close();
}


  2.调用VMM产品,这里以“Get-VM -Name vm001” 为例:

/// <summary>
/// Invoke VMM Poershell
/// </summary>
public static void InvokeVMMPS()
{
RunspaceConfiguration rconfig = RunspaceConfiguration.Create();
PSSnapInException Pwarn = new PSSnapInException();

Runspace runspace = RunspaceFactory.CreateRunspace();
string test = "Import-Module VirtualMachineManager\r\n";
runspace = RunspaceFactory.CreateRunspace(rconfig); runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(test);
try {
var results = pipeline.Invoke();

using (Pipeline pipe = runspace.CreatePipeline())
{
//Get-VM -Name vm001
Command cmd = new Command("Get-VM");
cmd.Parameters.Add("Name", "vm001");
pipe.Commands.Add(cmd);
var result = pipe.Invoke();
}
}
catch (Exception ex)
{
throw ex;
}
}


Firstly, you need to add reference "System.Management.Automation". Then, add two name space:

using System.Management.Automation.Runspaces;

using System.Management.Automation;

Windows PowserShell能够很简洁 快速通过Script脚本方式获得我们想要执行效果. 如何在C#中任意执行PowerShell脚本.?类似目前我要在做一个进程管理工具. 通过PowerShell脚本方式获取当前系统进程调用的详细信息. C#如何执行Shell Script:

步骤如下:

<1>前提:安装PowerShell SDK.

要在C#执行Power Shell 脚本.需要在PowerShell的SDK添加相关引用. Windows 7系统自动集成Windows PowerShell 2.0版本.如果尚未请点击下载安装

<2>新建Console Application项目 命名:CallPowerShellDemo .添加引用:System.Management.Automation 这个命名空间需要引用PowerShell SDK中System.Management.Automation.dll. 如果已经PowerShell SDK可以在目录:C:\Program Files\Reference
Assemblies\Microsoft\WindowsPowerShell\v1.0
下找到:



添加相关引用:

1:  //导入引入

2:  using System.Management.Automation;

3:  using System.Management.Automation.Runspaces;

4:  using System.Management;

5:  using CallPowerShellDemo.EntityModel;


封装参数实体:

1:   /// <summary>

2:      /// 定义一个封装Shell脚本命令参数实体类

3:      /// Author:chenkai Date:2010年11月9日10:27:55

4:      /// </summary>

5:    public  class ShellParameter

6:      {

7:        public string ShellKey { get; set; }

8:        public string ShellValue { get; set; }

9:      }


执行脚本方法:

+
View Code

Main方法中调用:

+
View Code

执行结果: 获取以Ca作为开头名称系统进程信息 ShellScript :get-process Ca*



则利用PowerShell脚本轻松获取进程名称以Ca开头所有进程名称. 类似我们轻松在获取360在本地系统详细的版本信息: get-process 360* –fileversioninfo



对于C#执行Shell脚本方式. 是通过Runspace类 ,Runspace主要作用是分配一块独立空间,在空间之上建立一个独立为执行Shell命令唯一通信通道,Runspace同时也为创建通道环境参数进行配置.
Runspace主要用来构建对象和配置通信环境相关参数. Shell脚本命令通过管道内的运行空间主机应用程序执行,但RunSpace并没有提供对执行结果输出. 如果需要输出则需要pipeline.类支持

<3>Windows PowerShell 与C#之间交互.

PowerShell对.NET对象是无缝支持的, 在Windows PowerShell脚本编程中也提出面向对象的概念. 对于Shell脚本中对象和C#语言对象是否具有相互可操作性. ?答案是肯定的. 类似我们现在要做一个运算, 运算逻辑定义以及执行则有Shell脚本. 只需在C#中以对象的方式传给Shell脚本中对象相关的参数.值. 自动计算.

先定义一个计算操作对象:

1:      /// <summary>

2:      /// 计算操作的对象

3:      /// Author:chenkai Date:2010年11月9日13:54:49

4:      /// </summary>

5:     public class ConvertPatameter

6:      {

7:         public int FirstNum { get; set; }

8:         public int SecondNum { get; set; }

9:         public int Sum { get; set; }

10:      }


当我们顶一个操作对象. 初始化FirstNum和SecondNum,然后把值传入到Shell脚本中执行加法运算并把结果赋给Sum参数.Shell Script中定义加法执行规则:

1:  $a=$Result.FirstNum

2:  $b=$Result.SecondNum

3:  $Result.Sum=$a+$b

4:


C#调用对象处理Shell脚本执行方法:

1:              try

2:              {

3:                  //zaiShell 执行方法参数

4:               List<string> getlist = new List<string>();

5:                  getlist.Add("Set-ExecutionPolicy RemoteSigned");//先执行启动安全策略,,使系统可以执行powershell脚本文件

6:

7:                  string pspath = System.IO.Path.Combine(Environment.CurrentDirectory, "PSDoc1.ps1");

8:                  getlist.Add(pspath);

9:

10:                  //定义一个操作的实体对象

11:                  ConvertPatameter newconvert = new ConvertPatameter

12:                  {

13:                       FirstNum=200,

14:                       SecondNum=80,

15:                       Sum=0

16:                  };

17:

18:                  if (File.Exists(pspath))

19:                  {

20:                      RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();

21:                      Runspace newspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);

22:

23:                      newspace.Open();

24:                      Pipeline newline = newspace.CreatePipeline();

25:                      RunspaceInvoke scriptInvoker = new RunspaceInvoke(newspace);

28:                      Command getcmd = new Command(pspath);

29:                      newline.Commands.Add(getcmd);

30:

31:                      //注入脚本一个.NEt对象 这样在powershell脚本中就可以直接通过$key访问和操作这个对象

32:                      //newspace.SessionStateProxy.SetVariable(getshellpar.ShellKey,getshellpar.ShellValue);

33:                      newspace.SessionStateProxy.SetVariable("Result", newconvert);

34:

35:                     //执行

36:                     var gettakeres=newline.Invoke();

38:                     foreach (var getstr in gettakeres)

39:                     {

40:                         Console.WriteLine(getstr.ToString());

41:                     }

42:

43:                     Console.WriteLine("计算结果:" + newconvert.FirstNum.ToString() + "加上"

44:                         + newconvert.SecondNum.ToString() + "等于" + newconvert.Sum.ToString());

45:                     Console.WriteLine("对象的值已经修改:"+newconvert.Sum.ToString());

46:                  }

48:

49:              }

50:              catch (Exception se)


执行结果:



当把C#中实体对象ConvertPatameter赋给Shell脚本中对象$Result. 注意核心注册语句:

1:   //注入脚本一个.NEt对象 这样在powershell脚本中就可以直接通过$key访问和操作这个对象

2:   //newspace.SessionStateProxy.SetVariable(getshellpar.ShellKey,getshellpar.ShellValue);

3:   newspace.SessionStateProxy.SetVariable("Result", newconvert);


在脚本注册一个.NET对象并赋给Shell对象$Result,则在ShellScript脚本中利用加法运算 修改原来对象的Sum的属性.并返回给.NET对象中.这是一次关于.NEt对象和Shell Script中对象交互一次简单操作.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: