powershell 是否可以为默认的commandlet设置参数位置?

7d7tgy0s  于 2023-02-23  发布在  Shell
关注(0)|答案(1)|浏览(141)

例如,我希望Select-Object commandlet将Get-ChildItem|Select-Object 1解释为Get-ChildItem|Select-Object -First 1
对于我最常用的commandlet,我一直在使用这样的" Package 器":

function Select-Object{
    [CMDletbinding()]
    param (
        [Parameter(ValueFromPipeline)]
        $InputObect, 
        [Parameter(Position = 1)]
        [int]$First,
        [Parameter(Position = 2)]
        [int]$Last
    )
    $input | Select-Object -First $First -Last $Last
}

但是有时会有bug,我总是重新编写它来添加更多的参数。
我一直在阅读文档,没有发现任何其他参数拼接。
这不一定是一个官方的解决方案,所以如果有人想出了解决方案,我想知道。
PS:我知道这会导致代码混乱,但是我打算只在交互式\终端会话中使用它。使用gci | sel 1Get-ChildItem | Select-Object -First 1要好得多
任何帮助将不胜感激!

vhmi4jdf

vhmi4jdf1#

对于这样的 Package 器,你应该使用ProxyCommand,下面的大部分代码可以通过.Create(..)方法自动生成:

[System.Management.Automation.ProxyCommand]::Create((Get-Command Select-Object))

除了pipeline参数之外,仅使用您感兴趣的-First-Last这两个参数,函数将如下所示:

function sel {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        [object] $InputObject,

        [Parameter(Position = 1)]
        [int] $First,

        [Parameter(Position = 2)]
        [int] $Last
    )

    begin {
        $wrapper  = { Microsoft.PowerShell.Utility\Select-Object @PSBoundParameters }
        $pipeline = $wrapper.GetSteppablePipeline($MyInvocation.CommandOrigin)
        $pipeline.Begin($PSCmdlet)
    }
    process {
        $pipeline.Process($InputObject)
    }
    end {
        $pipeline.End()
    }
}

现在,您可以使用位置绑定而不会出现问题:

0..10 | sel 1   # for `-First 1`
0..10 | sel 1 1 # for `-First 1` `-Last 1`

至于 parameter splicing,你可能指的是powershell中的 Splatting。你可以查看about Splatting。作为一个例子,上面的代码使用了自动变量$PSBoundParameters的splatting。

相关问题