繁体   English   中英

PowerShell 中的包装函数:传递剩余参数

[英]Wrapper function in PowerShell: Pass remaining parameters

我正在尝试在 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 - 基本上就像动态别名一样。 这甚至可能吗?

这种做你问的。 如果您需要将破折号前缀选项传递给与 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)
    }
}

你写的东西确实有效。 请注意, $args是超出函数预期参数的未命名参数。

因此,如果您将测试称为

test -option "A" 1 2 3

$args将有1,2,3

请注意,如果您将 test 称为

test -option "A" -other "B" 1 2 3

$args将有-other,B,1,2,3

  • 您的解决方案工作方式,是外部程序(比如你的C:\\Program Files\\some\\program.exe为例):你总是可以传递值的数组(这是什么$args是)一个外部程序,其元素将作为单独的参数传递(字符串化,如有必要)。

  • 你可以用任何命令你的解决方案的工作,如果你改变$args@args [1],采取了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
    }
}

注意事项

  • 自动$args变量收集所有声明参数的参数,仅在简单(非高级)函数和脚本中可用 高级函数和脚本- 使用[CmdletBinding()]属性和/或[Parameter()]属性的那些 - 要求声明所有潜在参数。

  • PowerShell 具有内置魔法,使自动数组变量$args也支持通过 splatting 传递命名参数,而自定义数组或集合不支持。

    • 相比之下,自定义数组和集合仅支持 splatting positional (unnamed) arguments ,但是,它涵盖了对外部程序的所有调用。
    • 但是,在调用PowerShell命令时,此限制是有问题的:例如,如果您想通过-Path C:\\命名参数-Path C:\\传递到Set-Location cmdlet,请使用通过ValueFromRemaining Arguments声明的自定义集合参数,如图所示在OldFart的回答Set-Location @Remaining ),是行不通的; 要支持传递命名参数(除了通过@args ,如果可用),您必须使用基于hashtable的 splatting

因此,如果您的函数是高级函数并且您需要支持将命名参数传递给其他 PowerShell 命令,则需要一种不同的方法此答案显示了两种替代方法。


[1] 对于外部程序,存在@args$args行为不同的@args情况,即如果$args数组包含--% ,则停止解析符号@args识别它, $args将其视为文字.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM