条件 PowerShell 参数

Posted

技术标签:

【中文标题】条件 PowerShell 参数【英文标题】:Conditional PowerShell parameters 【发布时间】:2012-05-31 17:09:56 【问题描述】:

有没有办法在 PowerShell 函数中根据某些条件(例如,如果其中一个参数不存在或为假)强制要求某些参数?

我的想法是能够以两种方式调用函数。一个具体的例子是一个从 SharePoint 获取列表的函数 - 我应该能够使用列表的相对 URL(一个也是唯一的参数)或使用 Web URL 和列表显示名称(两个参数,都是必需的,但是仅当不使用列表相对 URL 时)。

【问题讨论】:

【参考方案1】:

还有一个更强大的选项,称为动态参数,它允许根据其他参数的值或任何其他条件动态添加参数。

您必须以不同的方式构建脚本,像往常一样声明常规参数,并包括一个 DynamicParam 块来创建动态参数,一个 Begin 块来使用动态参数初始化变量,以及一个 Process使用脚本运行的代码块,可以使用常规参数,以及在Begin 中初始化的变量。它看起来像这样:

param( 
  # Regular parameters here
)

DynamicParam 
  # Create a parameter dictionary
  $runtimeParams = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

  # Populate it with parameters, with optional attributes
  # For example a parameter with mandatory and pattern validation
  $attribs = New-Object  System.Collections.ObjectModel.Collection[System.Attribute]

  $mandatoryAttrib = New-Object System.Management.Automation.ParameterAttribute
  $mandatoryAttrib.Mandatory = $true
  $attribs.Add($mandatory)

  $patternAttrib = New-Object System.Management.Automation.ValidatePatternAttribute('your pattern here')
  $attribs.Add($patternAttrib)

  # Create the parameter itself with desired name and type and attribs
  $param = New-Object System.Management.Automation.RuntimeDefinedParameter('ParameterName', String, $attribs)

  # Add it to the dictionary
  $runtimeParams.Add('ParameterName', $param)

  # Return the dictionary
  $ruintimeParams


Begin 
  # If desired, move dynamic parameter values to variables
  $ParameterName = $PSBoundParameters['ParameterName']


Process 
  # Implement the script itself, which can use both regular an dynamic parameters

当然,有趣的部分是您可以在DynamicParam 部分和Begin 部分添加条件,以根据任何内容创建不同的参数,例如其他参数值。动态参数可以具有任何名称、类型(字符串、整数、布尔值、对象...)和属性(强制、位置、验证集...),并且它们是在脚本执行之前创建的,以便您获取参数任何支持它的环境中的选项卡完成 (IntelliSense),例如 PowerShell 控制台、PowerShell ISE 或 Visual Studio Code 编辑器。

一个典型的例子是根据常规参数的值创建一组不同的动态参数,方法是在DynamicParam 部分中使用简单的if

谷歌“PowerShell 动态参数”以获取更多信息,例如显示动态参数的帮助。例如:

PowerShell Magazine Dynamic Parameters in PowerShell

【讨论】:

感谢您的回答。尽管最初的答案确实是我所需要的,但这绝对是解决问题的非常有趣的方式,我可以在一些复杂的情况下看到它的威力。另外,我想说这个选项被忽视了,因此不太为人所知。再次感谢分享。【参考方案2】:

您需要使用parameters set naming。

您可以将独占参数分配给不同的参数集名称。

【讨论】:

你能给我一个小例子,我怎样才能完成我写的东西? 阅读这里blogs.technet.com/b/heyscriptingguy/archive/2011/06/30/…我现在太忙了,没有时间写一个例子,但是链接给出了一个很好的解释。 cmets 中的代码看起来很糟糕...但是:param ( [Parameter(ParameterSetName = 'rel', Mandatory = $true)][string]$RelativeUrl, [Parameter(ParameterSetName = 'web', Mandatory = $true)][string]$WebUrl, [Parameter(ParameterSetName = 'web', Mandatory = $true)][string]$DisplayName ) 现在你必须设置参数sets,每个参数一个设想。参数可以转到多个集合或所有集合(如果未指定 parameterSetName)。更多关于_Functions_Advanced_Parameters的帮助 链接(实际上)已损坏。它重定向到一个非特定页面,https://docs.microsoft.com/en-us/powershell/developer/windows-powershell【参考方案3】:

正如 Christian 所指出的,这可以通过 ParameterSetNames 来完成。看看这个例子:

function Get-MySPWeb 
    [CmdletBinding(DefaultParameterSetName="set1")]
    param (
        [parameter(ParameterSetName="set1")] $RelativeUrl,
        [parameter(ParameterSetName="set2")] $WebUrl,
        [parameter(ParameterSetName="set2", Mandatory=$true)] $DisplayName
    )
    Write-Host ("Parameter set in action: " + $PSCmdlet.ParameterSetName)
    Write-Host ("RelativeUrl: " + $RelativeUrl)
    Write-Host ("WebUrl: " + $WebUrl)
    Write-Host ("DisplayName: " + $DisplayName)

如果您使用-RelativeUrl Foo 运行它,它将绑定到“set1”。如果你在没有任何参数的情况下调用这个函数,它也会绑定到“set1”。

(注意 - 当 PowerShell v3(带有 Windows 8 消费者预览版)中未提供参数时,它将绑定到“set1”,但除非您添加,否则它将在 PowerShell v2 中绑定错误[CmdletBinding(DefaultParameterSetName="set1")] 到参数块。感谢 @x0n 提供 DefaultParameterSetName 提示!)

如果您尝试使用两个集合中的参数值运行它,您将收到错误。

如果您使用-WebUrl Bar 运行它,它会提示您输入 DisplayName 的参数值,因为它是强制性参数。

【讨论】:

这正是我需要的!谢谢!只有一件事:当我在没有参数的情况下运行它时,我得到一个错误(但我想要这样)。一个后续问题:在使用参数集时,它打算将 switch 与 $PSCmdlet.ParameterSetName 变量一起使用,对吧? 对,$PSCmdlet.ParameterSetName 在那里,因此您可以根据参数绑定过程评估的参数集采取适当的行动。顺便说一句,有趣的是您遇到了错误,这似乎是 PSv2 和 PSv3 之间的行为差​​异。 让它像 v3 一样工作的诀窍是使用默认参数集指令。我已经编辑了您的答案以显示这一点。 如果您将 Cmdlet 构建为 .NET 程序集,则 DefaultParameterSetName 必须进入 [Cmdlet()] 属性 - 如果添加单独的 [CmdletBinding()] 属性,它将不起作用

以上是关于条件 PowerShell 参数的主要内容,如果未能解决你的问题,请参考以下文章

(24)Poweshell中的if条件判断

powershell ParameterSet解析

PowerShell初级篇●Powershell条件判断

PowerShell Install Nginx

powershell 发布一个SDL Tridion页面,即PowerShell。先决条件:http://code.google.com/p/tridion-powershell-modules/和任

powershell 发布一个SDL Tridion页面,即PowerShell。先决条件:http://code.google.com/p/tridion-powershell-modules/和任