繁体   English   中英

将参数从C#传递给调用的PowerShell脚本

[英]Passing argument from C# to called PowerShell Script

我在C#文件中有以下功能:

private void RunScriptFile(string scriptPath, string computerName, PSCredential credential)
{
   RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
   Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
   runspace.Open();
   RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
   Pipeline pipeline = runspace.CreatePipeline();
   string scriptCommand = "Invoke-Command -ComputerName " + computerName + " -FilePath " + scriptPath + " -ArgumentList " +  credential;
   pipeline.Commands.AddScript(scriptCommand);
   Collection<PSObject> results = pipeline.Invoke();
   runspace.Close();
}

我使用上面的C#代码中传递的凭据调用以下PowerShell脚本; script.ps1

Param([PSCredential]$Credentials)
<code part using credentials>

pipeline.Invoke() ,C#代码只是在没有任何操作的情况下关闭,也没有抛出任何错误。

打电话时我有什么问题吗? 如果从PowerShell调用如下调用相同的调用工作正常:

Invoke-Command -ComputerName <computerName> -FilePath <scipt.ps1> -ArgumentList " +  credential;

如果你使用带有自包含命令的.AddScript() - 看似是CommandCollection.AddScript()的唯一选项 - 你只能以字符串形式嵌入参数 ,作为你传递的PowerShell代码片段的一部分 - 而且不适用于PSCredential实例。

为了单个命令的上下文中将参数作为特定的.NET类型传递 ,您可以使用带有.AddCommand()AddParameter() / AddArgument()方法的PowerShell实例。

适用于您的场景:

private void RunScriptFile(string scriptPath, string computerName, PSCredential credential) {
  Collection<PSObject> results; 
  using (var ps = PowerShell.Create()) {
    ps.AddCommand("Invoke-Command")
      .AddParameter("ComputerName", computerName)
      .AddParameter("FilePath", scriptPath)
      .AddParameter("ArgumentList", new object[] { credential })
    results = ps.Invoke();
  }
}

这种方法的另一个优点是不需要解析PowerShell代码,这样可以更快,更健壮。

通常, PowerShell类的使用简化了PowerShell SDK的使用,并且在许多情况下已足够(通常不需要明确地管理运行空间,管道,...)。


但是,正如PetSerAl指出的那样, PowerShell.AddScript() 可以接受类型化参数 ,如果您通过param(...)块重新.AddParameter() 声明(类型化)参数的代码片段 ,然后调用.AddParameter() / .AddArgument()

ps.AddScript(@"param([string] $ComputerName, [string] $FilePath, [pscredential] $Credential) Invoke-Command -ComputerName $ComputerName -FilePath $FilePath -ArgumentList $Credential")
  .AddArgument(computerName)
  .AddArgument(scriptPath)
  .AddArgument(credential)

然而,正如您所看到的,这使得解决方案更加冗长。

声明参数会使意图更加明显,但您也可以使用自动的,数组值$args变量来访问以位置方式传递的参数

ps.AddScript(@"Invoke-Command -ComputerName $args[0] -FilePath $args[1] -ArgumentList $args[2]")
  .AddArgument(computerName)
  .AddArgument(scriptPath)
  .AddArgument(credential)

暂无
暂无

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

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