Sharing below sample Data $vmStats
and $VM_List
is a variable with list of white-space separated VM names.
Sample Json Data
{
"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": ""
}
]
}
I want to extract two values from the above Json data, vmStatus
and status
(part of psClient).
I tried different iterations of the below code, but I couldn't get the second value status
.
Code
$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={
$psClientObj = ($_ | Select-Object -ExpandProperty psClient) -replace '@{', '{' -replace '}', '}'
$psClientObj = $psClientObj | ConvertFrom-Json
$psClientObj.status
}}
$VM_Stats_Col += $VM_Stats
}
Write-Output $VM_Stats_Col
The $_.psClient
returns the full list of values under that Property. So is it good option to extract the value of status
by using some regex on that ?
$VM_Stats_Col = @()
$JsonData = Get-Content -Path $vmStats | ConvertFrom-Json
foreach ($VM in $VM_List) {
$VM_Data = $JsonData.vmDeployStatusList | Where-Object { $_.name -eq $VM }
if ($VM_Data) {
# Clean up the hashtable-like string and parse it manually
$psClientRaw = $VM_Data.psClient -replace '^@{', '' -replace '}$', ''
$psClientDict = @{}
# Split by semicolon and extract key=value pairs
$psClientRaw -split '; ' | ForEach-Object {
$pair = $_ -split '=', 2
if ($pair.Length -eq 2) {
$psClientDict[$pair[0].Trim()] = $pair[1].Trim()
}
}
# Build output object
$VM_Stats = [PSCustomObject]@{
Name = $VM_Data.name
VM_Status = $VM_Data.vmStatus
VM_ClientStatus = $psClientDict['status']
}
$VM_Stats_Col += $VM_Stats
}
}
Write-Output $VM_Stats_Col
psClient
is not valid JSON — it looks like a PowerShell hashtable string.
We clean the string by removing @{
and }
and then split it by ;
to get key-value pairs.
Those pairs are added to a dictionary ($psClientDict
), and we access the status
value from it.
The output is a list of custom objects with Name
, VM_Status
, and VM_ClientStatus
.
Name VM_Status VM_ClientStatus
---- --------- ---------------
TEST-SRV11 1 1
TEST-SRV10 1 0
TEST-SRV21 2 1
TEST-SRV23 2 3