【问题标题】:How to pass parameters to a powershell script using c# winforms?如何使用 c# winforms 将参数传递给 powershell 脚本?
【发布时间】:2020-04-04 16:54:55
【问题描述】:

我想通过 winforms 执行一个 powershell 脚本并获得格式良好的输出。我设法让它工作,但现在我需要将参数传递给我的脚本。我无法做到这一点。

这是我的 RunScript 函数:

        private string RunScript(string scriptFile)
        {
            Runspace runSpace = RunspaceFactory.CreateRunspace();
            runSpace.Open();
            Pipeline pipeLine = runSpace.CreatePipeline();
            Command script = new Command(scriptFile);
            script.Parameters.Add("COM_USERNAME", usernameBox.Text);
            script.Parameters.Add("COM_PASSWORD", passwordBox.Text);
            script.Parameters.Add("installDir", installDirBox.Text);
            script.Parameters.Add("TEMPVAULT_PATH", tempVaultBox.Text);
            script.Parameters.Add("MAX_REQ_LIMIT", maxReqLimBox.Text);
            script.Parameters.Add("MAX_BUFF_LIMIT", maxBuffLimBox.Text);
            pipeLine.Commands.AddScript(script.ToString());
            pipeLine.Commands.Add("Out-String");
            Collection<PSObject> results = pipeLine.Invoke();
            runSpace.Close();

            StringBuilder strBuilder = new StringBuilder();
            foreach (PSObject item in results)
            {
                strBuilder.AppendLine(item.ToString());
            }

            return strBuilder.ToString();
        }

这是我正在尝试的脚本:

param (
  [bool]   $STARTSERVICE = $false ,
  [bool]   $INSTALL = $false ,
  [bool]   $INSTALL_DASHBOARD = $false,
  [bool]   $DASHBOARD_SETTINGS = $false,
  [bool]   $DASHBOARD_CREATENEWDB = $false,
  [bool]   $DALIM_SETTINGS = $false,
  [bool]   $INSTALLIIS = $true,
  [bool]   $FIRST_INSTALL = $true,
  [bool]   $RECOVERY = $false,
  [string] $COM_USERNAME,
  [string] $COM_PASSWORD,
  [string] $RECOVERY_ADM_NAME,
  [string] $RECOVERY_ADM_PWD,
  [string] $Windows2012DVDLetter = "F:",
  [string] $COM_UNCPATH,
  [string] $installDir = "C:\Program Files\App\",
  [string] $TEMPVAULT_PATH = "C:\TempVault",
  $SOAP_MaxPostSize = 4294967295,
  $MAX_REQ_LIMIT = 500000000,
  $MAX_BUFF_LIMIT = 500000000

)

Write-Output "`nUsername = " $COM_USERNAME
Write-Output "`nPassword = " $COM_PASSWORD
Write-Output "`nCOM_UNCPATH = " $COM_UNCPATH
Write-Output "`nMaximum Request Limit = " $MAX_REQ_LIMIT
Write-Output "`nMaximum Buff Limit = " $MAX_BUFF_LIMIT
Write-Output "`nIsFirstInstall = " $FIRST_INSTALL
Write-Output "`nInstallation Directory = " $installDir
Write-Output "`nTempVault Path = " $TEMPVAULT_PATH
Write-Output "`nRestriction level = " $RESTRICT_LVL

我的输出只显示了脚本中预先注册的值,但我试图显示的那些(文本框输入)没有。我错过了什么吗?

【问题讨论】:

  • 从这个Answer看来,参数应该设置为:Parameters.Add(, )
  • No @Mahan.A 它似乎不是那样工作的,在他的情况下,他传递的值没有参数名称,所以他只获得值(文件)并且 paramName 为空。不过谢谢!
  • @Mahan.A.,添加到 Asuar 的评论:有几个 Command.Parameters.Add() overloads,但感兴趣的是 void Add(string name, System.Object value),这表明参数名称是 first i>.

标签: c# winforms powershell


【解决方案1】:

注意:以下假设scriptFile*.ps1 文件的路径,而不是该文件的内容(包含Powershell 代码的字符串)。
后一种情况的处理方法见底部。


您可以大大简化您的调用

private string RunScript(string scriptFile)
{
  using (var ps = PowerShell.Create()) {
    ps.AddCommand(scriptFile) // Be sure to pass a *full path*
        .AddParameter("COM_USERNAME", usernameBox.Text)
        .AddParameter("COM_PASSWORD", passwordBox.Text)
        .AddParameter("installDir", installDirBox.Text)
        .AddParameter("TEMPVAULT_PATH", tempVaultBox.Text)
        .AddParameter("MAX_REQ_LIMIT", maxReqLimBox.Text)
        .AddParameter("MAX_BUFF_LIMIT", maxBuffLimBox.Text)
      .AddCommand('Out-String'); // Add a pipeline segment
    // Return the 1st (and in this case only) output object, as a string.
    return ps.Invoke<string>()[0]; 
  }
} 

使用PowerShell.Create() 创建一个类PowerShell 的实例,它基于隐式创建的运行空间提供更高级别的API

  • 可以链接方法。
  • 反复调用.AddCommand() 会自动添加新的管道段。

至于你尝试了什么

pipeLine.Commands.AddScript(script.ToString());

.AddScript() 方法用于添加任意段 PowerShell 代码,而不是用于添加带有关联参数的 Command 实例。
Command 实例代表 PowerShell 命令,例如 Out-String 或外部可执行文件的名称/路径或脚本文件 (*.ps1) 的路径[1])。

通过使用.ToString() 对存储在script 中的Command 实例进行字符串化,您实际上只是将脚本路径 作为要执行的命令传递——您添加的所有参数.AddParameter() 丢失了,这就是为什么您只在脚本的输出中看到 default 参数值的原因。

相反,您应该按如下方式添加您的 Command 实例

pipeLine.Commands.Add(script)

如果scriptFile不是文件路径,而是脚本文件的内容(包含PowerShell代码的字符串):

正如您已经澄清的那样,这是您的实际用例,因为该脚本作为 资源 嵌入到您通过RunScript(Properties.Resources.&lt;the script&gt;) 传递的可执行文件中@

调整顶部的简化方法如下:

// If `scriptFile` is the *contents* of a *.ps1 file,
// add it as a script [block] with .AddScript(),
// then add parameters (and the additional pipeline command).
ps.AddScript(scriptFile) 
        .AddParameter("COM_USERNAME", usernameBox.Text)
        .AddParameter("COM_PASSWORD", passwordBox.Text)
        .AddParameter("installDir", installDirBox.Text)
        .AddParameter("TEMPVAULT_PATH", tempVaultBox.Text)
        .AddParameter("MAX_REQ_LIMIT", maxReqLimBox.Text)
        .AddParameter("MAX_BUFF_LIMIT", maxBuffLimBox.Text)
  .AddCommand('Out-String'); // Add a pipeline segment

[1] PowerShell 仅允许对位于 PATH 环境变量中列出的目录中的可执行文件/脚本执行仅按名称执行(例如,foo.ps1)。否则,必须指定文件 path,并且使用 完整路径 是最安全的,因为 .NET 的当前目录通常与 PowerShell 的不同。

【讨论】:

    猜你喜欢
    • 2020-09-04
    • 2015-06-07
    • 2011-08-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    相关资源
    最近更新 更多