简体   繁体   English

Powershell cmdlet的嵌套参数

[英]Nested parameters for Powershell cmdlet

Newbie Question. 新手问题。

How do I declare nested parameters for a Powershell cmdlet? 如何为Powershell cmdlet声明嵌套参数? I want a cmdlet that would look something like this. 我想要一个看起来像这样的cmdlet。

New-FootballTeam 
[-Defenders [[-LeftBack] <string>] [[-RightBack] <string>] ]
[-Midfielders [[-LeftWing] <string>] [[-RightWing] <string>] [[-CentreMidfield] <string>] ] 

I tried using the ParameterSetName parameter to club the parameters under Defenders and Midfielders together. 我尝试使用ParameterSetName参数将DefendersMidfielders下的参数组合在一起。 But when I do a help New-FootballTeam the Defenders and Midfielders tags don't show up and I see something like this. 但是当我为help New-FootballTeam提供help New-FootballTeamDefendersMidfielders标签没有出现,我看到了类似的东西。

New-FootballTeam 
[[-LeftBack] <string>] [[-RightBack] <string>]
[[-LeftWing] <string>] [[-RightWing] <string>] [[-CentreMidfield] <string>] 

Thanks, in advance. 提前致谢。

PowerShell does not support parameter nesting like you have described it. PowerShell不像您描述的那样支持参数嵌套。 PowerShell supports multiple ParameterSets that allow you specify different "sets" of parameters that are valid for a particular command invocation. PowerShell支持多个ParameterSet,可让您指定对特定命令调用有效的不同参数“集”。 ParameterSets (other than the internal AllParametersSet - where parameters that aren't assigned a parameterset are put) are mutually exclusive. ParameterSet(内部的AllParametersSet除外-放置未分配参数集的参数)是互斥的。 Usually each parameterset has a unique parameter that PowerShell uses to select a particular parameter set to use for parameter parsing - that's the mutually exclusive bit. 通常,每个参数集都有一个唯一的参数,PowerShell会使用该参数来选择用于参数解析的特定参数集-这是互斥的位。 If PowerShell can't determine which parameterset to use it will issue an error. 如果PowerShell无法确定要使用哪个参数集,则会发出错误。 In some cases, you can help PowerShell by using [CmdletBinding(DefaultParameterSet="<defaultParameterSetName>")] to tell PowerShell which parameterset to use when it can't figure it out based on the supplied parameters and arguments. 在某些情况下,可以通过使用[CmdletBinding(DefaultParameterSet="<defaultParameterSetName>")]告诉PowerShell,当无法根据提供的参数和参数弄清楚PowerShell使用哪个参数集时,可以帮助PowerShell。

There is a neat powershell feature called Dynamic Parameters which you can use to solve this problem. 有一个名为“动态参数”的精巧Powershell功能,可用于解决此问题。 It's a bit long-winded though: 但是有点长:

Function New-FootballTeam {
    [CmdletBinding()]
    Param(
        [Switch]$Defenders,
        [Switch]$Midfielders
    )

    DynamicParam {
        $dynamicParameters = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        $toAdd = @()

        if ($Defenders) {
            $toAdd += @('LeftBack', 'RightBack')
        }

        if ($Midfielders) {
            $toAdd += @('LeftWing', 'RightWing')
        }

        $toAdd | % {
            $attr = New-Object System.Management.Automation.ParameterAttribute
            $attr.ParameterSetName = "__AllParameterSets"
            $attr.Mandatory = $True

            $attributes = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
            $attributes.Add($attr)

            $param = New-Object System.Management.Automation.RuntimeDefinedParameter(
                $_,
                'string',
                $attributes
            )

            $dynamicParameters.Add($_, $param)
        }

        return $dynamicParameters
    }

    Begin {
        $LeftBack  = $PSBoundParameters.LeftBack
        $RightBack = $PSBoundParameters.RightBack
        $LeftWing  = $PSBoundParameters.LeftWing
        $RightWing = $PSBoundParameters.RightWing
    }

    End {
        if ($Defenders) {
            Write-Host "LeftBack : $LeftBack"
            Write-Host "RightBack: $RightBack"
        }
        if ($Midfielders) {
            Write-Host "LeftWing : $LeftWing"
            Write-Host "RightWing: $RightWing"
        }
    }

}

However, there are a few caveats with this solution - dynamic parameters are not listed when you use Get-Help, and Intellisense can sometimes play up with them too. 但是,此解决方案有一些警告-使用Get-Help时未列出动态参数,并且Intellisense有时也可以使用它们。 But it does work, and as the parameters in the example are set to Mandatory, when the Defenders/Midfielders switches are set, PS will prompt you to enter the required Wings/Backs. 但这确实有效,并且由于示例中的参数设置为“强制”,所以在设置了“后卫” /“中场”开关后,PS会提示您输入所需的“后翼”。 动态参数-仅防御者动态参数=后卫和中场

Defining your parameter like so: 像这样定义参数:

function New-FootballTeam {

    param(
    [Parameter(Mandatory = $true, ParameterSetName = "Defenders")]
    [switch]$Defenders,
    [Parameter(ParameterSetName = "Defenders", Position = 0)]
    [string]$LeftBack,
    [Parameter(ParameterSetName = "Defenders", Position = 1)]
    [string]$RightBack,
    [Parameter(Mandatory = $true, ParameterSetName = "Midfielders")]
    [switch]$Midfielders,
    [Parameter(ParameterSetName = "Midfielders", Position = 0)]
    [string]$LeftWing,
    [Parameter(ParameterSetName = "Midfielders", Position = 1)]
    [string]$RightWing,
    [Parameter(ParameterSetName = "Midfielders", Position = 2)]
    [string]$CentreMidfield
    )

}

will give you something like what you want: 会给你一些你想要的东西:

NAME  
    New-FootballTeam

SYNTAX
    New-FootballTeam [[-LeftBack] <string>] [[-RightBack] <string>] -Defenders  [<CommonParameters>]

    New-FootballTeam [[-LeftWing] <string>] [[-RightWing] <string>] [[-CentreMidfield] <string>] -Midfielders  [<CommonParameters>]

Although I'm not quite sure of the point of the parameter sets or the parameters Defenders and Midfielders in this example. 尽管在此示例中我不太确定参数集或参数Defenders和Midfielders的意义。 You can tell exactly what you mean by the parameter names. 您可以通过参数名称准确说明您的意思。 It would be simpler to just have all the positions as parameters in a single set. 将所有位置作为参数放在一个集合中会更简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM