为什么这个函数不适用于管道变量?

fin*_*ast 3 powershell piping

我创建了这个函数来解析特定文本的字段并返回一个自定义对象.

如果我使用语法,一切正常,Get-MachineUser -VMArray $PassedArray但如果我管道数组它不起作用$PassedArray | Get-MachinesUser.

我和我的团队中的某个人一起工作,我们发现当我们传递数组时,它只处理数组中的最后一个条目.我不介意使用其他语法,但我很好奇我有什么错误导致管道无法正常工作.

function Get-MachinesUser{
    param (
        [parameter(Mandatory=$true, ValueFromPipeline=$true)]
        [System.Object[]] $VMArray
    )
    foreach($vm in $VMArray){
        if($VM.Description -match '.*(ut[A-Za-z0-9]{5}).*'){
            [PSCustomObject]@{
            "Name" = $vm.Name  
            "User" = $Matches[1]
            }
        }
    }
}  
Run Code Online (Sandbox Code Playgroud)

Mar*_*agg 6

要支持管道输入,您需要在函数中使用一个过程块:

function Get-MachinesUser{
    param (
        [parameter(Mandatory=$true, ValueFromPipeline=$true)]
        [System.Object[]] $VMArray
    )
    Process{
        foreach($vm in $VMArray){
            if($VM.Description -match '.*(ut[A-Za-z0-9]{5}).*'){
                [PSCustomObject]@{
                "Name" = $vm.Name  
                "User" = $Matches[1]
                }
            }
        }
    }  
}
Run Code Online (Sandbox Code Playgroud)

处理

该块用于为函数提供逐个记录的处理.此块可能会被使用任意次,具体取决于函数的输入.例如,如果函数是管道中的第一个命令,则将使用Process块一次.如果该函数不是管道中的第一个命令,则对于函数从管道接收的每个输入,都会使用一次Process块.

资料来源:https://ss64.com/ps/syntax-function-input.html

(注意:引用稍作修改,因为SS64错误地指示在没有管道输入的情况下不执行进程块,而实际上它仍然执行一次).

包含ForEach循环仍然是正确的,因为这意味着在通过参数传递时支持数组输入.但是,为了在通过管道发送时处理所有输入,Process { }需要一个块.

  • 为了补充这个答案,这里有一篇[Boe Prox关于这个主题的优秀指南](https://learn-powershell.net/2013/05/07/tips-on-implementing-pipeline-support/) (3认同)