在这个例子中,我试图将Get-ChildItem
的结果传递给一个脚本块,但成效有限并且意外结果。
C:\temp
包含3个文件:
我想要的是将$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传递给scriptblock:
$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 :(得分:2)
PowerShell在将它们传递给scriptblock时展开列表,以便第一个值转到第一个参数,第二个值转到第二个参数等,而不是整个列表/数组转到第一个参数。
在第一个示例中,您传递的参数列表包含单个值和值数组。展开该(外部)列表时,您仍然有两个参数(单个值和一个数组)。
在第二个示例中,您只传递一个数组。展开该参数列表时,最终会得到一个包含三个单独值的列表,第一个值将转到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