如何将Get-Childitem的结果正确传递到脚本块中? [英] How to pass results of Get-Childitem into a Scriptblock properly?
问题描述
在此示例中,我尝试将Get-ChildItem
的结果传递到脚本块中,但成功率有限且结果出乎意料.
In this example, I'm trying to pass the results of Get-ChildItem
into a scriptblock, with limited success and unexpected results.
C:\temp
包含3个文件:
- A.txt
- B.txt
- C.txt
我想要的是将$files
传递到此处的脚本块中,并维护Get-ChildItem
返回的三个文件的整个列表.换句话说,我希望$files
在脚本块的内部和外部返回A.txt,B.txt和C.txt.
What I want is to pass $files
into the scriptblock here, and maintain the entire list of three files that Get-ChildItem
has returned. In other words, I would like for $files
to return A.txt, B.txt, and C.txt, both inside and outside the scriptblock.
我能够做到这一点,但是我不能可靠地做到这一点,也无法解释原因.我不想依靠虚拟"变量来使其正常工作,我想了解两者之间的区别.
I am able to do this, but I'm not able to do it reliably, and cannot explain why. I do not want to have to rely on a "dummy" variable to make this work properly, I'd like to understand what the difference is.
这里的第一个示例返回所有文件:
The first example here returns all of the files:
$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传递到脚本块中:
The second example only passes A.txt into the 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
有人可以帮忙解释执行此操作的正确方法吗?
Can someone help to explain the proper way to do this?
推荐答案
PowerShell在将列表传递到脚本块时会展开列表,以便第一个值进入第一个参数,第二个值进入第二个参数,以此类推,而不是整个列表/数组转到第一个参数.
PowerShell unrolls lists when passing them to a scriptblock, so that the first value goes to the first parameter, the second value to the second parameter, etc. instead of the entire list/array going to the first parameter.
在第一个示例中,您传递了一个由单个值和值数组组成的参数列表.展开该(外部)列表时,您仍然有两个参数(一个值和一个数组).
In your first example you pass an argument list that consists of a single value and an array of values. When unrolling that (outer) list you still have two arguments (a single value and an array).
在第二个示例中,您仅传递了一个数组.展开该参数列表时,您最终得到三个单独值的列表,其中第一个进入脚本块的第一个参数.
In your second example you pass just an array. When unrolling that parameter list you end up with a list of three individual values, the first of which goes to the first parameter of the scriptblock.
To prevent this behavior you need to "mask" lone arrays by wrapping the variable in another array with the unary array construction operator:
Start-Job -ScriptBlock {
Param($files)
Write-Host $files.Count
} -ArgumentList (,$files) | Out-Null
或者使用
Alternatively use the using
scope modifier instead of passing arguments:
Start-Job -ScriptBlock {
Write-Host $using:files.Count
} | Out-Null
这篇关于如何将Get-Childitem的结果正确传递到脚本块中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!