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

PowerShell构建符合API要求的CSR JSON格式规范实现求助

问题:PowerShell生成符合API要求的CSR JSON格式

我正在开发用于管理公司自研设备的PowerShell命令,设备通过API实现功能。目前遇到的问题是:将输入参数转换为符合API要求的格式,尤其是CSR的Subject部分,避免手动字符串处理,直接通过ConvertTo-Json生成正确的JSON。

API格式要求

核心的names字段格式

"names": [
    {
        "C": string,
        "L": string,
        "O": string,
        "OU": string,
        "ST": string
    }
]

完整API请求Schema

{
    "cn": string,
    "algorithm": string,
    "dnsNames": [
        string
    ],
    "emailAddresses": [
        string
    ],
    "encryptionAlgo": string,
    "ipAddresses": [
        string
    ],
    "name": string,
    "names": [
        {
            "C": string,
            "L": string,
            "O": string,
            "OU": string,
            "ST": string
        }
    ],
    "password": string,
    "privateKeyBytes": string,
    "size": integer
}

当前实现代码

我当前的实现依赖手动拼接字符串后进行替换,虽然能工作但不规范,希望找到无需字符串处理的正确方式:

function New-ConnectionCSR {
param (
    [Parameter(Mandatory=$true)] [string] $name,
    [Parameter()] [string] $cn=$name,
    [Parameter()] [string] $algorithm="RSA",
    [Parameter()] [int] $size=2048,
    [Parameter()] [string[]] $dnsNames,
    [Parameter()] [string[]] $ipAddresses,
    [Parameter()] [string[]] $emailAddresses,
    [Parameter()] [Alias('organization','org')] [string] $o="",
    [Parameter()] [Alias('oganizationalunit')] [string] $ou="", # 注意:此处拼写错误,应为organizationalunit
    [Parameter()] [Alias('location','locality')] [string] $l="",
    [Parameter()] [Alias('state')] [string] $st="",
    [Parameter()] [Alias('country')] [string] $c=""
    )

    Write-Debug "Start: $($MyInvocation.MyCommand.Name)"

    # Mandatory Parameters
    $body=@{
        
        "name"          = $name
        "cn"            = $cn
        "algorithm"     = $algorithm
        "names"         = @()

    }

    #Optional Parameters
    if($size){$body.Add('size',$size)}
    if($dnsNames){
        $dnsNames = $dnsNames.Split(",")
        $body.Add('dnsNames',$dnsNames)
    }
    if($ipAddresses){
        $ipAddresses = $ipAddresses.Split(",")
        $body.Add('ipAddresses',$ipAddresses)
    }
    if($emailAddresses){
        $emailAddresses = $emailAddresses.Split(",")
        $body.Add('emailAddresses',$emailAddresses)
    }
    if($ou -or $o -or $l -or $st -or $c){
        $names = @()
        if($ou){ $names += ('"ou":"' + $ou + '"') }
        if($o){ $names += ('"o":"' + $o + '"') }
        if($l){ $names += ('"l":"' + $l + + '"') }
        if($st){ $names += ('"st":"' + $st + '"') }   
        if($c){ $names += ('"c":"' + $c + '"') }
               
        $body.names += "{ $(($names -join ",")) }"
    }

    $jsonBody = ($body | ConvertTo-Json).Replace('\"','"')
    $jsonBody = $jsonBody.Replace('"{','{')
    $jsonBody = $jsonBody.Replace('}"','}')
    
    Write-Debug "JSON Body:`n$($jsonBody)"
}

注:末尾的字符串替换操作是我希望避免的

调用示例

New-ConnectionCSR -name "MyConnectionCert" -cn "mydevice.local" -size 2048 -dnsNames "mydevice.contoso.com,mydevice.contoso.local" -ipAddresses "10.0.0.1" -emailAddresses "support@contoso.com" -ou "MyOU" -o "MyOrg" -l "MyCity" -st "FDL" -c "USA"

正确解决方案

问题出在手动拼接names字段的字符串,导致ConvertTo-Json将其识别为普通字符串而非JSON对象。正确的做法是用PowerShell哈希表构建names中的对象,直接加入数组,这样ConvertTo-Json就能自动处理格式:

修改后的函数代码

function New-ConnectionCSR {
param (
    [Parameter(Mandatory=$true)] [string] $name,
    [Parameter()] [string] $cn=$name,
    [Parameter()] [string] $algorithm="RSA",
    [Parameter()] [int] $size=2048,
    [Parameter()] [string[]] $dnsNames,
    [Parameter()] [string[]] $ipAddresses,
    [Parameter()] [string[]] $emailAddresses,
    [Parameter()] [Alias('organization','org')] [string] $o="",
    [Parameter()] [Alias('organizationalunit')] [string] $ou="", # 修正拼写错误
    [Parameter()] [Alias('location','locality')] [string] $l="",
    [Parameter()] [Alias('state')] [string] $st="",
    [Parameter()] [Alias('country')] [string] $c=""
    )

    Write-Debug "Start: $($MyInvocation.MyCommand.Name)"

    # Mandatory Parameters
    $body=@{
        "name"          = $name
        "cn"            = $cn
        "algorithm"     = $algorithm
        "names"         = @()
    }

    #Optional Parameters
    if ($size) { $body['size'] = $size } # 用索引赋值比Add更简洁
    if ($dnsNames) {
        $body['dnsNames'] = $dnsNames.Split(",")
    }
    if ($ipAddresses) {
        $body['ipAddresses'] = $ipAddresses.Split(",")
    }
    if ($emailAddresses) {
        $body['emailAddresses'] = $emailAddresses.Split(",")
    }
    if ($ou -or $o -or $l -or $st -or $c) {
        $nameObject = @{}
        # 仅添加有值的字段,键名严格匹配API要求的大写形式
        if ($ou) { $nameObject['OU'] = $ou }
        if ($o) { $nameObject['O'] = $o }
        if ($l) { $nameObject['L'] = $l }
        if ($st) { $nameObject['ST'] = $st }
        if ($c) { $nameObject['C'] = $c }
        # 将哈希表加入names数组
        $body.names += $nameObject
    }

    # 使用-Depth参数确保嵌套对象被正确序列化
    $jsonBody = $body | ConvertTo-Json -Depth 3
    
    Write-Debug "JSON Body:`n$($jsonBody)"
    return $jsonBody # 可选:返回生成的JSON
}

关键改进点

  1. 用哈希表构建names对象:不再手动拼接字符串,而是创建$nameObject哈希表,添加有值的字段后直接加入$body.names数组,ConvertTo-Json会自动将其序列化为JSON对象。
  2. 修正参数拼写错误:将oganizationalunit改为organizationalunit,确保别名生效。
  3. 简化赋值方式:用$body['key'] = value替代Add方法,更简洁。
  4. 添加-Depth参数:因为存在嵌套数组和对象,指定-Depth 3确保所有层级都被正确序列化(默认Depth为2,可能导致嵌套对象被截断)。
  5. 移除字符串替换操作:无需再手动修正JSON格式,ConvertTo-Json直接生成符合要求的输出。

内容的提问来源于stack exchange,提问作者rick.leon.fl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 13:56:02