如何将Get-Childitem的结果正确传递到脚本块中? [英] How to pass results of Get-Childitem into a Scriptblock properly?

查看:212
本文介绍了如何将Get-Childitem的结果正确传递到脚本块中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此示例中,我尝试将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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆