如何包装 cmdlet

问题描述 投票:0回答:1

PowerShell 包含一个用于处理 cmdlet 的大型框架。但有时 cmdlet 会错过特定自定义需求所需的功能,例如在这个问题中如何用不同的颜色突出显示Select-String结果的属性?.

如何在自定义命令中正确包装 cmdlet,而不丢失任何现有功能作为参数(及其约束)和现有管道功能?

powershell parameter-passing pipeline wrapper
1个回答
0
投票

在 PowerShell 中,包装的 cmdlet 称为 Proxy-Command。尽管原始命令可能包含一组复杂的参数和复杂的管道,但创建代理命令非常容易。对于此示例,我冒昧地将

Select-String
cmdlet 作为源并将其更改为
Color-String
cmdlet。
代理命令的基础可以简单地从
CommandMetaData
类中提取:

$MetaData = [System.Management.Automation.CommandMetaData](Get-Command Select-String)
$ProxyCommand = [System.Management.Automation.ProxyCommand]::Create($MetaData)

$ProxyCommand
中的内容可能会用作新命令的模板:

1.创建一个新函数,例如:

function Color-String {

2.将代理命令的内容(
$ProxyCommand | Clip
)粘贴到你自己的函数中

这应该类似于:

[CmdletBinding(DefaultParameterSetName='File', HelpUri='https://go.microsoft.com/fwlink/?LinkID=2097119')]
param(
# ...
<#

.ForwardHelpTargetName Microsoft.PowerShell.Utility\Select-String
.ForwardHelpCategory Cmdlet

#>

3.关闭你的函数:

}

此时,如果您调用此

Color-String
模板,它将与原始
Select-String
命令的行为相同。

请注意,对于新命令,我使用名称

Color-String
(即使这不是 批准的动词),但您甚至可以考虑在此处使用相同的名称,这将推翻原始
Select-String
命令,因为您知道您仍然可以使用其完整限定名称来选择源命令:
Microsoft.PowerShell.Utility\Select-String

4.给你修改

  • 例如添加
    Color
    参数:
[ValidateNotNullOrEmpty()]
[ValidateScript( { $_ -in $PSStyle.Foreground.PSObject.Properties.Name } )]
[String]
${Color} = 'White' # "Bold"

由于原始

select-String
不存在此参数,因此在使用包装命令 (
$PSBoundParameters
) 将其作为 splatted 字典传递时,需要将其从
& $wrappedCmd @PSBoundParameters
中删除:

if ($PSBoundParameters.TryGetValue('Color', [ref]$outBuffer)) { $Null = $PSBoundParameters.Remove('Color') }
  • 而不是将新功能添加到例如进程块

在这种情况下,调用命令(

$steppablePipeline.Begin($PSCmdlet)
)显然无法弄清楚如何路由输出和错误,因此我们需要显式地将参数设置为
$True
因为我们计划将输入写入管道:

$steppablePipeline.Begin($True)

为了构建 处理块(其功能与

-Begin
 cmdlet 的 
-Process
-End
ForEach-Object
参数类似),您需要对 PowerShell pipeline 有一些了解,其中不仅仅是一种语法。要更深入地了解,您可以阅读:掌握(可步进)管道

对于此示例,

Process
需要更改为:

process
{
    try {
        $MatchInfo = $steppablePipeline.Process($_)
        $Line = $_
        -Join @(
            $Start = 0
            $MatchInfo.Matches.ForEach{
                $Line.SubString($Start, ($_.Index - $Start))
                $PSStyle.Foreground.PSObject.Properties[$Color].Value
                $_.Value
                $PSStyle.Reset
                $Start = $_.Index + $_.Length
            }
            $Line.SubString($Start)
        )
    } catch {
        throw
    }
}

把它们放在一起:

function Color-String {
[CmdletBinding(DefaultParameterSetName='File', HelpUri='https://go.microsoft.com/fwlink/?LinkID=2097119')]
param(
    [ValidateSet('Ordinal','Invariant','Current','','aa','aa-DJ','aa-ER','aa-ET','af','af-NA','af-ZA','agq','agq-CM','ak','ak-GH','am','am-ET','ar','ar-001','ar-AE','ar-BH','ar-DJ','ar-DZ','ar-EG','ar-ER','ar-IL','ar-IQ','ar-JO','ar-KM','ar-KW','ar-LB','ar-LY','ar-MA','ar-MR','ar-OM','ar-PS','ar-QA','ar-SA','ar-SD','ar-SO','ar-SS','ar-SY','ar-TD','ar-TN','ar-YE','arn','arn-CL','as','as-IN','asa','asa-TZ','ast','ast-ES','az','az-Cyrl','az-Cyrl-AZ','az-Latn','az-Latn-AZ','ba','ba-RU','bas','bas-CM','be','be-BY','bem','bem-ZM','bez','bez-TZ','bg','bg-BG','bm','bm-ML','bn','bn-BD','bn-IN','bo','bo-CN','bo-IN','br','br-FR','brx','brx-IN','bs','bs-Cyrl','bs-Cyrl-BA','bs-Latn','bs-Latn-BA','byn','byn-ER','ca','ca-AD','ca-ES','ca-ES-VALENCIA','ca-FR','ca-IT','ccp','ccp-BD','ccp-IN','ce','ce-RU','ceb','ceb-PH','cgg','cgg-UG','chr','chr-US','ckb','ckb-IQ','ckb-IR','co','co-FR','cs','cs-CZ','cu','cu-RU','cy','cy-GB','da','da-DK','da-GL','dav','dav-KE','de','de-AT','de-BE','de-CH','de-DE','de-IT','de-LI','de-LU','dje','dje-NE','dsb','dsb-DE','dua','dua-CM','dv','dv-MV','dyo','dyo-SN','dz','dz-BT','ebu','ebu-KE','ee','ee-GH','ee-TG','el','el-CY','el-GR','en','en-001','en-150','en-AE','en-AG','en-AI','en-AS','en-AT','en-AU','en-BB','en-BE','en-BI','en-BM','en-BS','en-BW','en-BZ','en-CA','en-CC','en-CH','en-CK','en-CM','en-CX','en-CY','en-DE','en-DK','en-DM','en-ER','en-FI','en-FJ','en-FK','en-FM','en-GB','en-GD','en-GG','en-GH','en-GI','en-GM','en-GU','en-GY','en-HK','en-IE','en-IL','en-IM','en-IN','en-IO','en-JE','en-JM','en-KE','en-KI','en-KN','en-KY','en-LC','en-LR','en-LS','en-MG','en-MH','en-MO','en-MP','en-MS','en-MT','en-MU','en-MW','en-MY','en-NA','en-NF','en-NG','en-NL','en-NR','en-NU','en-NZ','en-PG','en-PH','en-PK','en-PN','en-PR','en-PW','en-RW','en-SB','en-SC','en-SD','en-SE','en-SG','en-SH','en-SI','en-SL','en-SS','en-SX','en-SZ','en-TC','en-TK','en-TO','en-TT','en-TV','en-TZ','en-UG','en-UM','en-US','en-US-POSIX','en-VC','en-VG','en-VI','en-VU','en-WS','en-ZA','en-ZM','en-ZW','eo','eo-001','es','es-419','es-AR','es-BO','es-BR','es-BZ','es-CL','es-CO','es-CR','es-CU','es-DO','es-EC','es-ES','es-GQ','es-GT','es-HN','es-MX','es-NI','es-PA','es-PE','es-PH','es-PR','es-PY','es-SV','es-US','es-UY','es-VE','et','et-EE','eu','eu-ES','ewo','ewo-CM','fa','fa-AF','fa-IR','ff','ff-Latn','ff-Latn-BF','ff-Latn-CM','ff-Latn-GH','ff-Latn-GM','ff-Latn-GN','ff-Latn-GW','ff-Latn-LR','ff-Latn-MR','ff-Latn-NE','ff-Latn-NG','ff-Latn-SL','ff-Latn-SN','fi','fi-FI','fil','fil-PH','fo','fo-DK','fo-FO','fr','fr-BE','fr-BF','fr-BI','fr-BJ','fr-BL','fr-CA','fr-CD','fr-CF','fr-CG','fr-CH','fr-CI','fr-CM','fr-DJ','fr-DZ','fr-FR','fr-GA','fr-GF','fr-GN','fr-GP','fr-GQ','fr-HT','fr-KM','fr-LU','fr-MA','fr-MC','fr-MF','fr-MG','fr-ML','fr-MQ','fr-MR','fr-MU','fr-NC','fr-NE','fr-PF','fr-PM','fr-RE','fr-RW','fr-SC','fr-SN','fr-SY','fr-TD','fr-TG','fr-TN','fr-VU','fr-WF','fr-YT','fur','fur-IT','fy','fy-NL','ga','ga-IE','gd','gd-GB','gl','gl-ES','gn','gn-PY','gsw','gsw-CH','gsw-FR','gsw-LI','gu','gu-IN','guz','guz-KE','gv','gv-IM','ha','ha-GH','ha-NE','ha-NG','haw','haw-US','he','he-IL','hi','hi-IN','hr','hr-BA','hr-HR','hsb','hsb-DE','hu','hu-HU','hy','hy-AM','ia','ia-001','id','id-ID','ig','ig-NG','ii','ii-CN','is','is-IS','it','it-CH','it-IT','it-SM','it-VA','iu','iu-CA','iu-Latn','iu-Latn-CA','ja','ja-JP','jgo','jgo-CM','jmc','jmc-TZ','jv','jv-ID','ka','ka-GE','kab','kab-DZ','kam','kam-KE','kde','kde-TZ','kea','kea-CV','khq','khq-ML','ki','ki-KE','kk','kk-KZ','kkj','kkj-CM','kl','kl-GL','kln','kln-KE','km','km-KH','kn','kn-IN','ko','ko-KP','ko-KR','kok','kok-IN','ks','ks-IN','ksb','ksb-TZ','ksf','ksf-CM','ksh','ksh-DE','kw','kw-GB','ky','ky-KG','lag','lag-TZ','lb','lb-LU','lg','lg-UG','lkt','lkt-US','ln','ln-AO','ln-CD','ln-CF','ln-CG','lo','lo-LA','lrc','lrc-IQ','lrc-IR','lt','lt-LT','lu','lu-CD','luo','luo-KE','luy','luy-KE','lv','lv-LV','mas','mas-KE','mas-TZ','mer','mer-KE','mfe','mfe-MU','mg','mg-MG','mgh','mgh-MZ','mgo','mgo-CM','mi','mi-NZ','mk','mk-MK','ml','ml-IN','mn','mn-MN','mn-Mong','mn-Mong-CN','mn-Mong-MN','moh','moh-CA','mr','mr-IN','ms','ms-BN','ms-MY','ms-SG','mt','mt-MT','mua','mua-CM','my','my-MM','mzn','mzn-IR','naq','naq-NA','nb','nb-NO','nb-SJ','nd','nd-ZW','nds','nds-DE','nds-NL','ne','ne-IN','ne-NP','nl','nl-AW','nl-BE','nl-BQ','nl-CW','nl-NL','nl-SR','nl-SX','nmg','nmg-CM','nn','nn-NO','nnh','nnh-CM','nqo','nqo-GN','nr','nr-ZA','nso','nso-ZA','nus','nus-SS','nyn','nyn-UG','oc','oc-FR','om','om-ET','om-KE','or','or-IN','os','os-GE','os-RU','pa','pa-Arab','pa-Arab-PK','pa-Guru','pa-Guru-IN','pl','pl-PL','prg','prg-001','ps','ps-AF','ps-PK','pt','pt-AO','pt-BR','pt-CH','pt-CV','pt-GQ','pt-GW','pt-LU','pt-MO','pt-MZ','pt-PT','pt-ST','pt-TL','qu','qu-BO','qu-EC','qu-PE','quc','quc-GT','rm','rm-CH','rn','rn-BI','ro','ro-MD','ro-RO','rof','rof-TZ','ru','ru-BY','ru-KG','ru-KZ','ru-MD','ru-RU','ru-UA','rw','rw-RW','rwk','rwk-TZ','sa','sa-IN','sah','sah-RU','saq','saq-KE','sbp','sbp-TZ','sd','sd-PK','se','se-FI','se-NO','se-SE','seh','seh-MZ','ses','ses-ML','sg','sg-CF','shi','shi-Latn','shi-Latn-MA','shi-Tfng','shi-Tfng-MA','si','si-LK','sk','sk-SK','sl','sl-SI','sma','sma-NO','sma-SE','smj','smj-NO','smj-SE','smn','smn-FI','sms','sms-FI','sn','sn-ZW','so','so-DJ','so-ET','so-KE','so-SO','sq','sq-AL','sq-MK','sq-XK','sr','sr-Cyrl','sr-Cyrl-BA','sr-Cyrl-ME','sr-Cyrl-RS','sr-Cyrl-XK','sr-Latn','sr-Latn-BA','sr-Latn-ME','sr-Latn-RS','sr-Latn-XK','ss','ss-SZ','ss-ZA','ssy','ssy-ER','st','st-LS','st-ZA','sv','sv-AX','sv-FI','sv-SE','sw','sw-CD','sw-KE','sw-TZ','sw-UG','syr','syr-SY','ta','ta-IN','ta-LK','ta-MY','ta-SG','te','te-IN','teo','teo-KE','teo-UG','tg','tg-TJ','th','th-TH','ti','ti-ER','ti-ET','tig','tig-ER','tk','tk-TM','tn','tn-BW','tn-ZA','to','to-TO','tr','tr-CY','tr-TR','ts','ts-ZA','tt','tt-RU','twq','twq-NE','tzm','tzm-MA','ug','ug-CN','uk','uk-UA','ur','ur-IN','ur-PK','uz','uz-Arab','uz-Arab-AF','uz-Cyrl','uz-Cyrl-UZ','uz-Latn','uz-Latn-UZ','vai','vai-Latn','vai-Latn-LR','vai-Vaii','vai-Vaii-LR','ve','ve-ZA','vi','vi-VN','vo','vo-001','vun','vun-TZ','wae','wae-CH','wal','wal-ET','wo','wo-SN','xh','xh-ZA','xog','xog-UG','yav','yav-CM','yi','yi-001','yo','yo-BJ','yo-NG','zgh','zgh-MA','zh','zh-Hans','zh-Hans-CN','zh-Hans-HK','zh-Hans-MO','zh-Hans-SG','zh-Hant','zh-Hant-HK','zh-Hant-MO','zh-Hant-TW','zu','zu-ZA')]
    [ValidateNotNull()]
    [string]
    ${Culture},

    [Parameter(ParameterSetName='Object', Mandatory=$true, ValueFromPipeline=$true)]
    [Parameter(ParameterSetName='ObjectRaw', Mandatory=$true, ValueFromPipeline=$true)]
    [AllowNull()]
    [AllowEmptyString()]
    [psobject]
    ${InputObject},

    [Parameter(Mandatory=$true, Position=0)]
    [string[]]
    ${Pattern},

    [Parameter(ParameterSetName='File', Mandatory=$true, Position=1, ValueFromPipelineByPropertyName=$true)]
    [Parameter(ParameterSetName='FileRaw', Mandatory=$true, Position=1, ValueFromPipelineByPropertyName=$true)]
    [string[]]
    ${Path},

    [Parameter(ParameterSetName='LiteralFile', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
    [Parameter(ParameterSetName='LiteralFileRaw', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
    [Alias('PSPath','LP')]
    [string[]]
    ${LiteralPath},

    [Parameter(ParameterSetName='ObjectRaw', Mandatory=$true)]
    [Parameter(ParameterSetName='FileRaw', Mandatory=$true)]
    [Parameter(ParameterSetName='LiteralFileRaw', Mandatory=$true)]
    [switch]
    ${Raw},

    [switch]
    ${SimpleMatch},

    [switch]
    ${CaseSensitive},

    [Parameter(ParameterSetName='Object')]
    [Parameter(ParameterSetName='File')]
    [Parameter(ParameterSetName='LiteralFile')]
    [switch]
    ${Quiet},

    [switch]
    ${List},

    [switch]
    ${NoEmphasis},

    [ValidateNotNullOrEmpty()]
    [string[]]
    ${Include},

    [ValidateNotNullOrEmpty()]
    [string[]]
    ${Exclude},

    [switch]
    ${NotMatch},

    [switch]
    ${AllMatches},

    [ValidateNotNullOrEmpty()]
    [System.Text.Encoding]
    ${Encoding},

    [ValidateNotNullOrEmpty()]
    [ValidateCount(1, 2)]
    [ValidateRange(0, 2147483647)]
    [int[]]
    ${Context},

    [ValidateNotNullOrEmpty()]
    [ValidateScript( { $_ -in $PSStyle.Foreground.PSObject.Properties.Name } )]
    [String]
    ${Color} = 'White'
)

begin
{
    try {
        $outBuffer = $null
        if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) { $PSBoundParameters['OutBuffer'] = 1 }
        if ($PSBoundParameters.TryGetValue('Color', [ref]$outBuffer)) { $Null = $PSBoundParameters.Remove('Color') }

        $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Utility\Select-String', [System.Management.Automation.CommandTypes]::Cmdlet)
        $scriptCmd = {& $wrappedCmd @PSBoundParameters }

        $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
        $steppablePipeline.Begin($True)
    } catch {
        throw
    }
}

process
{
    try {
        $MatchInfo = $steppablePipeline.Process($_)
        $Line = $_
        -Join @(
            $Start = 0
            $MatchInfo.Matches.ForEach{
                $Line.SubString($Start, ($_.Index - $Start))
                $PSStyle.Foreground.PSObject.Properties[$Color].Value
                $_.Value
                $PSStyle.Reset
                $Start = $_.Index + $_.Length
            }
            $Line.SubString($Start)
        )
    } catch {
        throw
    }
}

end
{
    try {
        $steppablePipeline.End()
    } catch {
        throw
    }
}

clean
{
    if ($null -ne $steppablePipeline) {
        $steppablePipeline.Clean()
    }
}
<#

.ForwardHelpTargetName Microsoft.PowerShell.Utility\Select-String
.ForwardHelpCategory Cmdlet

#>

}

使用示例:

'I have a blue house',
'With a blue window',
'Blue is the colour of all that I wear',
'Blue are the streets',
'And all the trees are too',
'I have a girlfriend and she is so blue' |
    Color-String 'Blue' -AllMatches -Color Blue

结果:

© www.soinside.com 2019 - 2024. All rights reserved.