相同类型的Powershell参数集

相同类型的Powershell参数集,powershell,types,Powershell,Types,我正在尝试在powershell中编写一个函数,该函数将包含一个或两个参数 一个参数集将采用名字和姓氏 另一个需要用户名。 显然,这三个都是字符串,但我希望用户能够直接键入 Get-Info <Username> 关于如何使Powershell在命令中没有命名参数的情况下默认为正确大小写的提示 出现错误的代码示例: clear-host function Get-Info { [CmdletBinding(DefaultParameterSetName='Username'

我正在尝试在powershell中编写一个函数,该函数将包含一个或两个参数

一个参数集将采用名字和姓氏 另一个需要用户名。 显然,这三个都是字符串,但我希望用户能够直接键入

Get-Info <Username>
关于如何使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"

您可以在参数声明中使用position属性来设置参数的顺序,这意味着您不必命名参数本身,只需命名值

未指定Position关键字时,cmdlet参数必须由其名称引用


一种解决方法是使用
valuefrompippeline
以不同的方式传递仅限用户名的参数;e、 g

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"
但这不是一个很好的解决方案;特别是有更好的解决方法(即使用命名参数)

正如您所描述的,我想不出实现重载的方法;虽然我明白你为什么会认为这是可能的


更新

另一种解决方法是提供一个伪参数,然后添加逻辑以重新映射参数的值;e、 g

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"

这并不像预期的那样有效。与问题中的示例一样(谢谢@JohnLBevan!)在给出
Get Info firstname lastname
时返回一个错误,即找不到接受参数“lastname”的位置参数,因为它将“firstname”绑定到用户名参数谢谢,JohnLBevan,这并不是我想要的,但第二种选择可能必须要做。聪明的想法。
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"