trouble parsing json in powershell - json

I have the below JSON which is just a bit of the file but illustrates it.
I am not that experienced with JSON and I have tried a lot of the examples that I could find but they only seem to show JSON that is just key/value pairs. I've seen a few to target arrays but I cant translate them to my particular JSON
for example I'm trying to get that the 'SavedPlayerDataVersion' is equal to 8 into a variable and I've put it into an object but I cant figure out how to target that particular item within the array and object
could anyone point me in the right direction please?
Thank you
{
"profileVersion": 1,
"profile": {
"id": 0,
"class": "PrimalPlayerDataBP_C",
"names": ["PrimalPlayerDataBP_C_29", "ArkGameMode", "PersistentLevel", "Aberration_P", "/Game/Maps/Aberration/Aberration_P"],
"properties": [{
"name": "SavedPlayerDataVersion",
"type": "IntProperty",
"value": 8
}, {
"name": "HexagonCount",
"type": "IntProperty",
"value": 106860
}, {
"name": "MyPersistentBuffDatas",
"type": "ArrayProperty",
"arrayType": "ObjectProperty",
"value": [1, 2, 3, 4]
}],
"extra": null
}
}
"type": "IntProperty",
"value": 8
}, {
"name": "HexagonCount",
"type": "IntProperty",
"value": 6800
}, {
"name": "NumChibiLevelUpsData",
"type": "IntProperty",
"value": 2
}, {
"name": "MyData",
"type": "StructProperty",
"structType": "PrimalPlayerDataStruct",
"value": [{
"name": "PlayerDataID",
"type": "UInt64Property",
"value": 656195017
}, {
"name": "UniqueID",
"type": "StructProperty",
"structType": "UniqueNetIdRepl",
"value": {
"unk": 8,
"netId": "76561198046328344"
}
}
I have edited the question after the original answers as I realised that what I also needed to access was a 'level' deeper. so it would be getting at "PlayerDataID"
I tried $value = ($jsonobj.profile.properties.mydata | Where-Object { $_.name -eq "PlayerDataID" }).value but that isnt getting it for me

JSON is exactly key-value pairs, so handling it like an object in PowerShell is the way to go. Start with ConvertFrom-Json and put the result in a variable, let's say $myJson.
$myJson.profile.class would net you PrimalPlayerDataBP_C. That's how you access nested properties. As for the arrays, you can iterate through them with foreach, get specific values with where or select, depends on what you need actually.
# This one returns the version number
$version = ($myJson.profile.properties | Where {$_.name -eq "SavedPlayerDataVersion"}).value
# This one checks whether version is 8
$isVersion8 = $NULL -ne `
($myJson.profile.properties | Where {$_.name -eq "SavedPlayerDataVersion" -and $_.value -eq 8})
Be careful when accessing array items using their index, as you never can be sure that the item with a specific index is the one you're looking for.
As I'm writing this answer, #Theo beat me to it, so kudos to him for the one-liner.
EDIT:
Including a step-by-step example for clarity's sake. You can do the same with fewer lines.
# Get an array of properties
$properties = $myJson.profile.properties
# Select the property with the required name from the array
$myData = $properties | Where {$_.name -eq "MyData"}
# MyData is multivalued, so need to use 'Where' again
$playerDataId = $myData.value | Where {$_.name -eq "PlayerDataID"}
# Value you are looking for
$playerDataId.value

You can get the value you seek with a one-liner.
For demo I'm using a Here-String for your json data, but probably you would read that from file with $data = Get-Content -Path 'thefile.json' -Raw | ConvertFrom-Json
$data = #'
{
"profileVersion": 1,
"profile": {
"id": 0,
"class": "PrimalPlayerDataBP_C",
"names": ["PrimalPlayerDataBP_C_29", "ArkGameMode", "PersistentLevel", "Aberration_P", "/Game/Maps/Aberration/Aberration_P"],
"properties": [{
"name": "SavedPlayerDataVersion",
"type": "IntProperty",
"value": 8
}, {
"name": "HexagonCount",
"type": "IntProperty",
"value": 106860
}, {
"name": "MyPersistentBuffDatas",
"type": "ArrayProperty",
"arrayType": "ObjectProperty",
"value": [1, 2, 3, 4]
}],
"extra": null
}
}
'# | ConvertFrom-Json
Then, to get the value from property with name "SavedPlayerDataVersion" you simply do:
$value = ($data.profile.properties | Where-Object { $_.name -eq "SavedPlayerDataVersion" }).value
Variable $value will now contain 8

Simple example:
$json = '{ "one": 1, "two": 2 }'
$data = $json | ConvertFrom-Json | Select one
$myVal = $data.one
$myVal
The printed output will be 1
In your case:
$json = '{
"profileVersion": 1,
"profile": {
"id": 0,
"class": "PrimalPlayerDataBP_C",
"names": ["PrimalPlayerDataBP_C_29", "ArkGameMode", "PersistentLevel", "Aberration_P", "/Game/Maps/Aberration/Aberration_P"],
"properties": [{
"name": "SavedPlayerDataVersion",
"type": "IntProperty",
"value": 8
}, {
"name": "HexagonCount",
"type": "IntProperty",
"value": 106860
}, {
"name": "MyPersistentBuffDatas",
"type": "ArrayProperty",
"arrayType": "ObjectProperty",
"value": [1, 2, 3, 4]
}],
"extra": null
}}'
$data = $json | ConvertFrom-Json | Select -expand profile | Select -expand properties | Select name, type, value
$myVal = $data[0].value
$myVal

Related

How to read specific Key from JSON file with Powershell

I'm trying to read a Json file with some passwords but them are stored into Key-Value pattern as below:
{
"id": "a8cc4184-3844-4605-8e35-ea479ae1094e",
"name": "Test Credentials and Secrets",
"values": [
{
"key": "apassword",
"value": "mypassword",
"enabled": true
},
{
"key": "tpassword",
"value": "my other password",
"enabled": true
},
],
"exported_using": "Postman/7.34.0"
}
How can I get any specific value with PowerShell? tpassword value for instance.
I would recommend using ConvertFrom-Json to turn it into an Object so you can then access the properties easily with PowerShell.
I saved the json above to C:\temp\json.json and then the following got me the tpassword value:
$json = Get-Content C:\temp\json.json | ConvertFrom-Json
$json.values | Where-Object key -eq 'tpassword' | Select-Object Value

Removing Objects from JSON using powershell

I have a test.json file which has the below structure:
{
"name": "test",
"class": "4",
"exam": "test",
"marks": "4"
}
I want to remove some pairs from it like exam and class, and ultimately it should look like below:
{
"name": "test",
"marks": "4"
}
How can I do it from PowerShell?
Your post was not completely clear if you wanted to remove certain keys, or if you only wanted to retain marks and name. The code below performs the latter:
Get-Content 'test.json' -Raw |
ConvertFrom-Json |
Select-Object name, marks |
ConvertTo-Json
Result:
{
"name": "test",
"marks": "4"
}
powershell cmd:
$obj = Get-Content .\aaa.json | ConvertFrom-Json
$obj.psobject.properties.remove('exam')
$obj.psobject.properties.remove('class')
$obj | ConvertTo-Json
output:
{
"name": "test",
"marks": "4"
}

powershell that reads values from csv or json file and create registry keys if do not exist

I am trying to write a powershell script that creates registry keys and their values from a csv or json file containing the list of the registries .
did any one code such thing can help ? :)
Using ConvertFrom-Json, convert your JSON to a custom PSCustomObject object. Then iterate through the object properties and call New-ItemProperty to create the new registry entries with the appropriate values.
PowerShell
$jsonFile = "<path to JSON file>"
$customObject = Get-Content $jsonFile | ConvertFrom-Json
$customObject.PSObject.Properties | ForEach-Object {
[void](New-ItemProperty -LiteralPath $_.Value.path -Name $_.Value.name -Value $_.Value.value -PropertyType $_.Value.type -Force)
}
JSON
{
"reg1": {
"path": "path1",
"name": "name1",
"value": "value1",
"type": "type1"
},
"reg2": {
"path": "path2",
"name": "name2",
"value": "value2",
"type": "type2"
},
"reg3": {
"path": "path3",
"name": "name3",
"value": "value3",
"type": "type3"
}
}
Links
ConvertFrom-Json (learn.microsoft.com)
New-ItemProperty (learn.microsoft.com)

ConvertFrom-JSON won't accept convertto-json with children when working with WebServiceProxy

I am pulling data from an API using the New-WebServiceProxy in PowerShell 4.0 and then piping it out to a JSON file for review and import on another API service (same API version, etc, just a different host).
$tasklist.Taskconfig | ConvertTo-JSON-Depth 50 -As String | Out-File -FilePath $exportpath\$name.xml -Force
Gives me my XML containing the TaskConfig. In this case, TaskConfig is an object type automatically generated by the API I'm interfacing with. When I want to import the content I am using:
$taskconfig = (Get-Content "$taskjson") -join "`n" | ConvertFrom-Json
but when I run this it's unable to create the object. I assume this is because the JSON contains nested children, giving the error-
Cannot convert value "#{Name=plugindive; Value=;> Children=System.Object[]}" to type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1rcleWeb_WebClientAPI_asmx_wsdl.TaskConfig". Error: "Cannot convert the "#{Name=plugindive; Value=;Children=System.Object[]}" value of type "System.Management.Automation.PSCustomObject" to type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1rcleWeb_WebClientAPI_asmx_wsdl.TaskConfig"."
I've tried explictly stating the type of object:
$taskconfig = [Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1rcleWeb_WebClientAPI_asmx_wsdl.TaskConfig](Get-Content "$taskjson" | Out-string | ConvertFrom-Json)
as well as creating the object then trying to add the children from my JSON -
$taskconfig.children = $json.children
But these all fail in the same way.
I don't seem to get this same issue in PowerShell 5.0 interestingly enough, but I can't verify why - is there another way to approach this?
Added example JSON below
{"Name": "plugindive",
"Value": null,
"Children": [{
"Name": "auto",
"Value": "False",
"Children": [
]
},
{
"Name": "categories",
"Value": null,
"Children": [{
"Name": "Module Z",
"Value": "False",
"Children": [
]
},
{
"Name": "Module A",
"Value": "False",
"Children": [
]
},
{
"Name": "Module B",
"Value": "False",
"Children": [
]
},
{
"Name": "Module C",
"Value": "False",
"Children": [
]
}
]
}
]
}
It seems as if this doesn't work in PowerShell v3.0, so I simply ended up making posts with the explicit XML directly, rather than converting to JSON.

ConvertFrom-JSON strips array from object

I'm loading a text file containing some Json to edit a property. However, after modifying the content and writing it to file, the Json becomes invalid.I
I use the following PowerShell to modify the file:
$manifest = Get-Content $PathToManifest -Raw | ConvertFrom-Json
#modify Json
Set-Content -Path $PathToManifest -Value ( $manifest | ConvertTo-Json)
The following snippet from my Json file gets corrupted:
"contributions": [
{
"id": "sample-data-widget",
"type": "ms.vss-dashboards-web.widget",
"targets": ["ms.vss-dashboards-web.widget-catalog"],
"properties": "#{name=Sample Data; description=Create sample data in a VSTS project.; previewImageUrl=img/logo.png; uri=index.html; supportedSizes=System.Object[]; supportedScopes=System.Object[]}"
}]
After loading the Json and writing it back to file the array syntax around targets is gone:
"contributions": [
{
"id": "sample-data-widget",
"type": "ms.vss-dashboards-web.widget",
"targets": "ms.vss-dashboards-web.widget-catalog",
"properties": "#{name=Sample Data; description=Create sample data in a VSTS project.; previewImageUrl=img/logo.png; uri=index.html; supportedSizes=System.Object[]; supportedScopes=System.Object[]}"
}]
Why is this happening? Is there a way to make sure the syntax doesn't change?
ConvertTo-Json has Depth parameter that controls how many levels of contained objects are included in the JSON representation. The default value is 2. ConvertTo-Json will call .ToString() on anything nested deeper than specified Depth.
So all you need is to specify sufficiently large number for Depth argument or just ([int]::MaxValue).
Set-Content -Path $PathToManifest -Value ( $manifest | ConvertTo-Json -Depth ([int]::MaxValue))
Examples of nesting and ConvertTo-Json behavior:
$NestedArray = #(1,#(2,#(3,#(4))))
Default:
$NestedArray | ConvertTo-Json
[
1,
{
"value": [
2,
[
3,
"4"
]
],
"Count": 2
}
]
No nesting at all:
$NestedArray | ConvertTo-Json -Depth 1
[
1,
{
"value": [
2,
"3 System.Object[]"
],
"Count": 2
}
]
Desired result:
$NestedArray | ConvertTo-Json -Depth 3
[
1,
{
"value": [
2,
[
3,
[
4
]
]
],
"Count": 2
}
]