2017-06-19 48 views
1

在這個例子中,我試圖將Get-ChildItem的結果傳遞給一個scriptblock,但成功有限,並且出現了意想不到的結果。如何正確地將Get-Childitem的結果傳遞給Scriptblock?

C:\temp包含3個文件:

  • A.TXT
  • B.txt
  • C.txt

我想是通過$files到腳本塊在這裏,保持Get-ChildItem已返回的三個文件的整個列表。換句話說,我希望$files能夠在腳本塊內部和外部返回A.txt,B.txt和C.txt。

我能夠做到這一點,但我無法做到可靠,並且無法解釋原因。我不想依賴一個「虛擬」變量來使其正常工作,我想了解它們之間的區別。

第一個例子這裏返回的所有文件:

$files = Get-ChildItem -Path "C:\temp" 
$test = $files.Get(0) 
Write-Host $files.Count 

Start-Job -ScriptBlock { 
    Param($test, $files) 
    Write-Host $files.Count 
} -ArgumentList $test, $files | Out-Null 

Wait-Job * | Out-Null 
$results += Get-Job | Receive-Job 

第二個例子只傳遞A.TXT到腳本塊:

$files = Get-ChildItem -Path "C:\temp" 
Write-Host $files.Count 

Start-Job -ScriptBlock { 
    Param($files) 
    Write-Host $files.Count 
} -ArgumentList $files | Out-Null 

Wait-Job * | Out-Null 
$results += Get-Job | Receive-Job 

有人可以幫助解釋正確的方式做這個?

+0

你應該使用foreach循環。並迭代每個值,並最終做到這一點的操作。 –

+0

@Ranadip Dutta這裏的問題是,在第二個示例中,只有一個文件傳遞到scriptblock,儘管看起來我已經像第一個例子那樣處理了,而第一個例子通過了所有文件。 –

回答

2

PowerShell在將列表傳遞給scriptblock時展開列表,以便第一個值轉到第一個參數,第二個值轉換爲第二個參數等,而不是整個列表/數組轉到第一個參數。

在第一個示例中,您傳遞一個由單個值和一組值組成的參數列表。展開(外部)列表時,您仍然有兩個參數(一個值和一個數組)。

在你的第二個例子中,你只傳遞一個數組。展開參數列表時,您最終會得到一個包含三個單獨值的列表,其中第一個列表將顯示在腳本塊的第一個參數中。

爲了防止這種行爲,你需要在另一個數組與unary array construction operator包裹變量「面具」孤獨的數組:

Start-Job -ScriptBlock { 
    Param($files) 
    Write-Host $files.Count 
} -ArgumentList (,$files) | Out-Null 

或者使用using scope modifier,而不是傳遞參數:

Start-Job -ScriptBlock { 
    Write-Host $using:files.Count 
} | Out-Null 
+0

我喜歡Scoping部分。 :) –

+2

@Ansgar Wiechers這正是我尋找的解釋非常感謝你!這個概念對我來說很有意義,基於我在這裏提出問題之前試圖解決這個問題的測試。這個概念對我來說是新的,所以文檔非常有用。 –

相關問題