2011-01-27 2 views
5

첫 번째 예제가 두 번째 예제와 같은 이유는 무엇입니까?원격 컴퓨터에서 Invoke-Command를 사용할 때 PowerShell에서 문자열 확장이 작동하지 않습니다.

1 :

$volumeNum = 2 
Invoke-Command -ComputerName $IP -Credential $GuestVM -ScriptBlock {"select volume $volumeNum" | diskpart} 

2 :

Invoke-Command -ComputerName $IP -Credential $GuestVM -ScriptBlock {"select volume 2" | diskpart} 

왜 does't PowerShell을 평가

"선택 볼륨 $의 volumeNum"

-

선택 볼륨 2

답변

7

현재의 환경 상태에 대한 액세스 권한이없는 Invoke-Command 통해 실행되는 스크립트 블록, 별도의 프로세스에서 실행됩니다. 로컬 컴퓨터에서 명령을 실행 중이면 제대로 작동합니다.

문자열 "select volume $volumeNum"은 원격 컴퓨터에서 실행될 때까지 평가되지 않습니다. 따라서 원격 시스템의 현재 프로세스 환경에서 값을 찾고 있으며 $volumeNum이 정의되어 있지 않습니다.

PowerShell은 Invoke-Command을 통해 인수를 전달하는 메커니즘을 제공합니다. 이것은 원격으로 내 로컬 컴퓨터에서 작동합니다

Invoke-Command -ComputerName $IP -Credential $GuestVM -ScriptBlock {param($volumeNum) "select volume $volumeNum" | diskpart} -ArgumentList $volumeNum 
3

스크립트 블록을 컴파일 :

Invoke-Command -ComputerName $ip -ScriptBlock { param($x) "hello $x" } -ArgumentList "world" 

내가 비슷한 접근 방식은 당신을 위해 일하는 것이 생각합니다. 즉, 변수 참조가 컴파일 타임에 고정된다는 의미입니다. 당신은 런타임 때까지 스크립트 블록의 생성을 연기함으로써이 문제를 해결할 수 있습니다

$sb = [scriptblock]::create("select volume $volumeNum | diskpart") 
Invoke-Command -ComputerName $IP -Credential $GuestVM -ScriptBlock $sb 
2

또한 메모를 따라오고 다른 사람을 위해 : GetNewClosure이 잘 작동하지 않습니다.

$filt = "*c*" 
$cl = { gci D:\testdir $filt }.GetNewClosure() 
& $cl 

# returns 9 items 
Invoke-command -computer mylocalhost -script $cl 
# returns 9 items 
Invoke-command -computer mylocalhost -script { gci D:\prgs\tools\Console2 $filt } 
# returns 4 items 
Invoke-command -computer mylocalhost -script { gci D:\prgs\tools\Console2 "*c*" } 
관련 문제