Объединение наборов параметров - PullRequest
1 голос
/ 08 ноября 2019

Это в некоторой степени связано с вопросом, который я задавал ранее; Групповой параметр (установлен?), Требующий один из параметров

У меня есть набор из 5 параметров;Годы, месяцы, дни, путь, ввод. Я хочу объединить наборы параметров, чтобы у меня могли быть следующие комбинации:

Годы & (Путь или Вход)
Месяцы & (Путь или Вход)
Дни & (Путь или Вход)

Путь - это типизированный путь, а Input - указатель на файл, в любом случае требуется один из них.

Я пробовал

    [Parameter(Mandatory = $true, ParameterSetName = 'Path')]
    [Parameter(Mandatory = $true, ParameterSetName = 'Input')
    [int]$Years = '7'

Но путь& Ввод требуется при использовании Годы

Param (
    [parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
    [string[]]$Filter = '*.*',
    [Parameter(Mandatory = $True, ParameterSetName = 'ByYears')]
    [int]$Years = '7',
    [Parameter(Mandatory = $True, ParameterSetName = 'ByMonths')]
    [int]$Months,
    [Parameter(Mandatory = $True, ParameterSetName = 'ByDay')]
    [int]$Days,
    [Parameter(Mandatory = $true, ParameterSetName = 'Path')]
    [string[]]$Path,
    [Parameter(Mandatory = $true, ParameterSetName = 'Input')]
    [string]$Input,
    [switch]$Recurse,
    [Parameter(Mandatory = $true)]
    [string]$ReportPath = $PWD
)

В конце я хочу иметь возможность только одной из комбинаций ниже;

-Годы 2 -Путь C: \ Temp
-Годы 2 -Вход C: \ Temp \ file.txt
-Месяцы 2 -Путь C: \ Temp
-Месяцы 2 -Ввод C: \ Temp \ file.txt
-Дни 2 -Путь C: \ Temp
-Дни 2 -Вход C: \ Temp \ file.txt

Ответы [ 2 ]

2 голосов
/ 09 ноября 2019

Нет никакого способа прямого выражения ParameterA and (ParameterB or ParameterC) в ParameterSets, но вы можете создать два набора параметров: ParameterA and ParameterB и ParameterA and ParameterC, которые делают то же самое.

Если вы продлите этодля вашего сценария вам понадобится 6 наборов параметров:

  • YearsAndPath
  • YearsAndInput
  • MonthsAndPath
  • MonthsAndInput
  • DaysAndPath
  • DaysAndInput

И затем вы просто помечаете каждый параметр наборами параметров, в которых он должен использоваться, и ваш блок param становится примерно таким:

function Invoke-Params
{

    param(
        [parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
        [string[]]$Filter = '*.*',

        [Parameter(Mandatory = $True, ParameterSetName = 'YearsAndPath')]
        [Parameter(Mandatory = $True, ParameterSetName = 'YearsAndInput')]
        [int]$Years = '7',

        [Parameter(Mandatory = $True, ParameterSetName = 'MonthsAndPath')]
        [Parameter(Mandatory = $True, ParameterSetName = 'MonthsAndInput')]
        [int]$Months,

        [Parameter(Mandatory = $True, ParameterSetName = 'DaysAndPath')]
        [Parameter(Mandatory = $True, ParameterSetName = 'DaysAndInput')]
        [int]$Days,

        [Parameter(Mandatory = $true, ParameterSetName = 'YearsAndPath')]
        [Parameter(Mandatory = $true, ParameterSetName = 'MonthsAndPath')]
        [Parameter(Mandatory = $true, ParameterSetName = 'DaysAndPath')]
        [string[]]$Path,

        [Parameter(Mandatory = $true, ParameterSetName = 'YearsAndInput')]
        [Parameter(Mandatory = $true, ParameterSetName = 'MonthsAndInput')]
        [Parameter(Mandatory = $true, ParameterSetName = 'DaysAndInput')]
        [string]$Input,

        [switch]$Recurse,
        [Parameter(Mandatory = $true)]
        [string]$ReportPath = $PWD
    )

}

Следующее затем работает нормально:

PS> Invoke-Params -Years 5 -Path "xxx"
PS> Invoke-Params -Years 5 -Input "xxx"

, и они выдают исключение:

PS> Invoke-Params -Years 5
Invoke-Params : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:1
+ Invoke-Params -Years 5
+ ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Invoke-Params], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Invoke-Params

PS> Invoke-Params -Years 5 -Path "aaa" -Input "bbb"
Invoke-Params : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:1
+ Invoke-Params -Years 5 -Path "aaa" -Input "bbb"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Invoke-Params], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Invoke-Params
1 голос
/ 09 ноября 2019

Ответ mclayton является верным в том смысле, что вам придется использовать 6 имен наборов параметров.
Существует три «временных» параметра, которые должны исключать друг друга и должны использоваться вместе содин из двух параметров 'path'.

Однако не следует использовать $input в качестве параметра, поскольку это Автоматическая переменная в качестве Матиас Р. Джессен ужепрокомментировал, и поскольку вы устанавливаете параметр $Years со значением по умолчанию, Mandatory должно быть $false для этого.

Поскольку использование комбинаций наборов параметров всегда является загадкой, я бы поставилпараметры в более логичном порядке (по крайней мере для меня ..), сначала определив два параметра 'пути' и установив DefaultParameterSetName в качестве первого из них. Кроме того, добавив Position = 0 к этому первому параметру, вы можете вызывать функцию только путем, не называя его.

Просто поиграйте с функцией ниже, чтобы увидеть, какие комбинации возможны и какая функция будетиспользуйте:

function Show-Parameters {
    [CmdletBinding(DefaultParameterSetName = 'ByFolderYears')]
    param (
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ParameterSetName = 'ByFolderYears')]
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ParameterSetName = 'ByFolderMonths')]
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ParameterSetName = 'ByFolderDays')]
        [Alias('Path')]
        [string[]]$FolderPath,

        [Parameter(Mandatory = $true, ParameterSetName = 'ByFileYears')]
        [Parameter(Mandatory = $true, ParameterSetName = 'ByFileMonths')]
        [Parameter(Mandatory = $true, ParameterSetName = 'ByFileDays')]
        [Alias('File')]
        [string]$FilePath,

        [Parameter(Mandatory = $false, ParameterSetName = 'ByFolderYears')]
        [Parameter(Mandatory = $false, ParameterSetName = 'ByFileYears')]
        [int]$Years = 7,

        [Parameter(Mandatory = $true, ParameterSetName = 'ByFolderMonths')]
        [Parameter(Mandatory = $true, ParameterSetName = 'ByFileMonths')]
        [int]$Months,

        [Parameter(Mandatory = $true, ParameterSetName = 'ByFolderDays')]
        [Parameter(Mandatory = $true, ParameterSetName = 'ByFileDays')]
        [int]$Days,

        [string[]]$Filter = '*.*',
        [string]$ReportPath = $PWD,
        [switch]$Recurse
    )
    # just to show what parameter the function will use
    $paramsUsed = [ordered]@{}
    $paramSet   = $PSCmdlet.ParameterSetName

    if ($paramSet.StartsWith('ByFolder')) { $paramsUsed['FolderPath'] = $FolderPath -join '; ' }
    else {$paramsUsed['FilePath'] = $FilePath}

    if ($paramSet.EndsWith('Years')) { $paramsUsed['Years'] = $Years }
    elseif ($paramSet.EndsWith('Months')) { $paramsUsed['Months'] = $Months }
    else { $paramsUsed['Days'] = $Days }

    if ($Filter) { $paramsUsed['Filter'] = $Filter -join '; ' }
    if ($ReportPath) { $paramsUsed['ReportPath'] = $ReportPath }
    if ($Recurse) { $paramsUsed['Recurse'] = $Recurse }

    Write-Host "Using ParameterSet '$paramSet'" -ForegroundColor Cyan
    $paramsUsed
}

Например

Show-Parameters 'D:\some\path', 'Z:\some\folder'

выходы

Using ParameterSet 'ByFolderYears'

Name                           Value
----                           -----
FolderPath                     D:\some\path; Z:\some\folder
Years                          7
Filter                         *.*
ReportPath                     C:\Users\YourName

и т. д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...