PowerShell解析含数组JSON:提取vmStatus与psClient的status值
提取JSON嵌套字段psClient.status的解决方案
问题说明
需要从指定JSON文件中提取虚拟机的vmStatus值,以及psClient字段内嵌的status值。原代码尝试转换psClient的字符串格式但未成功,询问正则提取是否可行。
示例JSON数据
{ "totalRecords": 4, "pageNo": 0, "errorMessage": "", "errorCode": 0, "vmDeployStatusList": [ { "vmStatus": 1, "slaStatus": 1, "vmUsedSpace": 23451098, "name": "TEST-SRV11", "psClient": "@{hostName=cluster1.local.com; clientId=110; clientName=cluster1.local.com; status=1; flags=1}", "dcPlan": "" }, { "vmStatus": 1, "slaStatus": 1, "vmUsedSpace": 8248576001, "name": "TEST-SRV10", "psClient": "@{hostName=cluster1.local.com; clientId=40; clientName=cluster1.local.com; status=0; flags=1}", "dcPlan": "" }, { "vmStatus": 2, "slaStatus": 1, "vmUsedSpace": 76131082098, "name": "TEST-SRV21", "psClient": "@{hostName=cluster1.local.com; clientId=24; clientName=cluster1.local.com; status=1; flags=1}", "dcPlan": "" }, { "vmStatus": 2, "slaStatus": 1, "vmUsedSpace": 5540098763, "name": "TEST-SRV23", "psClient": "@{hostName=cluster1.local.com; clientId=11; clientName=cluster1.local.com; status=3; flags=1}", "dcPlan": "" } ] }
原代码问题分析
原代码中尝试将psClient的@{...}格式替换为{...}后用ConvertFrom-Json解析,但该格式并非标准JSON——键名和字符串值未加双引号,导致解析失败。
可行方案
方案1:正则提取(快速直接)
直接从psClient字符串中匹配status对应的数值,无需完整解析整个字段:
$VM_Stats_Col = @() foreach ($VM in $VM_List) { $VM_Stats = Get-Content -Path $vmStats | ConvertFrom-Json | Select-Object -ExpandProperty vmDeployStatusList | Where-Object { $_.name -eq $VM } | Select-Object -Property name, @{N='VM_Status'; E={$_.vmStatus}}, @{N='VM_Dep_Stats'; E={ # 正则匹配status后的数字 [regex]::Match($_.psClient, 'status=(\d+)').Groups[1].Value }} $VM_Stats_Col += $VM_Stats } Write-Output $VM_Stats_Col
方案2:转换为标准JSON解析(更可靠)
将psClient的PowerShell哈希表格式转换为标准JSON后解析,能完整获取所有psClient字段:
$VM_Stats_Col = @() foreach ($VM in $VM_List) { $VM_Stats = Get-Content -Path $vmStats | ConvertFrom-Json | Select-Object -ExpandProperty vmDeployStatusList | Where-Object { $_.name -eq $VM } | Select-Object -Property name, @{N='VM_Status'; E={$_.vmStatus}}, @{N='VM_Dep_Stats'; E={ # 转换为标准JSON格式 $psClientStr = $_.psClient -replace '@{', '{' ` -replace '}', '}' ` -replace '(\w+)=', '"$1":' ` -replace '([^;]+?)(;|$)', { $val = $args[0].Groups[1].Value if ($val -match '^\d+$') { $val } else { "`"$val`"" } } $psClientObj = $psClientStr | ConvertFrom-Json $psClientObj.status }} $VM_Stats_Col += $VM_Stats } Write-Output $VM_Stats_Col
说明
- 正则方案适合仅需提取
status值的场景,代码简洁高效。 - 标准JSON转换方案可获取
psClient的所有字段,扩展性更强,适合后续需要其他字段的情况。
内容的提问来源于stack exchange,提问作者Marcos
相关产品推荐
相关产品推荐

