Условные параметры PowerShell

Есть ли способ сделать некоторые параметры обязательными на основе какого-либо условия (например, если один из параметров отсутствует или неверен) в функции PowerShell?

Моя идея состоит в том, чтобы иметь возможность вызывать функцию двумя способами. Конкретным примером является функция, которая получает список из SharePoint - я должен иметь возможность вызывать его со списком относительных URL-адресов (один-единственный параметр) ИЛИ с веб-URL и отображаемым именем списка (два параметра, оба обязательных, но только если список относительных URL не используется).

Ответ 1

Как указал Кристиан, это можно сделать через 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")] ошибка привязки, если вы не добавите [CmdletBinding(DefaultParameterSetName="set1")] к параметру Спасибо. @x0n за подсказку DefaultParameterSetName!)

Если вы попытаетесь запустить его со значением параметра из обоих наборов, вы получите ошибку.

Если вы запустите его с -WebUrl Bar вам будет предложено -WebUrl Bar значение параметра для DisplayName, потому что это обязательный параметр.

Ответ 2

Существует гораздо более мощный параметр, называемый динамическими параметрами, который позволяет динамически добавлять параметры в зависимости от значения других параметров или любого другого условия.

Вы должны структурировать свой скрипт другим способом, объявив обычные параметры как обычно, и включив в себя блок 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 чтобы создавать различные параметры, зависящие от чего-либо, например, от других значений параметров. Динамические параметры могут иметь любое имя, тип (string, int, bool, object...) и атрибуты (обязательно, position, validate set...), и они создаются перед выполнением сценария, так что вы получаете параметр Завершение вкладки (IntelliSense) в любой среде, которая его поддерживает, например в консоли PowerShell, PowerShell ISE или редакторе кода Visual Studio.

Типичным примером может быть создание другого набора динамических параметров в зависимости от значения обычного параметра с помощью простого if в разделе DynamicParam.

Google "PowerShell динамические параметры" для получения дополнительной информации, например, отображение справки для динамических параметров. Например:

Ответ 3

Вам нужно использовать параметры набора имен.

Вы можете назначить эксклюзивный параметр для другого имени набора параметров.