我可以确定 PowerShell 函数是否作为管道的一部分运行吗? [英] Can I determine if a PowerShell function is running as part of a pipeline?

查看:39
本文介绍了我可以确定 PowerShell 函数是否作为管道的一部分运行吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

PowerShell 函数能否确定它是否作为管道的一部分运行?我有一个函数,它用 FileInfo 的实例填充数组,如果函数以这种方式运行,我想屈服"到管道,或者如果函数被调用,则产生一些漂亮的输出自己从命令行.

Can a PowerShell function determine if it is being run as part of a pipeline? I have a function which populates an array with instances of FileInfo which I would like to "yield" to the pipeline if the function is being run this way or produce some pretty output if the function is being invoked by itself from the command line.

function Do-Something {
    $file_infos = @()
    # Populate $file_infos with FileInfo instances...

    if (INVOKED_IN_PIPELINE) {
        return $file_infos
    }
    else {
        foreach ($file_info in $file_infos) {
            write-host -foregroundcolor yellow $file_info.fullname
        }
    }
}

基本上,我想弄清楚如何实现INVOKED_IN_PIPELINE.如果它在管道中运行(例如 Do-Something | format-table fullname),我会简单地产生数组,但如果直接运行(例如 Do-Something),它会将数组的内容漂亮地打印到控制台.

Basically, I'm trying to figure out how to implement INVOKED_IN_PIPELINE. If it is run in a pipeline (e.g. Do-Something | format-table fullname), I would simply yield the array, but if run directly (e.g. Do-Something), it would pretty-print the contents of the array to the console.

有没有办法做到这一点?如果有更惯用"的方式来实现这种事情,我也有兴趣知道.

Is there a way to do this? If there is a more "idiomatic" way to achieve this kind of thing, I would also be interested to know.

推荐答案

此信息作为 $PSCmdlet.MyInvocation 的一部分提供.下面是一个 cmdlet,您可以用来对此进行试验.为任何命令执行一次写出该属性的内容,然后传递对象(因此您可以使用更大的管道对对象进行更多操作)是做什么的.您将看到有一个名为 PipelineLength 的属性,当您单独运行此命令时,该属性等于 1,并为管道中的每个项目增加.还要注意PipelinePosition.它告诉你这个命令在管道中的位置.

This information is available as part of $PSCmdlet.MyInvocation. Here is a cmdlet you can use to experiment with this. What it does it to write out the contents of that property once for any command execution and then passes on the object (so you can manipulate the objects some more with bigger pipelines). What you'll see is that there is a property called PipelineLength which is equal to 1 when you run this command by itself and increases for each item in the pipeline. Also notice PipelinePosition. It tells you what position this command is in the pipeline.

注意: $PSCmdlet 仅在您编写高级函数(例如具有 [CmdletBinding()] 属性)时可用.>

NOTE: $PSCmdlet is only available when you write an advanced function (e.g. have the [CmdletBinding()] attribute.

function test-PSCmdlet
{
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$true)]
$test
)
Begin{
    $once = $false
    }
process
    {
        if (!$once)
        {
            write-host ($PSCmdlet.MyInvocation |out-string)
            $once = $true
        }
        Write-Output $_
    }
}

以下是一些示例:

PS C:\Users\jsnover.NTDEV> test-PSCmdlet

MyCommand        : test-PSCmdlet
BoundParameters  : {}
UnboundArguments : {}
ScriptLineNumber : 1
OffsetInLine     : 14
HistoryId        : 61
ScriptName       : 
Line             : test-PSCmdlet
PositionMessage  : 
                   At line:1 char:14
                   + test-PSCmdlet <<<< 
InvocationName   : test-PSCmdlet
PipelineLength   : 1
PipelinePosition : 1
ExpectingInput   : False
CommandOrigin    : Runspace


PS C:\Users\jsnover.NTDEV> gps lsass | test-PSCmdlet |Format-table Name,Id -auto

MyCommand        : test-PSCmdlet
BoundParameters  : {[test, System.Diagnostics.Process (lsass)]}
UnboundArguments : {}
ScriptLineNumber : 1
OffsetInLine     : 26
HistoryId        : 62
ScriptName       : 
Line             : gps lsass | test-PSCmdlet |Format-table Name,Id -auto
PositionMessage  : 
                   At line:1 char:26
                   + gps lsass | test-PSCmdlet <<<<  |Format-table Name,Id -aut
                   o
InvocationName   : test-PSCmdlet
PipelineLength   : 3
PipelinePosition : 2
ExpectingInput   : True
CommandOrigin    : Runspace


Name   Id
----   --
lsass 620

这篇关于我可以确定 PowerShell 函数是否作为管道的一部分运行吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆