将参数传递给PowerShell中的scriptblock

dex*_*ter 40 powershell scriptblock

我猜你不能这样做:

  $servicePath = $args[0]

  if(Test-Path -path $servicePath) <-- does not throw in here

  $block = {

        write-host $servicePath -foreground "magenta"

        if((Test-Path -path $servicePath)) { <-- throws here.

              dowork 
        }
  }
Run Code Online (Sandbox Code Playgroud)

那么如何将我的变量传递给scriptblock $ block?

Lar*_*ens 44

Keith的答案也适用Invoke-Command,但不能使用命名参数.应使用-ArgumentList参数设置参数,并且应以逗号分隔.

$sb = {
    param($p1,$p2)
    $OFS=','
    "p1 is $p1, p2 is $p2, rest of args: $args"
}
Invoke-Command $sb -ArgumentList 1,2,3,4
Run Code Online (Sandbox Code Playgroud)

另见这里这里.


Kei*_*ill 31

scriptblock只是一个匿名函数.例如,您可以$args在scriptblock内部使用以及声明param块

$sb = {
  param($p1, $p2)
  $OFS = ','
  "p1 is $p1, p2 is $p2, rest of args: $args"
}
& $sb 1 2 3 4
& $sb -p2 2 -p1 1 3 4
Run Code Online (Sandbox Code Playgroud)

  • 不在PowerShell中.如果你在当前的运行空间中运行scriptblock,那么是,这些变量被选中.但这只是一个动态的范围界定功能.尝试使用Start-Job的scriptblock,其中scriptblock被序列化为另一个PowerShell进程以供执行,您将看不到自动捕获的变量. (5认同)

小智 9

对于 2020 年想要在远程会话脚本块中使用局部变量的读者,从 Powershell 3.0 开始,您可以使用“$Using”范围修饰符直接在脚本块中使用局部变量。例子:

$MyLocalVariable = "C:\some_random_path\"
acl = Invoke-Command -ComputerName REMOTEPC -ScriptBlock {Get-Acl $Using:MyLocalVariable}
Run Code Online (Sandbox Code Playgroud)

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-7 的示例 9 中找到


小智 6

顺便说一句,如果使用脚本块在单独的线程(多线程)中运行:

$ScriptBlock = {
    param($AAA,$BBB) 
    return "AAA is $($AAA) and BBB is $($BBB)"
}

$AAA = "AAA"
$BBB = "BBB1234"    
$null = Start-Job $ScriptBlock -ArgumentList $AAA,$BBB
Run Code Online (Sandbox Code Playgroud)

然后产生:

$null = Start-Job $ScriptBlock -ArgumentList $AAA,$BBB    
Get-Job | Receive-Job
AAA is AAA and BBB is BBB1234
Run Code Online (Sandbox Code Playgroud)