This is my file structure, I would Like to access Subscription base on the value of "Name"
{
"Topics":
[
{
"Name": "topic1",
"Subscription": "sub1"
},
{
"Name": "topic2",
"Subscription": "sub2"
}
]
}
$json = Get-Content 'path' | Out-String | ConvertFrom-Json
$subscriptions=$json.Topics.Subscription|Where Name -EQ "topic1"
I'm getting the Name by executing following command
$json.Topics.Name
topic1
topic2
$json.Topics.Subscriptions
sub1
sub2
But not sure how to keep this in where clause
Try the following:
$json = #'
{
"Topics":
[
{
"Name": "topic1",
"Subscription": "sub1"
},
{
"Name": "topic2",
"Subscription": "sub2"
}
]
}
'#
$objectFromJson = $json | ConvertFrom-Json
$objectFromJson.Topics | Where-Object Name -eq 'topic1'
The above yields:
Name Subscription
---- ------------
topic1 sub1
If you would like to output only the .Subscription property value, simply use
($objectFromJson.Topics | Where-Object Name -eq 'topic1').Subscription
As for what you tried:
$json.Topics.Subscription
This extracts the values of the Subscription properties, which are mere strings ("sub1" and "sub2"), which don't have a .Name property, so your Where Name -EQ "topic1" filter matches nothing.
Related
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"
}
currently i am working on fetching Azure ad application expiry status on that i have pulled around 1700 ad applications and i have added one key pair(status) to the json object based on the secret expiry date
1) valid 2) Expired 3) expiring soon
so i have extracted all applications to a json file now i need to split single file into 3 files based on status as mentioned below
[
{
"DisplayName": "Reporter-dev",
"ObjectId": null,
"ApplicationId": {
"value": "62838283828288282828828288282828",
"Guid": "62838283828288282828828288282828"
},
"KeyId": "62838283828288282828828288282828",
"Type": "Password",
"StartDate": {
"value": "/Date(1590537256000)/",
"DateTime": "27 May 2020 05:24:16"
},
"EndDate": {
"value": "/Date(1653609256000)/",
"DateTime": "27 May 2022 05:24:16"
},
"Ownername": "shetty#gmail.com",
"Status": "Valid"
},
{
"DisplayName": "azure-cli-2018",
"ObjectId": null,
"ApplicationId": {
"value": "52388282828828288273673282932739223",
"Guid": "52388282828828288273673282932739223"
},
"KeyId": "52388282828828288273673282932739223",
"Type": "Password",
"StartDate": {
"value": "/Date(1568849784000)/",
"DateTime": "19 September 2019 05:06:24"
},
"EndDate": {
"value": "/Date(1600472184000)/",
"DateTime": "19 September 2020 05:06:24"
},
"Ownername": "joseph#gmail.com",
"Status": "Expired"
},
{
"DisplayName": "azure-cli-2019",
"ObjectId": null,
"ApplicationId": {
"value": "26382882828828282882828282828",
"Guid": "26382882828828282882828282828"
},
"KeyId": "26382882828828282882828282828",
"Type": "Password",
"StartDate": {
"value": "/Date(1576143476000)/",
"DateTime": "12 December 2019 15:07:56"
},
"EndDate": {
"value": "/Date(1607765876000)/",
"DateTime": "12 December 2020 15:07:56"
},
"Ownername": "zzzzzzzzz#gmail.com",
"Status": "About to Expire"
}
]
The below will split out the JSON based on the status and convert the data back to JSON. Change $JSONPath, $ValidPath, $ExpiredPath, $ExpiredSoonPath to the paths you require, the ones currently populated are what I have used for testing.
The contents of $JSONPath must have valid JSON to be able to work, whilst this is probably not the most efficient nor elegant it should do what you need.
$JSONPath = "C:\PS\JT\JSON.txt"
$JSONObj = Get-Content $JSONPath | ConvertFrom-Json
$ValidPath = "C:\PS\JT\Valid.txt"
$ExpiredPath = "C:\PS\JT\Expired.txt"
$ExpireSoonPath = "C:\PS\JT\ExpireSoon.txt"
$JSONObj | Where {$_.Status -eq "Valid"} | ConvertTo-Json | Out-File $ValidPath
$JSONObj | Where {$_.Status -eq "Expired"} | ConvertTo-Json | Out-File $ExpiredPath
$JSONObj | Where {$_.Status -eq "About to Expire"} | ConvertTo-Json | Out-File $ExpireSoonPath
Something very simple like the below example should work in theory but since you won't show your code there's a bunch of guess work here...
$collection = $json | ConvertFrom-Json
$valid = #(); $exp = #(); $soon = #(); $unknown = #()
foreach($item in $collection) {
switch ($item.Status)
{
'Valid' { $valid += $item }
'Expired' { $exp += $item }
'About to Expire' { $soon += $item }
Default { $unknown += $item}
}
}
$valid | Out-File .\Valid.txt -Append
$exp | Out-File .\Expired.txt -Append
$soon | Out-File .\AboutToExpire.txt -Append
$unknown | Out-File .\Unknown.txt -Append
Or if json is the desired output as in the other example;
$valid | ConvertTo-Json | Out-File .\Valid.txt -Append
etc, etc
Adding to the other answers, here is another solutions using pipelines.
Get-Content -Path .\sample.json -Raw | ConvertFrom-Json |
ForEach-Object { $_ | ConvertTo-Json | Out-File -FilePath "$($_.Status).json" }
Explanation
Parse JSON content using Get-Content, also making sure we use the -Raw switch to return the contents as one string with the newlines preserved. We don't need the contents as an array of strings(default behaviour).
Pipe to ConvertFrom-Json to deserialize the JSON into a System.Management.Automation.PSCustomObject.
Iterate over the objects using Foreach-Object and convert the object to a JSON file using ConvertTo-Json and Out-File. Note the default depth for ConvertTo-Json is 2, so if your JSON files end up having deeper levels, then you will need to specify a larger depth using the -Depth switch.
If its easier understand, you can also use a regular foreach loop here:
$json = Get-Content -Path .\sample.json -Raw | ConvertFrom-Json
foreach ($object in $json) {
$object | ConvertTo-Json | Out-File -FilePath "$($object.Status).json"
}
I want to return only the hash value of one object from my test.json file.
Right now, I am getting all hash values with my code.
json file:
[
{
"name": "abc.txt",
"hash": "D23FC7C4C9F1ED7CD147D7D29E3A541D"
},
{
"name": "def.txt",
"hash": "681B75B81734F7215C2DAD1F7EDFDAF7"
},
{
"name": "ghi.txt",
"hash": "81709CDC04EBDBDAA9BA15F6CAF1F05B"
},
{
"name": "xyz.txt",
"hash": "56F07815D06966FA3A73275797496881"
}
]
My code:
$jsonFile = $PSScriptRoot + "\test.json"
(Get-Content $jsonFile | ConvertFrom-Json | where {$_.name -eq 'abc.txt'}).hash
Careful with the parentheses:
((Get-Content $jsonFile | ConvertFrom-Json) | where {$_.name -eq "abc.txt"}).hash
#D23FC7C4C9F1ED7CD147D7D29E3A541D
Like this your json file contains a list of dictionaries. First you need to select which item of your list you want to have and then you can retrieve the value based on the key.
Try something like this:
$jsonFile = $PSScriptRoot + "\test.json"
$jsonList = Get-Content $jsonFile | ConvertFrom-Json
$jsonList[0].hash
Alternatively:
$jsonObject = $jsonList | Where-Object {$_.name -eq 'abc.txt'} | Select-Object hash
I have a folder with hundreds of json files in it & need to read them & create an output file with the various fields & values in it.
{
"id": "02002010",
"booktitle": "",
"pagetitle": "Demo Page",
"parent": "02002000",
"img": [
{
"imgfile": "02A.png",
"imgname": "02A.png"
}
],
"fmt": "",
"entries": [
{
"itemid": "1",
"partnumber": "1234567",
"partdescription": "Washer",
"partqty": "2",
"Manufacturer": "ACME",
"partdescriptionlocal": "Washer"
},
{
"itemid": "2",
"partnumber": "98765-B",
"partdescription": "Screw",
"partqty": "8",
"Vendor": "Widget Inc",
"TYPE": "Galv",
"partdescriptionlocal": "Screw"
}]
}
The json files will have generally the same structure, except that the "entries" may contain various fields in it that may not be the same from one entry to the next, or one json file to the next. Some may have fields within entry that I do not know the name of. There will be a few common fields in each "entries" section, but they could vary, and could be in a different order than what is shown.
I would like to write the output to a text/csv file that would be delimited that could then be imported into Excel. One column header with all fields listed. As new "entries" fields are found, tack them on to the end of each row & add to the header also.
you mean to do something like this?
$json = gc C:\temp\file.json | ConvertFrom-Json
$props = $json.entries | % {$_ | gm -MemberType NoteProperty} | select -exp name -Unique
$results = #()
foreach ($entry in $json.entries) {
$obj = $json | select *
foreach ($prop in $props) {
$obj | Add-Member -MemberType NoteProperty -Name $prop -Value $($entry | select -exp $prop -ea 0)
}
$results += $obj
}
$results | epcsv C:\temp\file.csv -NoTypeInformation -Encoding ASCII
$results
Consider JSON in this format :
"Stuffs": [
{
"Name": "Darts",
"Type": "Fun Stuff"
},
{
"Name": "Clean Toilet",
"Type": "Boring Stuff"
}
]
In PowerShell 3, we can obtain a list of Stuffs :
$JSON = Get-Content $jsonConfigFile | Out-String | ConvertFrom-Json
Assuming we don't know the exact contents of the list, including the ordering of the objects, how can we retrieve the object(s) with a specific value for the Name field ?
Brute force, we could iterate through the list :
foreach( $Stuff in $JSON.Stuffs ) {
But I am hopeful there exists a more direct mechanism ( similar to Lync or Lambda expressions in C# ).
$json = #"
{
"Stuffs":
[
{
"Name": "Darts",
"Type": "Fun Stuff"
},
{
"Name": "Clean Toilet",
"Type": "Boring Stuff"
}
]
}
"#
$x = $json | ConvertFrom-Json
$x.Stuffs[0] # access to Darts
$x.Stuffs[1] # access to Clean Toilet
$darts = $x.Stuffs | where { $_.Name -eq "Darts" } #Darts
I just asked the same question here: https://stackoverflow.com/a/23062370/3532136
It has a good solution. I hope it helps ^^.
In resume, you can use this:
The Json file in my case was called jsonfile.json:
{
"CARD_MODEL_TITLE": "OWNER'S MANUAL",
"CARD_MODEL_SUBTITLE": "Configure your download",
"CARD_MODEL_SELECT": "Select Model",
"CARD_LANG_TITLE": "Select Language",
"CARD_LANG_DEVICE_LANG": "Your device",
"CARD_YEAR_TITLE": "Select Model Year",
"CARD_YEAR_LATEST": "(Latest)",
"STEPS_MODEL": "Model",
"STEPS_LANGUAGE": "Language",
"STEPS_YEAR": "Model Year",
"BUTTON_BACK": "Back",
"BUTTON_NEXT": "Next",
"BUTTON_CLOSE": "Close"
}
Code:
$json = (Get-Content "jsonfile.json" -Raw) | ConvertFrom-Json
$json.psobject.properties.name
Output:
CARD_MODEL_TITLE
CARD_MODEL_SUBTITLE
CARD_MODEL_SELECT
CARD_LANG_TITLE
CARD_LANG_DEVICE_LANG
CARD_YEAR_TITLE
CARD_YEAR_LATEST
STEPS_MODEL
STEPS_LANGUAGE
STEPS_YEAR
BUTTON_BACK
BUTTON_NEXT
BUTTON_CLOSE
Thanks to mjolinor.
David Brabant's answer led me to what I needed, with this addition:
x.Stuffs | where { $_.Name -eq "Darts" } | Select -ExpandProperty Type
Hows about this:
$json=Get-Content -Raw -Path 'my.json' | Out-String | ConvertFrom-Json
$foo="TheVariableYourUsingToSelectSomething"
$json.SomePathYouKnow.psobject.properties.Where({$_.name -eq $foo}).value
which would select from json structured
{"SomePathYouKnow":{"TheVariableYourUsingToSelectSomething": "Tada!"}
This is based on this accessing values in powershell SO question
. Isn't powershell fabulous!
In regards to PowerShell 5.1 ...
Operating off the assumption that we have a file named jsonConfigFile.json with the following content from your post:
{
"Stuffs": [
{
"Name": "Darts",
"Type": "Fun Stuff"
},
{
"Name": "Clean Toilet",
"Type": "Boring Stuff"
}
]
}
This will create an ordered hashtable from a JSON file to help make retrieval easier:
$json = [ordered]#{}
(Get-Content "jsonConfigFile.json" -Raw | ConvertFrom-Json).PSObject.Properties |
ForEach-Object { $json[$_.Name] = $_.Value }
$json.Stuffs will list a nice hashtable, but it gets a little more complicated from here. Say you want the Type key's value associated with the Clean Toilet key, you would retrieve it like this:
$json.Stuffs.Where({$_.Name -eq "Clean Toilet"}).Type
It's a pain in the ass, but if your goal is to use JSON on a barebones Windows 10 installation, this is the best way to do it as far as I've found.
This is my json data:
[
{
"name":"Test",
"value":"TestValue"
},
{
"name":"Test",
"value":"TestValue"
}
]
Powershell script:
$data = Get-Content "Path to json file" | Out-String | ConvertFrom-Json
foreach ($line in $data) {
$line.name
}