首页 > 解决方案 > 管道记录失效

问题描述

我想在一个管道中将 cmdlet 链接在一起,从一个Import-Csv要处理的 NN 记录文件开始,最后我想为所有 NN 记录和累积的处理结果写出一个结果文件。在此过程中,我可能希望将数据添加到管道中,说明不再进一步处理此记录,但仍将其传递到管道中。

我设想这看起来像这样:

Import-Csv input | step-1 -env DEV | step-2 | step-3 | Export-Csv result

写入每个 cmdlet 以通过管道传输$_每条记录的所有属性并将它们保存在管道中。

读取某种“CanContinue”属性的最佳方法是什么,如果它是错误的短路处理,并且只是将其传递给管道中的下一个 cmdlet 而无需处理?

标签: powershellpowershell-2.0powershell-3.0powershell-4.0

解决方案


我假设您不希望此标志成为生成的 CSV 的一部分。在我看来,您可以使用两种类似的方法:在返回之前将标志添加到正在处理的对象中,或者将对象包装在另一个对象中(其中包含标志和另一个保存原始对象的属性)。

现在,我将探索添加属性的第一个选项。我要把它从正面CanContinue变为负面,DoNotProcess这样它的不存在就可以合并为$false(继续)。

为此,在您的每个处理函数中,只需检查DoNotContinue属性的值。如果是$true,则返回您收到的原始对象,无需额外处理。

如果是$false,您可以进行处理,如果满足停止处理的条件,则强制添加属性$true

Process {
    # processing done
    $MyObj |
        Add-Member -NotePropertyName DoNotContinue -NotePropertyValue $true -Force -PassThru
}

所有这样的命令都可以这样处理。

现在,当涉及到管道的末尾时,您不希望将此属性写入 CSV。为此,将其剥离Select-Object

Import-Csv input | 
    step-1 -env DEV | 
    step-2 | 
    step-3 | 
    Select-Object -Property * -ExcludeProperty DoNotContinue |
    Export-Csv result

奖金:

请参阅我对您的另一个问题的回答,而不是手动检查属性,而是将其定义为处理 cmdlet 中的参数,[Parameter(ValueFromPipelineByPropertyName)]如下所示:

param(
    [Parameter(ValueFromPipelineByPropertyName)]
    [Switch]
    $DoNotContinue
)

为什么要这样做?因为您让 PowerShell 为您处理对象,您只需检查$DoNotContinue. 它还允许您为特定调用覆盖该值。

(在这种情况下,我会将其重命名为$DoNotProcessor$SkipProcessing或其他名称;请记住,[Alias()]如果您希望它具有多个名称,也可以使用)


推荐阅读