在Powershell高级功能中,如何检测BEGIN块中的管道输入?

时间:2014-03-27 12:04:47

标签: function powershell pipeline

我有一个高级功能

function Start-Executable {
    [CmdletBinding()]
    Param (
        [String]$Arg1,
        [String[]]$Arg2,
        [Parameter(ValueFromPipeline=$true)][String[]]$PipeValue
    )

Begin {
    # Setup code
}
Process {
    # What goes on here?
    foreach ($val in $PipeValue) {
        # Process val here
    }
}
End {
}
}

在我的设置代码中,我需要做一些不同的操作,具体取决于用户是否提供了管道输入。但我不知道如何在我的BEGIN块中判断是否存在管道输入。有什么我可以检查的吗?

我尝试的另一件事是在$PipeValue循环之前将设置代码放在PROCESS块中,但这不起作用,因为看起来每个管道值都调用一次PROCESS块, $PipeValue每次都是一个项目的数组。是对的吗?如果为每个值重复调用PROCESS,为什么在PROCESS块中需要另一个循环?

更新

为了澄清,我要做的是在BEGIN中创建一个进程,在PROCESS中输入它并在END中读取输出。为此,我需要将RedirectStandardInput设置为$true,如果有管道输入,则不然。

作为解决方法,我可以让用户指定一个额外的参数(如果他们弄错了,事情就行不通)或者我可以在BEGIN中设置一个$first_time标志,然后创建进程第一次调用PROCESS。如果我在没有创建过程的情况下进入END,我会使用RedirectStandardInput创建$false。这比我喜欢的代码重复更多,但如果它是唯一的选择,我可能必须这样做。

3 个答案:

答案 0 :(得分:3)

Begin块在管道启动之前运行,因此该代码无法知道管道中的内容。

至于在Process块中需要另一个循环,如果函数需要接受任何$ PipeValue作为管道输入或作为参数传递,则必须具有该循环。如果它只是接受它作为管道数据,那么就没有必要为它提供参数。只需在进程块中使用$ _。

答案 1 :(得分:3)

$MyInvocation.ExpectingInput如果通过管道输入调用该函数,则返回true,否则返回false。

这在beginprocessend块中有效。它不适用于dynamicparam in PowerShell 5.1 or lower

答案 2 :(得分:2)

function Start-Executable {
    [CmdletBinding()]
    Param (
        [String]$Arg1,
        [String[]]$Arg2,
        [Parameter(ValueFromPipeline=$true, parametersetname="nopipeline")][String[]]$PipeValue
    )

Begin {
    # Setup code
    if($PSCmdlet.ParameterSetName -eq "nopipeline")
    {
        Write-Host "No pipeline input"
    }
    else
    {
        Write-Host "Pipeline input"
    }
}
Process {
    $PipeValue
}
End {
}
}

这似乎可以解决问题 基本上,参数被分配给参数集 如果使用该参数,则$pscmdlet.ParameterSetName包含"nopipeline" 如果使用管道,则$pscmdlet.ParameterSetName包含"__AllParameterSets"

示例输出:

PS H:\> @("a","b","c") | Start-Executable
Pipeline input
a
b
c

PS H:\> Start-Executable -PipeValue @("a","b","c")
No pipeline input
a
b
c

编辑:请注意,这不会告诉您管道输入。它将告诉您是否使用了命名参数。 换句话说,这种情况发生了:

PS H:\> Start-Executable
Pipeline input