考虑以下功能
Function IfFunctionExistsExecute
{
param ([parameter(Mandatory=$true)][string]$func)
begin
{
# ...
}
process
{
if(Get-Command $func -ea SilentlyContinue)
{
& $func # the amperersand invokes the function instead of just printing the variable
}
else
{
# ignore
}
}
end
{
# ...
}
}
用法:
Function Foo { "In Foo" }
IfFunctionExistsExecute Foo
这行得通。
但是这不起作用:
Function Foo($someParam)
{
"In Foo"
$someParam
}
IfFunctionExistsExecute Foo "beer"
然而这给了我丑陋的错误:
IfFunctionExistsExecute : A positional parameter cannot be found that accepts argument 'beer'.
At C:\PSTests\Test.ps1:11 char:24
+ IfFunctionExistsExecute <<<< Foo "beer"
+ CategoryInfo : InvalidArgument: (:) [IfFunctionExistsExecute], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,IfFunctionExistsExecute
如何在 PS 中执行此操作?
尝试在调用的函数和
IfFunctionExistsExecute
函数上创建一个可选参数;像这样:
Function IfFunctionExistsExecute
{
param ([parameter(Mandatory=$true)][string]$func, [string]$myArgs)
if(Get-Command $func -ea SilentlyContinue)
{
& $func $myArgs # the amperersand invokes the function instead of just printing the variable
}
else
{
# ignore
}
}
Function Foo
{
param ([parameter(Mandatory=$false)][string]$someParam)
"In Foo"
$someParam
}
IfFunctionExistsExecute Foo
IfFunctionExistsExecute Foo "beer"
对我来说:
C:\test>powershell .\test.ps1
In Foo
In Foo
beer
C:\test>
也许您也应该将参数传递给被调用函数:
$arguments = $args[1..($args.Length-1)]
& $func @arguments
我写了我的解决方案。以 powershell 风格命名的函数:Verb-Noun。它支持命名参数和剩余参数。
function Invoke-FunctionIfExist {
[CmdletBinding()]
param (
# Function name
[Parameter(Mandatory, Position=0)]
[string]
$Name,
# Hashtable with named arguments
[Parameter()]
[hashtable]
$Parameters = @{},
# Rest of arguments
[Parameter(ValueFromRemainingArguments)]
[object[]]
$Arguments = @()
)
process {
if (Get-Command $Name -ErrorAction SilentlyContinue) {
& $Name @NamedArguments @Arguments
}
}
}
用法示例:
PS> Invoke-FunctionIfExist Foo
In Foo
PS> Invoke-FunctionIfExist Foo beer
In Foo
beer
PS> Invoke-FunctionIfExist Foo -Parameters @{someParam='beer'}
In Foo
beer