【问题标题】:start powershell wont accept variable as parameter启动 powershell 不会接受变量作为参数
【发布时间】:2021-08-27 12:14:32
【问题描述】:

问题

调用的 powershell 脚本将接受参数但不是全部:

当前设置和代码:

我有一个公用文件夹,其中有两个 .ps1 脚本:

  • DoWork.ps1
  • Workmanager.ps1

Workmanager.ps1 调用 Dowork.ps1:

$targetPath="M:\target"
echo "target path: $targetPath"

start powershell {.\DoWork.ps1 -target $targetPath -tempdrive D:\}

输出(如预期):

目标路径:M:\target

DoWork.ps1 包含一些起始代码:

param 
(
    [string]$tempdrive, 
    [string]$target, 
    [int] $threads = 8,
    [int] $queuelength = -1
)
echo "variables:"
echo "temp drive: $tempdrive"
echo "target path: $target"

出乎意料的是,$target 没有被分配。以前我有一个名为 $targetpath 的变量,它也不起作用。

变量:
临时驱动器:D:\
目标路径:

调查结果

看来问题出在 Workmanager.ps1 中。将参数指定为固定字符串而不是变量将加载参数。有什么解决办法吗?

start powershell {.\DoWork.ps1 -target "foo" -tempdrive D:\}

【问题讨论】:

    标签: powershell variables parameters


    【解决方案1】:

    当您使用ScriptBlock 作为powershell.exe 的参数时,直到新会话开始之后 才会计算变量。 $targetPath 尚未在Workmanager.ps1 调用的子 PowerShell 进程中设置,因此它没有任何价值。 这实际上是 ScriptBlock 的一般预期行为,在其他情况下也是如此

    powershell -?的帮助文本中提到了解决方案:

    [-Command { - | <script-block> [-args <arg-array>] <========== THIS GUY
                  | <string> [<CommandParameters>] } ]
    

    您必须提供-args 参数,该参数将在执行时传递给ScriptBlock(用, 分隔多个参数)。传递的参数按位置传递,并且必须像您使用 $args 数组手动处理函数的参数一样引用。例如:

    $name = 'Bender'
    & powershell { Write-Output "Hello, $($args[0])" } -args $name
    

    但是,尤其是对于更复杂的ScriptBlock 实体,必须记住$args[i] 的哪个索引包含您在给定时间想要的值是一件很痛苦的事情。幸运的是,我们可以在 ScriptBlock 中定义参数来帮助我们:

    $name = 'Bender'
    & powershell { param($name) Write-Output "Hello, $name" } -args $name
    

    这将按预期打印Hello, Bender


    一些额外的指针:

    • ScriptBlock 可以是多行的,就像定义一个函数一样。方法。由于简单,上面的示例是单行的。

    • ScriptBlock 只是一个未命名的函数,这就是为什么在一个函数中定义参数和引用参数的工作方式相同。

    • 为了在powershell.exe -Command 之外举例说明此行为,Invoke-Command 要求您在similar fashion 中将变量传递给它的ScriptBlock。但是请注意,答案使用已经定义的函数体作为ScriptBlock(这是完全有效的)

    • 您不需要在这里使用Start-Processstart 是它的别名),至少如您的示例所示。您可以简单地使用呼叫运算符&amp;,除非您需要做一些比“运行程序并等待它完成”更复杂的事情。 See this answer of mine 了解更多信息。

    • 如果您选择将 string 传递给 powershell.exe,则无需提供参数,您的变量将在当前 PowerShell 进程中呈现。但是,可能打算在子进程中设置的任何其他未转义变量也是如此,因此请谨慎使用这种方法。就个人而言,无论如何我更喜欢使用ScriptBlock,并且只处理额外的参数定义和参数。

    • 当您不执行呈现为字符串的路径时,使用调用 &amp; 运算符是可选的。在上面的示例中可以省略它,但更有用的是:

      & "C:\The\Program Path\Contains\spaces.exe"
      
      & $programPathAsAVariable
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      • 1970-01-01
      • 1970-01-01
      • 2015-06-21
      相关资源
      最近更新 更多