【问题标题】:calling Invoke-Expression with Parameters in Powershell在 Powershell 中使用参数调用 Invoke-Expression
【发布时间】:2014-12-24 06:57:44
【问题描述】:

我用 c# 编写了一个 powershell 模块,其中包含一堆类似的 cmdlet

添加虚拟机

cmdlet 与 API 联系并拉回数据。

但为了与产品的 ssh CLI 保持一致,我编写了一个名为 newtask 的函数,它接受 'addvm' 作为参数和 $args。

例如

newtask addvm -id 12345

然后我调用 Add-VM 并像这样将 $args 作为字符串传递

Invoke-Expression Add-VM $argstr

问题是 Add-VM 抛出一个错误,它找不到接受参数 System.Object[] 的位置参数

找不到接受参数“System.Object[]”的位置参数

虽然我可以轻松地将“addvm”别名为“Add-VM”,但我正在尝试与 ssh CLI 保持一致,以便新用户可以快速开始使用此模块。

我认为发送像“-id 12345”这样的字符串就足够了,但事实并非如此。 pscmdlet 是否期望收到其他内容?

提前致谢。

【问题讨论】:

  • 我很确定错误来自 Invoke-Expression 而不是 Add-VM,您只需要在参数周围加上引号:Invoke-Expression "Add-VM $argstr"
  • 顺便说一句,我为什么不直接使用 Add-VM 呢?这种方式似乎只是增加了更多的输入。
  • @mikez 虽然我同意你的观点,但此模块适用于产品,产品的当前用户习惯于我在问题中提到的某种语法。在“addvm”的情况下,Add-VM 是有意义的,但 Delete 不是 powershell 动词,所以我不得不将 remove-vm 用于“deletevm”。我试图让它尽可能接近产品上的原始 ssh shell,以便无缝过渡。
  • 谢谢@mikez。 ""s 帮助并完成了工作。我的错。
  • 如果您想将调用用作抽象层,您可能需要使用Invoke-Command -ScriptBlock { ... $args } -ArgumentList ... 而不是Invoke-Expression "... $argstr"

标签: c# powershell command-line-arguments


【解决方案1】:

我知道这有点老了,但我遇到了类似的问题,一位同事向我展示了转义 $argstr 会阻止对象转换为字符串。

Invoke-Expression "Add-VM `$argstr"

【讨论】:

    【解决方案2】:

    该错误来自 Invoke-Expression 而不是 Add-VM,您只需要在参数周围加上引号:

    Invoke-Expression "Add-VM $argstr"
    

    这有强制所有对象为字符串格式的缺点。对于整数和字符串等简单类型,这可能是可以接受的,但如果您想通过更复杂的对象,它将无法工作。另一种方法是使用@args 来表达参数,但我认为您不能通过 Invoke-Expression 或 Invoke-Command 做到这一点。需要直接调用cmdlet:

    function newtask {
        params([string]$command)
    
        switch ($command) {
            "addvm" { Add-VM @args }
            "deletevm" { Remove-VM @args }
        }
    }
    

    【讨论】:

    • 这很棒。感谢您发布。我正在使用的另一个选项是一个数组,只需检查 $command 是否是 $cmdlist 中的一个元素。
    猜你喜欢
    • 2010-09-05
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多