You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让PowerShell函数通过ValueFromRemainingArguments支持同名多参数

问题描述

为GitHub CLI编写了PowerShell包装函数Invoke-Gh,用于处理重复执行场景(比如GraphQL请求限流自动重试)。函数通过ValueFromRemainingArguments接收剩余参数,多数调用场景正常,但调用GraphQL API传入多个大小写不同的同名参数(如-F enterprise=$enterprise、-f query='xxx')时,会报错:

Invoke-Gh: Cannot bind parameter because parameter 'f' is specified more than once...

可执行invoke-gh -f -F直接复现该问题。

函数代码如下:

function Invoke-Gh {
    <#
    .Synopsis
    Wrapper function that deals with Powershell's peculiar error output when gh uses the error stream.
    
    .Example
    Invoke-Git ThrowError
    $LASTEXITCODE
    
    #>
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$false)]
        [switch]$slurp,

        [Parameter(Mandatory=$false)]
        [switch]$fromJson,

        [parameter(ValueFromRemainingArguments=$true)]
        [string[]]$Arguments
    )

    $output = & {
        [CmdletBinding()]
        param(
            [parameter(ValueFromRemainingArguments=$true)]
            [string[]]$InnerArgs
        )
        $sleep = 0
        do {
            $output = & gh $InnerArgs
            if ($sleep -gt 0) {
                Start-Sleep -Seconds $sleep 
            }
            $sleep += 5
        }
        while ($output -like "*GraphQL: was submitted too quickly*")

        if ($LASTEXITCODE -ne 0) {
            throw "Error executing gh command: $InnerArgs"
        }

        if ($slurp) {
            $output = $output | & jq -s
        }

        if ($fromJson) {
            $output = $output | ConvertFrom-Json
        }
        return $output
    } -ErrorAction SilentlyContinue -ErrorVariable fail @Arguments

    if ($fail) {
        $fail.Exception
    }
        
    return $output
}

目标调用示例:

&gh api graphql --paginate -F enterprise=$enterprise -f query='query($endCursor: String, $enterprise: String!) {
           enterprise(slug: $enterprise) {
             id,
             organizations(first: 100, after: $endCursor) {
               nodes
               {
                 login,
                 name
               },
               pageInfo {
                   hasNextPage
                   endCursor
               }
             }
           }
         }' --jq '.data.enterprise.organizations.nodes' 

解决方案

问题根源是PowerShell参数绑定不区分大小写,会把-F和-f识别为同一个参数名,而内部脚本块的参数绑定逻辑不允许重复参数。解决方法是取消内部脚本块的参数定义,直接使用自动变量$args接收所有传递的参数,绕过PowerShell的参数解析逻辑,让参数原样传递给gh命令。

修改后的函数代码:

function Invoke-Gh {
    <#
    .Synopsis
    Wrapper function that deals with Powershell's peculiar error output when gh uses the error stream.
    
    .Example
    Invoke-Git ThrowError
    $LASTEXITCODE
    
    #>
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$false)]
        [switch]$slurp,

        [Parameter(Mandatory=$false)]
        [switch]$fromJson,

        [parameter(ValueFromRemainingArguments=$true)]
        [string[]]$Arguments
    )

    $output = & {
        $sleep = 0
        do {
            $output = & gh $args
            if ($sleep -gt 0) {
                Start-Sleep -Seconds $sleep 
            }
            $sleep += 5
        }
        while ($output -like "*GraphQL: was submitted too quickly*")

        if ($LASTEXITCODE -ne 0) {
            throw "Error executing gh command: $args"
        }

        if ($slurp) {
            $output = $output | & jq -s
        }

        if ($fromJson) {
            $output = $output | ConvertFrom-Json
        }
        return $output
    } -ErrorAction SilentlyContinue -ErrorVariable fail @Arguments

    if ($fail) {
        $fail.Exception
    }
        
    return $output
}

修改说明

  1. 移除内部脚本块的[CmdletBinding()]属性和param定义,避免PowerShell对传入参数进行绑定解析
  2. 将内部的$InnerArgs替换为自动变量$args,该变量会自动收集所有传递给脚本块的参数
  3. 无论参数大小写是否不同,都会原样传递给gh命令,不会触发重复参数绑定错误

修改后即可正常执行目标调用:

Invoke-Gh api graphql --paginate -F enterprise=$enterprise -f query='query($endCursor: String, $enterprise: String!) {
           enterprise(slug: $enterprise) {
             id,
             organizations(first: 100, after: $endCursor) {
               nodes
               {
                 login,
                 name
               },
               pageInfo {
                   hasNextPage
                   endCursor
               }
             }
           }
         }' --jq '.data.enterprise.organizations.nodes'

内容的提问来源于stack exchange,提问作者jessehouwing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:08:10