如何在参数化函数中使用splatting?

时间:2014-06-07 00:22:32

标签: powershell parameters parameter-passing powershell-v3.0

我正在编写参数化函数并尝试使用splatting重用参数集。

$Computername='localhost'

$params = @{'computername'=$Computername;
           'credential'='administrator'}

function Get-Diskinfo {
    Param ($drive,$computername,$credential)

    Get-WmiObject win32_logicaldisk -Filter "DeviceID = '$drive'" @params
}

在执行此类操作时,它无法识别用户输入的服务器名称。它仍然需要最初指定的$Computername值。

Get-Diskinfo -drive c: Server1 administrator

如何识别用户输入的计算机名?我错过了什么吗?

3 个答案:

答案 0 :(得分:2)

直到你的职能部门才开始调用@parms

这应该可行,使用函数中的参数来提取WMI查询:

$Computername='localhost'
$parms = @{'computername'=$Computername;
    'credential'='administrator'}

function Get-Diskinfo {
    Param ($drive,$computername,$credential)
    Get-WmiObject win32_logicaldisk -Filter "DeviceID = '$drive'" -ComputerName $computername -Credential $credential
    }

然后使用splatting运行函数:

Get-Diskinfo -drive c: @parm

该功能仍然可以直接使用参数运行:

Get-Diskinfo -drive c: Server1 administrator

答案 1 :(得分:2)

您的$params哈希表在创建它时会获得它的值,而不是在它被使用时。您的$computername,$credential参数永远不会在函数内引用,这意味着它们是死参数。

您不能同时使用带参数的splatting和普通函数调用。您应该只在函数scriptblock中使用参数。 Splatting仅适用于最终用户。 @Tim Ferril向您展示了如何正确编写函数。

如果您需要能够使用两个默认值并且能够更改ex。对于一个cmdlet ComputerName,那么您应该使用默认值而不是splatting。例如:

function Test-Global {
param(
    $ComputerName = $global:PC,
    $Username = $global:username
)

"Computername is '$ComputerName'"
"Username is '$UserName'"
}

#Set the reusable variables in global scope and call your function
$global:Username = "Frode"
$global:PC = "MyPC"

PS C:\Users\Frode> Test-Global
Computername is 'MyPC'
Username is 'Frode'

#If I need to modify the server for one function, I'd simply specify that parameter
PS C:\Users\Frode> Test-Global -ComputerName server1
Computername is 'server1'
Username is 'Frode'

为了方便用户设置默认值,您也可以为此创建一个函数。

#Create your reusable parameters
function Set-Params {
param(
    $ComputerName,
    $Username
)
    if($Username) { $global:Username = $Username }
    if($ComputerName) { $global:PC = $ComputerName }
}

PS C:\Users\Frode> Set-Params -ComputerName Test1 -Username Test1

PS C:\Users\Frode> Test-Global
Computername is 'Test1'
Username is 'Test1'

PS C:\Users\Frode> Set-Params -ComputerName Test2

PS C:\Users\Frode> Test-Global
Computername is 'Test2'
Username is 'Test1'

答案 2 :(得分:2)

而不是splatting随机哈希表,你需要splat由PowerShell自动定义的东西:

function Get-Diskinfo {
Param ($drive,$computername,$credential)

# Need to remove any parameter that is used "internally" and don't exist on cmdlet
$PSBoundParameters.Remove('drive') | Out-Null

    Get-WmiObject win32_logicaldisk -Filter "DeviceID = '$drive'" @PSBoundParameters

}

Get-Diskinfo -drive c: Server1 administrator

或者:使用传递的参数在函数内构建$ parms:

function Get-Diskinfo {
Param ($drive,$computername,$credential)

$parms = @{
    computername = $Computername
    credential = $credential
}

Get-WmiObject win32_logicaldisk -Filter "DeviceID = '$drive'" @parms
}