Powershell功能参数正确使用

时间:2018-07-06 18:41:41

标签: powershell

            PARAM (
                [parameter(Mandatory=$true)]
                [string]$Poolname,
                [array]$Ports = 443,
                [parameter(Mandatory=$true)]
                [ValidateSet("ELB","ALB")]
                $Loadbalncertype,
                [parameter(Mandatory=$true)]
                [ValidateSet("Ping","HTTPGet")]
                $HealthCheckConfigType,
                [parameter(Mandatory=$true)]
                [array]$LBSubnets,
            [parameter(Mandatory=$true)]
            [string]$SecGroupID,
            [int]$IdleTimeoutsec = 60,
            [bool]$SSLPassthrough = $false,
            string]$SSLCertificateName,
                [string]$HealthCheckPath,
            [string]$SSLPolicyName,
                [bool]$ConfigureProxyProtocol = $true
                )

在上文中,仅当$ Loadbalncertype = ELB时,我才想使用参数$ HealthCheckConfigType。我不确定如何在Powershell函数参数部分中创建此逻辑。

2 个答案:

答案 0 :(得分:3)

要专门在param定义中执行此操作,可以使用DynamicParam创建一个动态参数,但这需要大量工作,而且可能会适得其反。

如果您必须将$LoadBalancerType保留为[string],我想到的最直接的方法就是像这样使用[ValidateScript()]

param(
    [ValidateSet("ELB","ALB")]
    $LoadBalancerType ,

    [ValidateScript( { $LoadBalancerType -eq 'ELB' } )]
    [ValidateSet("Ping","HTTPGet")]
    $HealthCheckConfigType
)

这将给出糟糕的错误消息,您可以使用放置正确的throw覆盖该错误消息:

[ValidateScript( { $LoadBalancerType -eq 'ELB' -or $(throw 'A better error message') } )]

另一种选择是将$LoadBalancerType参数更改为单独的开关参数,并使用它们来定义参数集:

[CmdletBinding(DefaultParameterSet='ALB')]
param(
    [parameter(Mandatory=$true)]
    [string]$Poolname,

    [Parameter(Mandatory, ParameterSetName = 'ALB')]
    [Switch]$ALB ,

    [Parameter(Mandatory, ParameterSetName = 'ELB')]
    [Switch]$ELB ,

    [Parameter(Mandatory, ParameterSetName = 'ELB')
    [ValidateSet("Ping","HTTPGet")]
    $HealthCheckConfigType
)

这使参数解析器强制执行此限制,并且可以通过在函数上调用Get-Help在自动生成的参数集中看到它。

而且,尽管这不是通常的方法,但在您的情况下,如果使用所需值的名称来命名参数集,则可以不带条件地重新创建$LoadBalancerType

$LoadBalancerType = $PSCmdlet.ParameterSetName

(当然,假设唯一可能的参数集直接是负载均衡器名称;请谨慎操作)

但是,如果您从未真正需要该字符串值;也就是说,如果您只打算这样做:

if ($LoadBalancerType -eq 'ALB') {

} elseif ($LoadBalancerType -eq 'ELB') {

}

或类似的东西,那么您无需重新创建它,只需执行以下操作:

if ($ALB) {

} elseif ($ELB) {

}

或者,您根本不需要在param块中执行此检查;您可以在函数主体中进行操作,也可以在适当的情况下使用begin / process块。

答案 1 :(得分:2)

使用DynamicParam块:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_advanced_parameters?view=powershell-6#dynamic-parameters

我自己对他们没有很多经验,但这是该MS文档的代码示例。您可以处理并添加所需的任何参数:

  function Get-Sample {
  [CmdletBinding()]
  Param ([String]$Name, [String]$Path)

  DynamicParam
  {
    if ($path -match ".HKLM.:")
    {
      $attributes = New-Object -Type `
        System.Management.Automation.ParameterAttribute
      $attributes.ParameterSetName = "__AllParameterSets"
      $attributes.Mandatory = $false
      $attributeCollection = New-Object `
        -Type System.Collections.ObjectModel.Collection[System.Attribute]
      $attributeCollection.Add($attributes)

      $dynParam1 = New-Object -Type `
        System.Management.Automation.RuntimeDefinedParameter("dp1", [Int32],
          $attributeCollection)

      $paramDictionary = New-Object `
        -Type System.Management.Automation.RuntimeDefinedParameterDictionary
      $paramDictionary.Add("dp1", $dynParam1)
      return $paramDictionary
    }
  }
}

另一种选择是不要混用DynamicParam,并且在您的代码正文中,如果$HealthCheckConfigType不等于$LoadBalancerType,只需忽略ELB,但是如果要使用参数验证器来检查,DynamicParam是答案。