1

在此示例中,我尝试将结果传递Get-ChildItem到脚本块中,但成功有限且结果出乎意料。

C:\temp包含3个文件:

  • 一个.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

有人可以帮助解释这样做的正确方法吗?

4

1 回答 1

2

PowerShell 在将列表传递给脚本块时展开列表,以便第一个值传递给第一个参数,第二个值传递给第二个参数,依此类推,而不是整个列表/数组传递给第一个参数。

在您的第一个示例中,您传递了一个由单个值和一个值数组组成的参数列表。展开该(外部)列表时,您仍然有两个参数(一个值和一个数组)。

在第二个示例中,您只传递了一个数组。展开该参数列表时,您最终会得到一个包含三个单独值的列表,其中第一个值转到脚本块的第一个参数。

为了防止这种行为,您需要通过使用一元数组构造运算符将变量包装在另一个数组中来“屏蔽”单独的数组:

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

或者使用using范围修饰符而不是传递参数:

Start-Job -ScriptBlock {
    Write-Host $using:files.Count
} | Out-Null
于 2017-06-19T16:14:55.697 回答