2013-05-02 16 views
30

Chyba nie można po prostu to zrobić:przekazywać argumenty do scriptblock 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 
     } 
    } 

Więc jak mogę przekazać moje zmienne do scriptblock $ bloku?

+0

Co zrobisz ze swoim blokadą skryptu? Użyj Invoke-Command lub &? –

+3

Jeśli masz zamiar użyć '&', możesz to zrobić: '& {param ($ hello) $ hello} -hello world' – JohnL

+0

@LarsTruijens - Planuję wykonać Invoke-Command-Session – dexter

Odpowiedz

34

Keith's answer działa również dla Invoke-Command, z limitem, że nie można używać nazwanych parametrów. Argumenty należy ustawić za pomocą parametru -ArgumentList i należy je rozdzielić przecinkami.

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

zobaczyć również here i here.

26

Scriptblock to tylko anonimowa funkcja. Można użyć $args wewnątrz scriptblock jak również zadeklarować blok param np

$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

Dobrze, ale don Czy zamknięcie tradycyjnie obejmuje również zmienne? Zakładam, że złapię wyżej $ servicePath. – Kakira

+5

Nie w PowerShell. Jeśli uruchomisz blok skryptów w bieżącym obszarze roboczym, to tak, te zmienne zostaną pobrane. Ale to tylko dynamiczna funkcja ustalania zakresu. Wypróbuj to za pomocą skryptu skryptowego dla Start-Job, gdzie skryptblok jest serializowany do innego procesu PowerShell do wykonania i nie zobaczysz automatycznie przechwyconych zmiennych. –

1

Wiem, że ten artykuł jest nieco przestarzały, ale chciałem go wyrzucić jako możliwą alternatywę. Tylko nieznaczna zmiana poprzednich odpowiedzi.

$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

okazji, w przypadku korzystania z bloku skryptowy w oddzielnych nici (Multi gwintowane):

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

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

czym otrzymuje się:

$null = Start-Job $ScriptBlock -ArgumentList $AAA,$BBB  
Get-Job | Receive-Job 
AAA is AAA and BBB is BBB1234 
0

Domyślnie PowerShellu nie uchwycą zmienne dla ScriptBlock. Możesz jawnie przechwycić, dzwoniąc pod numer 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 
Powiązane problemy