我正在尝试在PowerShell中编写一个包装器函数,该函数基本上评估第一个参数并基于它在计算机上运行程序。然后,包装函数的所有剩余参数都应传递给运行的程序。
所以看起来应该是这样的:
function test ( [string] $option )
{
if ( $option -eq 'A' )
{
Write-Host $args
}
elseif ( $option -eq 'B' )
{
. 'C:\Program Files\some\program.exe' $args
}
}
现在只添加$args
不起作用,那么我需要做些什么才能使其正常工作?另一种选择可能是使用Invoke-Expression
,但感觉有点像eval
所以我想尽可能避免,此外我认为这样做会限制我只使用字符串参数吧?如果可能的话,我希望得到对包装程序/ cmdlet的完全支持 - 基本上就像动态别名一样。这甚至可能吗?
答案 0 :(得分:11)
这样做可以满足您的要求。如果您需要将带有破折号前缀的选项传递给与PowerShell常见参数冲突或导致歧义的可执行文件,则可能会遇到麻烦。但这可能会让你开始。
function Invoke-MyProgram
{
[CmdletBinding()]
Param
(
[parameter(mandatory=$true, position=0)][string]$Option,
[parameter(mandatory=$false, position=1, ValueFromRemainingArguments=$true)]$Remaining
)
if ($Option -eq 'A')
{
Write-Host $Remaining
}
elseif ($Option -eq 'B')
{
& 'C:\Program Files\some\program.exe' @Remaining # NOTE: @ not $ (splatting)
}
}
答案 1 :(得分:3)
您所写的内容(else if
处的语法错误除外 - 它应该是elseif
)确实有效。请注意,$args
的含义是超出函数预期参数的未命名参数。
因此,如果您将测试称为
test -option "A" 1 2 3
$args
将1,2,3
请注意,如果您将测试称为
test -option "A" -other "B" 1 2 3
$args
将-other,B,1,2,3
答案 2 :(得分:1)
您的解决方案可以直接用于外部程序 (例如您的C:\Program Files\some\program.exe
示例):您始终可以传递< em>值的数组 (这就是$args
)到外部程序,并且其元素将作为单独传递参数 (必要时进行字符串化)。
如果将$args
更改为@args
,则可以使用 any 命令使您的解决方案起作用 [1] < / sup>,以利用称为splatting的PowerShell参数传递技术:
function test ( [string] $option )
{
if ( $option -eq 'A' )
{
Write-Host $args
}
elseif ( $option -eq 'B' )
{
# Use @args to also support passing *named* arguments
# through to *PowerShell* commands.
& $someCommand @args
}
}
注意事项:
automatic $args
variable收集声明了 no 参数的所有参数,仅在 simple 中可用(非高级) )功能和脚本; advanced functions and scripts-使用[CmdletBinding()]
属性和/或[Parameter()]
属性的对象-要求声明所有个潜在参数。
PowerShell具有内置的魔术,使自动 array 变量$args
也支持传递 named 参数可以通过splatting 来实现,而 custom 数组或集合都不支持。
-Path C:\
声明的自定义集合参数(如OldFart's answer(Set-Location
)中所示,通过喷溅到ValueFromRemaining Arguments
cmdlet,不会工作要支持通过命名参数传递(通过Set-Location @Remaining
除外,如果可以的话),必须使用基于 hashtable 的外观。< / li>
因此,如果您的函数是一个高级一个 ,则需要支持将 named 参数传递给其他PowerShell命令,需要一种不同的方法:this answer显示了两种选择。
[1]对于外部程序,在极端情况下@args
的行为与@args
不同,即$args
数组包含$args
,stop-parsing symbol:--%
识别它,@args
将其视为文字。