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