2016-01-06 2 views
2

Я пытаюсь написать функцию в powershell, которая примет один или два аргумента.Наборы параметров Powershell того же типа

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

Get-Info <Username> 

или

без названия параметров. НО, если они НАЗНАЧИЛИ параметры, они могли бы потенциально поставить только имя FirstName или только LastName, что было бы хорошо. , например.

Get-Info -FirstName John 
Get-Info -LastName Doe 

Любые советы о том, как получить Powershell по умолчанию в правильном случае без именованных параметров в команде?

Пример кода с ошибкой:

clear-host 
function Get-Info { 
    [CmdletBinding(DefaultParameterSetName='Username',PositionalBinding=$true)] 
    param (
     [Parameter(ParameterSetName='Username', Position=0)] 
     [string]$Username 
     , 
     [Parameter(ParameterSetName='Name', Position=0)] 
     [string]$FirstName 
     , 
     [Parameter(ParameterSetName='Name', Position=1)] 
     [string]$LastName 
    ) 
    process { 
     "Username: $Username" 
     "FirstName: $FirstName" 
     "LastName: $LastName" 
    } 
} 

Get-Info "myUsername" 
Get-Info "myFirst" "myLast" #this doesn't work, as myFirst is bound to Username, and the Username parameterset has no second parameter 
Get-Info -Username "Username by Param Name" 
Get-Info -FirstName "FirstOnly" 
Get-Info -LastName "LastOnly" 

ответ

0

Вы можете использовать атрибут позиции в вашем объявлении параметра, чтобы установить порядок параметров, которые означают, вы не должны называть параметры по себе, просто ценности.

«Если ключевое слово Position не указано, для параметра cmdlet должно быть указано его имя».

https://technet.microsoft.com/en-us/library/ms714348(v=vs.85).aspx

+0

Это не работает так, как ожидалось. Как с примером в вопросе (Спасибо @JohnLBevan!) При предоставлении 'Get-Info firstname lastname' возвращается ошибка, которая не может быть найдена с помощью позиционного параметра _A, который принимает аргумент 'lastname'_ , потому что это привязка' firstname 'к Username parameter –

2

Обходной будет использовать ValueFromPipeline, чтобы передавать имя пользователя параметр только по-другому; например

clear-host 
function Get-Info { 
    [CmdletBinding(DefaultParameterSetName='Username',PositionalBinding=$true)] 
    param (
     [Parameter(ParameterSetName='Username', ValueFromPipeline=$true)] 
     [string]$Username 
     , 
     [Parameter(ParameterSetName='Name', Position=0)] 
     [string]$FirstName 
     , 
     [Parameter(ParameterSetName='Name', Position=1)] 
     [string]$LastName 
    ) 
    process { 
     "Username: $Username" 
     "FirstName: $FirstName" 
     "LastName: $LastName" 
    } 
} 

"myUsername" | Get-Info 
Get-Info "myFirst" "myLast" | write-host -ForegroundColor Cyan 
Get-Info -Username "Username by Param Name" 
Get-Info -FirstName "FirstOnly" | write-host -ForegroundColor Cyan 
Get-Info -LastName "LastOnly" 

Не отличное решение; тем более, что есть лучшее обходное решение (например, использование именованных параметров).

Я не мог понять, как реализовать перегрузку, как вы описали; хотя я понимаю, почему вы ожидаете, что это станет возможным.


Обновление

Другое решение состоит в создании фиктивного параметра, а затем добавить логику переназначить значения параметра в; например

clear-host 
function Get-Info { 
    [CmdletBinding(DefaultParameterSetName='Username',PositionalBinding=$true)] 
    param (
     [Parameter(ParameterSetName='Username', Position=0)] 
     [string]$Username 
     , 
     [Parameter(ParameterSetName='Username', Position=1)] 
     [string]$Hack = $null 
     , 
     [Parameter(ParameterSetName='Name', Position=0)] 
     [string]$FirstName 
     , 
     [Parameter(ParameterSetName='Name', Position=1)] 
     [string]$LastName 
    ) 
    begin { 
     if (($PSCmdlet.ParameterSetName -eq 'Username') -and (-not [String]::IsNullOrEmpty($Hack))) { 
      $PSCmdlet_ParameterSetName = 'Name' #since we can't assign to $PSCmdlet.ParameterSetName we may want a local variable to say which parameter set we're using 
      $FirstName = $Username 
      $LastName = $Hack 
      $Username = $null 
      $Hack = $null 
     } else { 
      $PSCmdlet_ParameterSetName = $PSCmdlet.ParameterSetName 
     } 
    } 
    process { 
     "Username: $Username" 
     "FirstName: $FirstName" 
     "LastName: $LastName" 
    } 
} 

Get-Info "myUsername" 
Get-Info "myFirst" "myLast" | write-host -ForegroundColor Cyan 
Get-Info -Username "Username by Param Name" 
Get-Info -FirstName "FirstOnly" | write-host -ForegroundColor Cyan 
Get-Info -LastName "LastOnly" 
+1

Спасибо, JohnLBevan, это было не совсем то, что я искал, но этот второй вариант, вероятно, придется сделать. Умное мышление. –

Смежные вопросы