Je suppose que vous ne pouvez pas simplement faire ceci:
$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
}
}
Alors, comment puis-je transmettre mes variables au bloc scriptblock $?
La réponse de Keith fonctionne également pour Invoke-Command
, avec la limite pour laquelle vous ne pouvez pas utiliser de paramètres nommés. Les arguments doivent être définis à l'aide du paramètre -ArgumentList
et doivent être séparés par des virgules.
$sb = {param($p1,$p2) $OFS=','; "p1 is $p1, p2 is $p2, rest of args: $args"}
Invoke-Command $sb -ArgumentList 1,2,3,4
Un scriptblock est juste une fonction anonyme. Vous pouvez utiliser $args
dans le bloc de script Ainsi que déclarer un bloc param, par exemple
$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
BTW, si vous utilisez le bloc de script pour s'exécuter dans un thread séparé (multithread):
$ScriptBlock = {
param($AAA,$BBB)
return "AAA is $($AAA) and BBB is $($BBB)"
}
$AAA = "AAA"
$BBB = "BBB1234"
$null = Start-Job $ScriptBlock -ArgumentList $AAA,$BBB
puis donne:
$null = Start-Job $ScriptBlock -ArgumentList $AAA,$BBB
Get-Job | Receive-Job
AAA is AAA and BBB is BBB1234
Je sais que cet article est un peu démodé, mais je voulais le proposer comme alternative possible. Juste une légère variation des réponses précédentes.
$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"
Par défaut, PowerShell ne capture pas les variables pour un ScriptBlock. Vous pouvez explicitement capturer en appelant GetNewClosure()
dessus, cependant:
$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