59

我想你不能这样做:

  $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 
        }
  }

那么如何将我的变量传递给脚本块 $block?

4

8 回答 8

62

基思的答案也适用于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

另请参阅此处此处

于 2013-05-03T16:57:35.043 回答
39

脚本块只是一个匿名函数。您可以$args在脚本块内使用以及声明一个参数块,例如

$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
于 2013-05-03T03:22:54.263 回答
13

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

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

$AAA = "AAA"
$BBB = "BBB1234"    
$null = Start-Job $ScriptBlock -ArgumentList $AAA,$BBB

然后产生:

$null = Start-Job $ScriptBlock -ArgumentList $AAA,$BBB    
Get-Job | Receive-Job
AAA is AAA and BBB is BBB1234
于 2017-05-25T20:12:41.240 回答
11

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

$MyLocalVariable = "C:\some_random_path\"
acl = Invoke-Command -ComputerName REMOTEPC -ScriptBlock {Get-Acl $Using:MyLocalVariable}

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

于 2020-05-19T19:57:26.177 回答
4

默认情况下,PowerShell 不会捕获 ScriptBlock 的变量。但是,您可以通过调用它来显式捕获GetNewClosure()

$servicePath = $args[0]

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

$block = {

    write-host $servicePath -foreground "magenta"

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

          dowork 
    }
}.GetNewClosure() <-- this makes it work
于 2017-10-16T18:40:20.803 回答
2

三个示例语法:

$a ={ 
  param($p1, $p2)
  "p1 is $p1"
  "p2 is $p2"
  "rest of args: $args"
}
//Syntax 1:
Invoke-Command $a -ArgumentList 1,2,3,4 //PS> "p1 is 1, p2 is 2, rest of args: 3 4"
//Syntax 2:
&$a -p2 2 -p1 1 3      //PS> "p1 is 1, p2 is 2, rest of args: 3"
//Syntax 3:
&$a 2 1 3              //PS> "p1 is 2, p2 is 1, rest of args: 3"
于 2020-11-05T14:20:06.417 回答
1

我知道这篇文章有点过时了,但我想把它作为一种可能的选择扔掉。只是与之前的答案略有不同。

$foo = {
    param($arg)

    Write-Host "Hello $arg from Foo ScriptBlock" -ForegroundColor Yellow
}

$foo2 = {
    param($arg)

    Write-Host "Hello $arg from Foo2 ScriptBlock" -ForegroundColor Red
}


function Run-Foo([ScriptBlock] $cb, $fooArg){

    #fake getting the args to pass into callback... or it could be passed in...
    if(-not $fooArg) {
        $fooArg = "World" 
    }
    #invoke the callback function
    $cb.Invoke($fooArg);

    #rest of function code....
}

Clear-Host

Run-Foo -cb $foo 
Run-Foo -cb $foo 

Run-Foo -cb $foo2
Run-Foo -cb $foo2 -fooArg "Tim"
于 2017-02-07T18:59:02.467 回答
0

其他可能性: $a ={ param($p1, $p2) "p1 is $p1" "p2 is $p2" "rest of args: $args" } $a.invoke(1,2,3,4,5 )

于 2021-02-26T15:08:13.833 回答