programing

powershell의 스크립트 블록에 인수 전달

yoursource 2023. 8. 15. 15:21
반응형

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

그러면 스크립트 블록 $block에 변수를 전달하려면 어떻게 해야 합니까?

키스의 대답은 또한 효과가 있습니다.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

여기와 여기도 참조하십시오.

스크립트 블록은 익명 기능일 뿐입니다.사용할 수 있습니다.$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

Powershell 3.0부터 시작하여 원격 세션 스크립트 블록에서 로컬 변수를 사용하려는 2020년의 읽기 사용자는 "$Using" 스코프 수식어를 사용하여 스크립트 블록에서 직접 로컬 변수를 사용할 수 있습니다.예:

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

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-7 의 예 9에서 찾을 수 있습니다.

BTW, 스크립트 블록을 사용하여 별도의 스레드(멀티 스레드)에서 실행하는 경우:

$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

기본적으로 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

세 가지 예제 구문:

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

저는 이 기사가 좀 구식이라는 것을 알지만, 가능한 대안으로 이것을 버리고 싶었습니다.이전 답변을 약간 변형한 것뿐입니다.

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

기타 가능성:

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

언급URL : https://stackoverflow.com/questions/16347214/pass-arguments-to-a-scriptblock-in-powershell

반응형