programing

파워셸 변수를 시작 작업으로 전달

starjava 2023. 8. 10. 18:08
반응형

파워셸 변수를 시작 작업으로 전달

powershell 내에서 변수를 시작 작업에 호출하는 가장 좋은 방법을 배우고 싶습니다. 그러면 스크립트를 배치한 클라이언트에 따라 특정되므로 각 서버의 스크립트를 편집할 필요가 없습니다.

$Servername = 'Server1'
    $pingblock = {
      pathping $servername | Out-File C:\client\PS\ServerPing.TXT
    }
    start-job $pingblock

위에서 코드를 실행하면 $server 이름 지정을 잊은 것처럼 도움말이 있는 파일이 나타납니다.

PSv3+ 대안으로 Keith Hill의 유용한 답변을 보완하기 위해:

스코프 수정자는 전달된 스크립트 블록 내에서 호출자의 스코프에 있는 변수의 값을 참조하는 데 사용될 수 있습니다.Start-Job인수를 전달하는 대신(기본적으로 백그라운드 작업으로 실행되는 스크립트 블록에는 호출자의 변수나 다른 정의가 표시되지 않음):

$Servername = 'Server1'
Start-Job { "Target: " + $using:ServerName } | Receive-Job -Wait -AutoRemoveJob

위의 산출물:

Target: Server1

참고:

  • 동일한 기법을 다음과 같이 사용할 수 있습니다.

    • Invoke-Command 원격 실행의 경우 - 이 질문을 참조하십시오.

    • PowerShell(Core) v6+에서는 기본적으로 사용할 수 있으며, 윈도우즈 PowerShell에서는 온디맨드 방식으로 설치할 수 Start-ThreadJob있습니다.

    • PowerShell(Core) v7+에서만 사용할 수 ForEach-Object -Parallel있습니다.

  • ()-Args와 마찬가지로 전달되는 것변수 자체아니라 변수 값뿐입니다. 즉, 호출자의 [1]변수는 수정할 수 없습니다.


그러나 스레드 기반 동시성 기능은 -Start-ThreadJob그리고.ForEach-Object Parallel간접적인 수정을 허용합니다. 즉, 당면한 변수 값이 (변종)의 인스턴스일 경우.NET 참조 유형(예: 해시 테이블). 이 경우 변수가 " 가리키는" 개체를 수정할 수 있습니다(변동 가능한 경우).이를 활용하려면 동시(동기화된) 컬렉션을 사용하는 것과 같이 동시 수정을 스레드 안전하게 만들기 위한 추가적인 노력이 필요합니다. 이 답변참조하십시오. 개별 개체의 명시적 잠금을 참조하십시오.

사용-ArgumentList에 대한 매개 변수.Start-Job예:

Start-Job -Scriptblock {param($p) "`$p is $p"} -Arg 'Server1'

당신의 경우:

$pingblock = {param($servername) pathping $servername | Out-File C:\...\ServerPing.txt}
Start-Job $pingblock -Arg Server1

다른 방법으로는 $args와 $input이 있습니다.이것은 동일한 메커니즘을 사용하는 invoke-command에도 적용됩니다.$input 메서드는 어레이에서 예상치 못한 방식으로 작동합니다.

start-job { $args[0] } -args hi | receive-job -wait -auto
hi


echo hi | start-job { $input } | receive-job -wait -auto
hi


echo hi there | start-job { $input.gettype() } | receive-job -wait -auto

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
False    False    <GetReadEnumerator>d__20                 System.Object

어레이의 경우 각 개체(%) 루프를 대신 사용하여 각 어레이 항목에서 병렬로 실행하는 것이 좋습니다.파워셸 7의 각 개체 병렬 또는 시작 스레드 작업을 참조하십시오.실제로 시작 작업에는 스로틀 제한 옵션이 없으므로 주의하여 사용하십시오.

echo yahoo.com facebook.com |
   % { $_ | start-job { test-netconnection $input } } |
   receive-job -wait -auto | select * -exclude runspaceid,pssourcejob* | ft

ComputerName RemoteAddress ResolvedAddresses PingSucce
                                             eded
------------ ------------- ----------------- ---------
yahoo.com    74.6.143.25   {74.6.143.25,...} True
facebook.com 31.13.71.36   {31.13.71.36}     True

언급URL : https://stackoverflow.com/questions/10075943/powershell-pass-variable-to-start-job

반응형