Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why won't this function work with a piped variable?

I created this function that parses a field for specific text and returns a custom object.

Everything works fine if I use the syntax, Get-MachineUser -VMArray $PassedArray but it doesn't work if I pipe the array $PassedArray | Get-MachinesUser.

I worked with someone on my team and we figured out when we pass the array it is only processing the last entry in the array. I don't mind using the other syntax, but I am curious what error I have that causes piping not to work.

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]
            }
        }
    }
}  
like image 360
finalbroadcast Avatar asked Feb 06 '26 00:02

finalbroadcast


1 Answers

To support pipeline input you need a process block in your function:

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

This block is used to provide record-by-record processing for the function. This block might be used any number of times, depending on the input to the function. For example, if the function is the first command in the pipeline, the Process block will be used one time. If the function is not the first command in the pipeline, the Process block is used one time for every input that the function receives from the pipeline.

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

(Note: The quote has been slightly amended as SS64 incorrectly indicated that the process block is not executed where there is no pipeline input, whereas in fact it still executes a single time).

You are still correct to include a ForEach loop, as this means that you support the array input when it's passed through the parameter. However in order to process all the input when it is sent via the pipeline a Process { } block is needed.

like image 197
Mark Wragg Avatar answered Feb 09 '26 07:02

Mark Wragg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!