I am trying to parse a JSON response that looks like
{
"Objects": [
{
"Name": "FirstName",
"Type": "XXXX",
},
{
"Name": "SecondName",
"Type": "YYYY",
},
{
"Name": "ThirdName",
"Type": "ZZZZ",
},
],
"TotalCount": 127
}
I want a CSV formatted like
"Name","Type"
"FirstName","XXXX"
"SecondName","YYYY"
and so on.
I tried creating a PSCustomObject and using Select-Object with it to generate the CSV but it does not give me the desired output.
My code:
$report=$null
foreach($obj in $json){
$item=$obj | ConvertFrom-Json
$report=[pscustomobject]#{
Name=($item.Objects.Name | Out-String).Trim()
Type=($item.Objects.Type | Out-String).Trim()
}
$report | Select-Object Name,Type | Export-Csv "PATH"`
Gives me CSV that looks like:
"Name","Type"
"FirstName
SecondName
ThirdName",
"XXXX
YYYY
ZZZZ"
if you really want the total count in the csv as well, here is one thing you could do:
$psobjarray = ($json | convertfrom-json)
$psobjarray.objects | Select-Object Name,Type | Export-Csv $Path
"Total Count: $($psobjarray.totalcount)" | out-file $Path -append
Related
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
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.
I need some help with converting a CSV File to Json using PowerShell. I have a script that gets the send message logs from Office365 using PowerShell and export them into a CSV file. I will then use the ConvertTo-Json cmdlet to Convert the CSV file into Json. The output Json file includes so many unnecessary texts that make it hard to read. For example, here is what I want:
{
"SenderAddress": "support#email.com",
"RecipientAddress": "zzzz#email.edu",
"Subject": "Microsoft PowerShell",
"Status": "Delivered",
}
Here is what I get after converting the CSV to Json:
{
"value": "\"support#email.com\",\"zzzz#email.edu\",\"Microsoft PowerShell\",\"Delivered\"",
"PSPath": "C:\\Logs\\Logs-1.csv",
"PSParentPath": "C:\\Logs",
"PSChildName": "Logs-1.csv",
"PSDrive": {
"CurrentLocation": "Windows\\system32",
"Name": "C",
"Provider": "Microsoft.PowerShell.Core\\FileSystem",
"Root": "C:\\",
"Description": "Windows",
"MaximumSize": null,
"Credential": "System.Management.Automation.PSCredential",
"DisplayRoot": null
},
"PSProvider": {
"ImplementingType": "Microsoft.PowerShell.Commands.FileSystemProvider",
"HelpFile": "System.Management.Automation.dll-Help.xml",
"Name": "FileSystem",
"PSSnapIn": "Microsoft.PowerShell.Core",
"ModuleName": "Microsoft.PowerShell.Core",
"Module": null,
"Description": "",
"Capabilities": 52,
"Home": "C:\\Users\\test",
"Drives": "C D E"
},
"ReadCount": 3
Here is the PowerShell cmdlet I run to convert the CSV file to Json.
Get-Content "C:\Logs\logs-1.csv" | ConvertTo-Json | Add-Content -Path "C:\Logs\logs-1.json
I also tried the following:
Get-Content "C:\Logs\logs-1.csv" |Select-Object -Property SenderAddress, RecipientAddress, Subject, Status ConvertTo-Json | Add-Content -Path "C:\Logs\logs-1.json
I go this result:
{
"SenderAddress": null,
"RecipientAddress": null,
"Subject": null,
"Status": null
}
Any idea what I can do to convert the CSV file to Json correctly without the extra info?
Thanks in advance for any help.
I'm guessing you need to use Import-Csv not Get-Content or Get-Item.
Try:
Import-Csv "C:\Logs\logs-1.csv" |
ConvertTo-Json |
Add-Content -Path "C:\Logs\logs-1.json"
Or:
Import-Csv "C:\Logs\logs-1.csv" |
Select-Object -Property SenderAddress, RecipientAddress, Subject, Status |
ConvertTo-Json |
Add-Content -Path "C:\Logs\logs-1.json"
If you intend to overwrite C:\Logs\logs-1.json, use Set-Content instead of Add-Content.
Also, you could define how many levels of contained objects are included in the JSON representation (default depth = 2).
import-csv .\INPUTFILE.csv | ConvertTo-Json -depth 100 | Out-File .\OUTPUTFILE.json
I have converted the following JSON file to powershell representation object.
{
"computer": [
{
"children": [
{
"children": [ {
"children": [ {
"path": "T:\Dropbox\kvaki.html",
"name": "kvaki",
"type": "url",
"url": "http://example.com"
} ],
"path": "T:\Dropbox\",
"name": "Njusha",
"type": "folder"
}, {
"path": "T:\Dropbox\Europa.html",
"name": "Europa",
"type": "url",
"url": "http://example.com"
}, {
"path": "T:\Dropbox\math.html",
"name": "math",
"type": "url",
"url": "http://example.com"
} ],
"path": "T:\Dropbox\",
"name": "Money",
"type": "folder"
}
],
"full_path_on_file_sys": "T:\Dropbox\"
}
]
}
After doing some computations with powershell representation I would like to save it to file as JSON.
But command $jsonRepresentation | ConvertTo-Json | Out-File "D:\dummy_path\file.json" saves it in this way
{
"computer": [
{
"children": " ",
"full_path_on_file_sys": "T:\Dropbox\"
}
]
}
Question: how to achieve correct saving of complex powershell JSON representation?
-depth argument for ConvertTo-Json solves the issue.
$jsonRepresentation | ConvertTo-Json -depth 100 | Out-File "D:\dummy_path\file.json"
Just pipe it to Set-Content, or Out-File:
Get-Process powershell |
ConvertTo-Json |
Set-Content json.txt
If you want to both view the output and save it to file, you can pipe the tee command.
Get-Process powershell | ConvertTo-Json | Tee-Object json.txt
$json.properties.metadata | ConvertTo-Json -Compress
if you are stuck with PowerShell Version 2, the JSON module of Joel Bennett from the 'PowerShell Code Repository' might help.
1) The below command can be used to convert a json to CSV
Example:
Get-Content package.json | Out-String | ConvertFrom-Json | Select parameter1, parameter2, parameter3 | ConvertTo-Csv -NoTypeInformation | Format-Table >> C:\JenkinsWorkspace\Result.csv
Get-Content: This is like "cat" command in linux which will get all data of file "package.json" and converts from Json (Using ConvertFrom-Json function) extracting the details of only required parameters and then converting them into CSV using "ConvertTo-Csv" function without any unwanted Type Headers and formatting them into Table.
2) The above result can also be formatted into proper csv to view it as Excel format without any duplicates and also having Text-To-Column conversion using below command:
Import-Csv "C:\Result.csv" -delimiter "," | Sort-Object _from -Unique | Export-csv "C:\FINAL_REPORT_$date.csv"