【问题标题】:Why won't this function work with a piped variable?为什么此函数不适用于管道变量?
【发布时间】:2017-05-11 21:24:25
【问题描述】:

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

如果我使用语法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]
            }
        }
    }
}  

【问题讨论】:

  • $PassedArray 是什么对象类型,其中包含哪些对象类型(字符串、对象集合、其他)?
  • 这是一个字符串数组。

标签: powershell piping


【解决方案1】:

要支持管道输入,您需要在函数中添加一个进程块:

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]
                }
            }
        }
    }  
}

流程

此块用于为 功能。这个块可以使用任意次数, 取决于函数的输入。例如,如果函数 是管道中的第一个命令,将使用 Process 块 一度。如果函数不是管道中的第一个命令, Process 块对函数的每个输入使用一次 从管道接收。

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

(注:由于 SS64 错误地指出在没有管道输入的情况下不会执行进程块,而实际上它仍然执行一次),因此引用已稍作修改。 p>

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

【讨论】:

  • 为了补充这个答案,这里是excellent guide on this topic by Boe Prox
  • 这是正确的,但根据在回答和编辑后发表的评论,他输入的是字符串数组,而不是对象。如果准确,还需要将[System.Object[]] $VMArray 更改为[String[]] $VMArrayif($VM.Description -match 更改为if($VM -match
  • 我可能在这里忽略了一些东西,但是添加进程块会改变管道的行为吗?当我调用该函数时,使用相同的变量作为普通参数:Get-MachineUser -VMArray $PassedArray 它工作正常。这可能是我刚刚在 Powershell 的行为中忽略的东西,但我认为传递数组或仅将其用作参数之间没有区别。
  • 有区别。使用它作为参数一次传递整个集合。通过管道 powershell 发送它会自动展开它并通过进程块一次处理一项(基本上自动完成 foreach 的工作)。
  • 为了完整,建议不要只写一个“Process”-Part,你应该写一个“Begin”-Part(对于初始操作,必须只运行一次并使用对于所有元素,例如建立与特定服务器的远程连接)和“结束”部分(释放连接,处置对象等)
猜你喜欢
  • 2012-08-10
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 1970-01-01
  • 2012-12-23
  • 1970-01-01
相关资源
最近更新 更多