Powershell 管道语义是';t传播到Where对象

Powershell 管道语义是';t传播到Where对象,powershell,Powershell,我使用以下命令来运行管道 .\Find-CalRatioSamples.ps1 data16 ` | ? {-Not (Test-GRIDDataset -JobName DiVertAnalysis -JobVersion 13 -JobSourceDatasetName $_ -Exists -Location UWTeV-linux)} 第一个是我的自定义脚本,运行速度非常快(毫秒)。第二个是自定义命令,也是由我编写的(请参阅)。它非常慢 实际上,它处理每一行输入的速度并不慢。

我使用以下命令来运行管道

.\Find-CalRatioSamples.ps1 data16 `
    | ? {-Not (Test-GRIDDataset -JobName DiVertAnalysis -JobVersion 13 -JobSourceDatasetName $_  -Exists -Location UWTeV-linux)}
第一个是我的自定义脚本,运行速度非常快(毫秒)。第二个是自定义命令,也是由我编写的(请参阅)。它非常慢

实际上,它处理每一行输入的速度并不慢。处理第一行输入之前的设置非常昂贵。然而,这样做的速度相当快。因此,所有昂贵的代码都执行一次,并且对于每个新的管道输入,只需要执行相当快的代码

不幸的是,当我想做的时候?{}在上面的构造中,PowerShell似乎不像以前那样保留管道。现在,它为每一行输入调用一个新的时间,使该命令为每一行重做所有设置


在调用管道的方式上是否有一些可以更改的地方?或者我是如何编写cmdlet来防止这种情况发生的?还是我被卡住了,因为这正是对象工作的方式?

它正在按设计工作。调用命令时,您正在脚本块内启动一个新的(嵌套的)管道

如果您的函数在其
Begin
块中执行昂贵的代码,那么您需要直接将第一个脚本导入到函数中以获得这一优势

.\Find-CalRatioSamples.ps1 data16 | 
    Test-GRIDDataset -JobName DiVertAnalysis -JobVersion 13 -Exists -Location UWTeV-linux |
    Where-Object { $_ }
但这样看来,您并没有返回您想要的对象(原始对象)

您可以更改
Test GRIDDataset
的一种方法是实现一个
-PassThru
开关,尽管您实际上并不接受原始脚本中的完整对象,因此我无法判断这是否可行;但您编写的代码似乎正在检索。。。基于名字的某处的东西(?)。也许这就足够了?当指定了
-PassThru
时,如果对象存在,则通过管道发送对象(而不仅仅是它们是否存在的布尔值)

那么您的代码将如下所示:

.\Find-CalRatioSamples.ps1 data16 | 
    Test-GRIDDataset -JobName DiVertAnalysis -JobVersion 13 -Exists -Location UWTeV-linux -PassThru

我以前没听说过普什图参数——看起来有点像个抢手货,但看起来不错。下面是一篇关于它的老博文,供后来讨论这个问题的人参考: