如何安全地将字符串文字参数传递给powershell.exe

如何安全地将字符串文字参数传递给powershell.exe,powershell,Powershell,从另一个环境(例如Java)调用PowerShell脚本时,需要将文字字符串参数作为流程参数的一部分传递 如何清理或转义将作为字符串文本传递给PowerShell调用的用户输入 我在任何地方都找不到完整的指南。用单引号将文字括起来 用双单引号替换现有单引号 删除(或失败启用)`0(零)个字符-powershell可以在内部处理这些字符,但不能将它们传递给子进程 (根据您的程序执行的操作,您可能还希望删除32以下甚至127以上的输入。但这与编码无关) 这就是所有的人 参数:单字符串vs数组 我

从另一个环境(例如Java)调用PowerShell脚本时,需要将文字字符串参数作为流程参数的一部分传递

如何清理或转义将作为字符串文本传递给PowerShell调用的用户输入


我在任何地方都找不到完整的指南。

用单引号将文字括起来

  • 用双单引号替换现有单引号
  • 删除(或失败启用)
    `0
    (零)个字符-powershell可以在内部处理这些字符,但不能将它们传递给子进程
  • (根据您的程序执行的操作,您可能还希望删除32以下甚至127以上的输入。但这与编码无关)
这就是所有的人

参数:单字符串vs数组 我建议将所有参数作为一个空格分隔的字符串传递,即使您使用了接受字符串数组的process start API

如果您传递一组参数,PowerShell将只使用单个空格将它们连接起来,然后根据自己的逻辑再次将它们分开。(即使一个参数以引号开头,而另一个参数以引号结尾,这也有效。)

传递一系列参数只会使代码变得丑陋,掩盖实际发生的事情,并可能提供错误的安全感

测试字符串参数传递的正确性
  • 尝试在一行中添加多个空格:如果使用正确,它们将完全保留
  • 尝试在括号中传递值:
    • 正确传递时,它们将作为文本传递
    • 否则,PowerShell将尝试执行括号中的值,例如,
      PowerShell.exe写入主机“a b(c)”
      将导致错误:“无法识别术语“c”
    • 警告:
      `(c`
      中转义括号似乎是一种解决方案,但实际上只是掩盖了一个错误:参数未被识别为字符串文字
  • 尝试添加特殊字符

提示:从另一个shell(如cmd.exe或bash)调用powershell.exe时,不要混淆该shell的解析和powershell的解析。例如,引号限制cmd.exe或bash的参数,但这些参数不带引号传递给PowerShell。这可能会导致一些混淆。

如果在调用PowerShell scirpt时创建命名参数,则通常可以将其用作脚本中的变量,并且不必担心在脚本中创建参数时它们的顺序。而不是为它们创建变量名,然后在脚本中创建参数

比如说,

调用您的PowerShell脚本,
\Named\u Parameters\u Example\u 2.ps1-envname Odyssey-servername HAL

命名参数示例2.ps1

write-host "If this script were really going to do something, it would do it on $servername in the $envname environment"

因此,有人建议只将字符串值放入环境变量中。虽然正确和安全地编码字符串似乎是完全可能的,但对我来说,完全避免这个问题似乎是一个更好的解决方案

在C#中,看起来是这样的:

var startInfo = new ProcessStartInfo("powershell.exe");
startInfo.Arguments = "Some-Command -StringArg1 $env:StringArg1 -StringArg2 $env:StringArg2";
startInfo.EnvironmentVariables.Add ("StringArg1", unencodedValue1);
startInfo.EnvironmentVariables.Add ("StringArg2", unencodedValue2);
Process.Start (startInfo);