2013-05-02 66 views
30

一個腳本塊我想你不能只是這樣做:參數傳遞給在PowerShell中

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

因此,如何能我通過我的變量到腳本塊$塊?

+0

你將與你的腳本塊做什麼?使用調用命令或&? – 2013-05-02 21:06:32

+3

如果你打算使用'&',那麼你可以這樣做:'&{param($ hello)$ hello} -hello world' – JohnL 2013-05-02 21:09:59

+0

@LarsTruijens - 我打算做Invoke-Command -Session – dexter 2013-05-03 14:25:20

回答

34

Keith's answer也適用於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 

另見herehere

26

scriptblock只是一個匿名函數。您可以使用$args的 腳本塊內以及聲明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 
+0

對,不過傳統上封閉也會捕獲變量?我假設$ servicePath將被捕獲。 – Kakira 2014-09-15 21:06:13

+5

不在PowerShell中。如果你在當前的運行空間中運行腳本塊,那麼是的,那些變量被拾取。但這只是一個動態的範圍界定功能。使用Start-Job的scriptblock試試這個,在這裏scriptblock被序列化到另一個PowerShell進程執行,你將看不到自動捕獲的變量。 – 2014-09-15 21:38:52

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" 
1

順便說一句,如果用腳本塊在一個單獨的線程中運行(多線程):

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

默認的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