Pipe complete array-objects instead of array items one at a time?

后端 未结 4 1053
北海茫月
北海茫月 2020-12-14 00:45

How do you send the output from one CmdLet to the next one in a pipeline as a complete array-object instead of the individual items in the array one at a time?

4条回答
  •  醉酒成梦
    2020-12-14 01:14

    There's an old-school solution, if you don't mind that your process is a function.

    Example: You want an array copied to the clipboard in a way that allows you to build it again on another system without any PSRemoting connectivity. So you want an array containing "A", "B", and "C" to transmute to a string: @("A","B","C") ...instead of a literal array.

    So you build this (which isn't optimal for other reasons, but stay on topic):

    # Serialize-List
    
    param 
    (
        [Parameter(Mandatory, ValueFromPipeline)]
        [string[]]$list
    )
        $output = "@(";
    
        foreach ($element in $list)
        {
            $output += "`"$element`","
        }
    
        $output = $output.Substring(0, $output.Length - 1)
        $output += ")"
        $output
    

    and it works when you specify the array as a parameter directly:

    Serialize-List $list

    @("A","B","C")

    ...but not so much when you pass it through the pipeline:

    $list | Serialize-List

    @("C")

    But refactor your function with begin, process, and end blocks:

    # Serialize-List
    
    param 
    (
        [Parameter(Mandatory, ValueFromPipeline)]
        [string[]]$list
    )
    
    begin
    {
        $output = "@(";
    }
    
    process
    {
        foreach ($element in $list)
        {
            $output += "`"$element`","
        }
    }
    
    end
    {
        $output = $output.Substring(0, $output.Length - 1)
        $output += ")"
        $output
    }
    

    ...and you get the desired output both ways.

    Serialize-List $list

    @("A","B","C")

    $list | Serialize-List

    @("A","B","C")

提交回复
热议问题