PowerShell ConvertTo-Json转换异常:如何正确获取动态维度值并生成合规JSON
问题分析与解决
你的问题核心出在PowerShell字符串插值的语法错误,再加上变量初始化和JSON生成逻辑的小问题,导致输出了哈希表的类型名称而非实际值。下面一步步拆解并修正:
1. 为什么会出现System.Collections.Hashtable...这类字符串?
在PowerShell的双引号字符串里,如果要插值复杂表达式(比如数组索引+属性访问),必须用$()把整个表达式包裹起来。否则PowerShell会把$Dimensions当成单独变量解析,然后把[$i].value当成普通字符串拼接,自然就输出了哈希表的类型名称,而非你想要的具体值。
错误写法:
"$Dimensions[$i].value"
正确写法(两种可选):
# 用$()包裹完整表达式 "$($Dimensions[$i].value)" # 或者直接去掉引号(因为值本身是字符串,无需插值) $Dimensions[$i].value
2. 其他需要修正的细节
$body变量未初始化:直接用+=会导致首次赋值出错,得先把它初始化为空数组- 循环内重复调用
ConvertTo-Json:会生成多个独立的JSON对象,而非统一的结构化输出;建议先收集所有请求对象,最后一次性转换为JSON
修正后的完整代码
# 初始化维度数组(注意每个哈希表的键值对要加分号分隔) $Dimensions = @( @{ name = 'num_vm'; value = '100' }, @{ name = 'days'; value = '10' }, @{ name = 'months'; value = '12' } ) # 初始化空数组存储所有请求对象 $requests = @() # 提前定义原代码中缺失的变量(示例值,你需要替换为实际内容) $resourceUsageId = "your-resource-id-123" $lastHourMinusFiveMinutes = (Get-Date).AddHours(-1).AddMinutes(-5).ToString("o") # 生成ISO 8601格式的时间 For ($i=0; $i -lt $Dimensions.Count; $i++) { # 正确构建请求对象,直接访问维度的name和value属性 $bodymessage = @{ 'resourceId' = $resourceUsageId 'quantity' = $Dimensions[$i].value 'dimension' = $Dimensions[$i].name 'effectiveStartTime' = $lastHourMinusFiveMinutes 'planId' = 'plan_meter' } # 将当前请求对象添加到数组中 $requests += $bodymessage } # 生成最终的JSON结构,一次性转换避免多个独立JSON $body = @{ request = $requests } | ConvertTo-Json -Depth 5 # 输出结果 $body
预期输出
修正后会生成一个包含所有请求的结构化JSON,示例如下:
{ "request": [ { "resourceId": "your-resource-id-123", "quantity": "100", "dimension": "num_vm", "effectiveStartTime": "2024-05-20T15:30:45.6789012Z", "planId": "plan_meter" }, { "resourceId": "your-resource-id-123", "quantity": "10", "dimension": "days", "effectiveStartTime": "2024-05-20T15:30:45.6789012Z", "planId": "plan_meter" }, { "resourceId": "your-resource-id-123", "quantity": "12", "dimension": "months", "effectiveStartTime": "2024-05-20T15:30:45.6789012Z", "planId": "plan_meter" } ] }
额外提示
如果确实需要每个请求输出单独的JSON对象(而非用一个数组包裹),可以在循环内直接转换并输出,但要确保插值逻辑正确:
For ($i=0; $i -lt $Dimensions.Count; $i++) { $bodymessage = @{ 'resourceId' = $resourceUsageId 'quantity' = $Dimensions[$i].value 'dimension' = $Dimensions[$i].name 'effectiveStartTime' = $lastHourMinusFiveMinutes 'planId' = 'plan_meter' } @{ request = @($bodymessage) } | ConvertTo-Json -Depth 5 }
内容的提问来源于stack exchange,提问作者Roger Chen
相关产品推荐
相关产品推荐

