繁体   English   中英

将参数从 c# 传递到 powershell 脚本

[英]Passing parameters from c# to powershell script

我创建了一个 powershell 脚本,其中包括:

param($ServerName, $Location)

"Application Name: $ServerName"
"Location: $Location"

当我在 powershell 中运行.\\Params.ps1 ConsoleApp1 Washington, DC ,它将显示:

Application Name: ConsoleApp1
Location: Washington D.C.

所以我知道这很好用。 现在我想把它带到 c# 并执行参数传递。

在我的控制台应用程序中,我创建了以下内容:

    static void Main(string[] args)
    {
        string[] scriptParam = { "ConsoleApp1", "Washington, D.C."};
        string powerShell = PerformScript(scriptParam);
        Console.WriteLine(powerShell);
        Console.WriteLine("\nPowershell script excuted!!");          
        Console.ReadLine();
    }

    static string PerformScript(string scriptParameters)
    {
        InitialSessionState runspaceConfiguration = InitialSessionState.Create();
        Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);

        runspace.Open();

        Pipeline pipeline = runspace.CreatePipeline();
       

        PowerShell ps = PowerShell.Create();
        ps.Runspace = runspace;
        ps.AddCommand(@"C:\Users\users\source\repos\ConsoleApp1\powershell\Params.ps1");

        foreach (string scriptParameter in scriptParameters)
        {
            ps.AddParameter(scriptParameter);
        }

        Collection<PSObject> psObjects = pipeline.Invoke();
        runspace.Close();

        StringBuilder stringBuilder = new();

        foreach (PSObject item in psObjects)
        {
            stringBuilder.AppendLine(item.ToString());
        }

        return stringBuilder.ToString();
    }

但是当我运行程序时,我在线上得到一个Exception Unhandled

Collection<PSObject> psObjects = pipeline.Invoke();

System.Management.Automation.PSInvalidOperationException: '管道不包含命令。'

传递参数时我做错了什么吗?


更新代码:

    static string PerformScript(string[] scriptParameters)
    {
        InitialSessionState runspaceConfiguration = InitialSessionState.Create();
        Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);

        runspace.Open();

        Pipeline pipeline = runspace.CreatePipeline();

        using (var ps = PowerShell.Create())
        {
            var result = ps.AddCommand(@"C:\Users\users\source\repos\ConsoleApp1\powershell\Params.ps1")
              .AddArgument("ConsoleApp1")
              .AddArgument("Washington, D.C.")
              .Invoke();
            foreach (var o in result)
            {
                Console.WriteLine(o);
            }
        }

        Collection<PSObject> psObjects = pipeline.Invoke();
        runspace.Close();

        StringBuilder stringBuilder = new();

        foreach (PSObject item in psObjects)
        {
            stringBuilder.AppendLine(item.ToString());
        }

        return stringBuilder.ToString();
    }

使用.AddArgument() ,而不是.AddParameter()

您试图传递的是位置(未命名)参数,即仅仅是其目标参数由它们的位置隐含的参数,这就是.AddArgument()的用途。

相比之下, .AddParameter()用于命名参数,您首先指定参数名称,然后是其(参数)。

这是一个简化的示例:

using (var ps = PowerShell.Create()) {
  var result = ps.AddCommand(@"C:\Users\users\source\repos\ConsoleApp1\powershell\Params.ps1")
    .AddArgument("ConsoleApp1")
    .AddArgument("Washington, D.C.")
    .Invoke();
  foreach (var o in result) {
    Console.WriteLine(o);
  }
}

注:以上用途大大简化的API,可直接通过的方法PowerShell实例(与创建.Create()如果自动创建一个默认的会话状态的运行空间就足够了,没有必要进行明确的创建与运行空间RunspaceFactory.CreateRunspace()与会话状态InitialSessionState.Create()以及运行空间与管道.CreatePipeline() -见如何将技术应用到你的代码底部。


至于你尝试什么

如果您错误地仅将.AddParameter()与单个方法参数一起使用,PowerShell SDK 所做的就是将省略的参数默认为true ,因此.AddParameter('foo')相当于传递-foo: $true from在 PowerShell 中。

仅当您传递的参数名称开关参数(类型为System.Management.Automation.SwitchParameter ,PowerShell 代码中的[switch] )时,这才按预期工作。


应用于您的代码:

static void Main(string[] args)
{
    Console.WriteLine(
      PerformScript(
        @"C:\Users\users\source\repos\ConsoleApp1\powershell\Params.ps1", 
        new string[] { "ConsoleApp1", "Washington, D.C." }
      )
    );
}

static string PerformScript(string scriptPath, string[] scriptArguments)
{
  StringBuilder stringBuilder = new();
  using (var ps = PowerShell.Create())
  {
    ps.AddCommand(scriptPath);
    foreach (var arg in scriptArguments)
    {
      ps.AddArgument(arg);
    }
    foreach (var o in ps.Invoke())
    {
      stringBuilder.AppendLine(o.ToString());
    }
  }
  return stringBuilder.ToString();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM