Как правильно передать результаты Get-Childitem в Scriptblock?
В этом примере я пытаюсь передать результаты Get-ChildItem
в сценарий, с ограниченным успехом и неожиданными результатами.
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
Может кто-нибудь помочь объяснить правильный способ сделать это?
1 ответ
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