如何从Powershell中的args或管道获取输入的数组参数?

Pau*_*ore 5 arrays powershell pipeline

我正在尝试编写一个带有数组参数的Powershell函数.我想用数组作为参数或管道输入来调用它.所以,调用看起来像这样:

my-function -arg 1,2,3,4
my-function 1,2,3,4
1,2,3,4 | my-function
Run Code Online (Sandbox Code Playgroud)

获得前两个很容易:

function my-function {
    param([string[]]$arg)
    $arg
}
Run Code Online (Sandbox Code Playgroud)

但是,对于管道输入,它更难.通过使用ValueFromPipeline,很容易在进程块中一次获取一个参数,但这意味着$ args变量是带有管道输入的单个值,但是如果使用-args则是一个数组.我可以在END块中使用$ input,但这根本不会得到-args输入,并且在END块中使用$ args只能从管道中获取最终项目.

我想我可以通过使用begin/process/end blocks从管道中显式收集参数值来完成此操作,如下所示:

function my-function {
    param([Parameter(ValueFromPipeline=$true)][string[]]$args)

    begin {
        $a = @()
    }
    process {
        $a += $args
    }

    end {
        # Process array here
        $a -join ':'
    }
}
Run Code Online (Sandbox Code Playgroud)

但这似乎非常混乱.对我来说这似乎也是一个相对常见的要求,所以我希望它易于实现.我错过了一种更简单的方法吗?或者如果没有,有没有办法将参数处理封装到子函数中,这样我就不必在我想要工作的每个函数中包含所有这些?

我的具体要求是我正在编写以SQL命令为输入的脚本.因为SQL可能是冗长的,所以我想允许在命令中管道(可能由另一个命令生成,或者从文件的get-contents生成),但也允许使用参数形式,以获得快速的SELECT语句.所以我从管道中获取了一系列字符串,或者作为参数.如果我得到一个数组,我只想用"n"加入它来制作一个字符串 - 逐行处理是不合适的.

我想另一个问题是,是否有一个更好的设计我的脚本,使得像这样更干净的多行输入?


谢谢 - 诀窍是不要使用ValueFromPipeline然后......

我在按照我想要的方式工作时遇到这么多麻烦的原因是在我的测试脚本中,我使用$ args作为我的参数变量的名称,忘记它是一个自动变量.所以事情很奇怪......

PS> 1,2,3,4 | ./args

PS> get-content args.ps1
param([string[]]$args)

if ($null -eq $args) { $args = @($input) }
$args -join ':'
Run Code Online (Sandbox Code Playgroud)

Doh :-)

Rom*_*min 7

使用自动变量$input.

如果只需要管道输入,那么:

function my-function {
    $arg = @($input)
    $arg
}
Run Code Online (Sandbox Code Playgroud)

但我经常使用这种组合方法(一种接受输入作为参数或通过管道输入的函数):

function my-function {
    param([string[]]$arg)

    # if $arg is $null assume data are piped
    if ($null -eq $arg) {
        $arg = @($input)
    }

    $arg
}


# test
my-function 1,2,3,4
1,2,3,4 | my-function
Run Code Online (Sandbox Code Playgroud)