簡體   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