Powershell cmdlet的嵌套参数

时间:2014-12-13 21:03:07

标签: c# powershell

新手问题。

如何声明Powershell cmdlet的嵌套参数?我想要一个看起来像这样的cmdlet。

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

我尝试使用ParameterSetName参数将DefendersMidfielders下的参数组合在一起。但是,当我执行help New-FootballTeam DefendersMidfielders标记时,不会显示,我会看到类似的内容。

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

提前谢谢。

3 个答案:

答案 0 :(得分:3)

PowerShell不支持您所描述的参数嵌套。 PowerShell支持多个ParameterSet,允许您指定不同的&#34;集&#34;对特定命令调用有效的参数。 ParameterSets(内部AllParametersSet除外 - 其中未分配参数集的参数)是互斥的。通常,每个parameterset都有一个唯一的参数,PowerShell使用该参数来选择用于参数解析的特定参数集 - 这是互斥的位。如果PowerShell无法确定要使用哪些参数,则会发出错误。在某些情况下,您可以使用[CmdletBinding(DefaultParameterSet="<defaultParameterSetName>")]帮助PowerShell告诉PowerShell在根据提供的参数和参数找不到哪个参数时使用它们。

答案 1 :(得分:2)

有一个称为动态参数的简洁PowerShell功能,您可以使用它来解决此问题。虽然有点啰嗦:

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"
        }
    }

}

但是,此解决方案有一些注意事项 - 使用Get-Help时未列出动态参数,Intellisense有时也可以使用它们。但它确实有效,并且由于示例中的参数设置为Mandatory,当Defenders / Midfielders开关设置时,PS将提示您输入所需的Wings / Backs。 Dynamic parameters - defenders only Dynamic parameters = defenders and midfielders

答案 2 :(得分:0)

像这样定义你的参数:

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
    )

}

会给你一些你想要的东西:

NAME  
    New-FootballTeam

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

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

虽然在这个例子中我不太确定参数集或参数Defenders和Midfielders的意义。您可以准确地确定参数名称的含义。将所有位置作为参数放在一个集合中会更简单。