PowerShell中的函数重载

Pri*_*moz 29 parameters powershell overloading function

你能在PowerShell中重载函数吗?

我希望我的函数接受字符串,数组或某些开关.

我想要的一个例子:

  • Backup-UsersData singleUser
  • Backup-UsersData @('Alice','Bob','Joe')
  • Backup-UsersData -all

Rom*_*min 28

在PowerShell中,函数不会重载.最后一个定义会覆盖相同作用域中的上一个定义,或者隐藏父作用域中的上一个定义.因此,您应该创建一个单独的函数,并提供一种通过参数区分其调用模式的方法.

在V2中,您可以使用高级功能,查看help about_Functions_Advanced_Parameters并避免一些解决参数集歧义的手动编码:

# advanced function with 3 parameter sets
function Backup-UsersData
(
    [Parameter(Position=0, ParameterSetName="user")]
    [string]$user,
    [Parameter(Position=0, ParameterSetName="array")]
    [object[]]$array,
    [Parameter(Position=0, ParameterSetName="all")]
    [switch]$all
)
{
    # use this to get the parameter set name
    $PSCmdlet.ParameterSetName
}

# test
Backup-UsersData -user 'John'
Backup-UsersData 1, 2
Backup-UsersData -all

# OUTPUT:
# user
# array
# all
Run Code Online (Sandbox Code Playgroud)

请注意,这种机制有时很奇怪.例如,在第一个测试中,我们必须-user明确指定参数名称.除此以外:

Backup-UsersData : Parameter set cannot be resolved using the specified named parameters.
At C:\TEMP\_101015_110059\try2.ps1:21 char:17
+ Backup-UsersData <<<<  'John'
    + CategoryInfo          : InvalidArgument: (:) [Backup-UsersData], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Backup-UsersData
Run Code Online (Sandbox Code Playgroud)

在许多情况下,使用混合参数的标准而非高级函数将执行以下操作:

function Backup-UsersData
(
    [string]$user,
    [object[]]$array,
    [switch]$all
)
{
    if ($user) {'user'}
    elseif ($array) {'array'}
    elseif ($all) {'all'}
    else {'may be'}
}

Backup-UsersData -user 'John'
Backup-UsersData -array 1, 2
Backup-UsersData -all
Backup-UsersData
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,你应该解决(或接受并忽略)歧义,例如决定如果做,如果:

Backup-UsersData -user 'John' -array 1, 2 -all
Run Code Online (Sandbox Code Playgroud)


Old*_*art 6

这是罗马答案的变体,我认为它更灵活一些:

function Backup
{
    [CmdletBinding(DefaultParameterSetName='Users')]
    Param (
        [parameter(mandatory=$true, ParameterSetName='Users', position=0, ValueFromPipeline=$true)][string[]]$User,
        [parameter(mandatory=$true, ParameterSetName='AllUsers')][switch]$All
    )

    Begin
    {
        if ($All) { $User = @('User1', 'User2', 'User3') }
    }

    Process
    {
        foreach ($u in $User)
        {
            echo "Backup $u"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)