I have a need to export the json results of a Invoke-WebRequest call to a .CSV file so that non-technical users can edit the data. This is what the json looks like when I save it to a .CSV file:
{
"Forecasts": [
{
"AccountNumber": "12345",
"Period": "2022-02-01T00:00:00",
"Field1": 3998.87968239,
"Field2": 2133.91206875
},
{
"AccountNumber": "12346",
"Period": "2022-03-01T00:00:00",
"Field1": 6741.483,
"Field2": 4007.857
}
]
}
I'm creating the .CSV file with this line of code:
$json.Forecasts | ForEach-Object { $_ | Export-Csv -path $fileName -NoTypeInformation -Append -Force }
And this is working good. After the user edits the data and saves and closes the .CSV file, I need to convert the .CSV data back into a JArray that looks like the original json structure (like above) so I can make another Invoke-WebRequest call (Patch), passing the JArray as the Body.
When I execute this line of code:
$editedJson = Get-Content -Raw -Path "$fileName" | ConvertFrom-CSV | Select-Object -Property AccountNumber,Period,Field1,Field2 | ConvertTo-json
The json looks like this:
[
{
"AccountNumber": "12345",
"Period": "2022-02-01T00:00:00",
"Field1": "3900.87968239",
"Field2": "2100.91206875"
},
{
"AccountNumber": "12346",
"Period": "2022-03-01T00:00:00",
"Field1": "6700.483",
"Field2": "4000.857"
}
]
As you can see, it's missing the "Forecasts" portion of the JArray and I don't know how to get the .CSV data back into this format. Can anyone help with this ?
You simply need to create an object with that property (Forecasts) and attach the imported CSV to said property:
# This line would be where you import the CSV:
# $csv = Import-Csv .....
$csv = #'
"AccountNumber","Period","Field1","Field2"
"12345","2/1/2022 12:00:00 AM","3998.87968239","2133.91206875"
"12346","3/1/2022 12:00:00 AM","6741.483","4007.857"
'# | ConvertFrom-Csv
#{
Forecasts = $csv
} | ConvertTo-Json
If you want to assure that the JSON representation of Forecasts is always an array (even when the CSV only has one row):
#{
Forecasts = [array]$csv
} | ConvertTo-Json
Related
I am importing JSON into Powershell to replace some values, but I also need to remove some objects from there.
Import:
$fileJson = Get-Content -path/Template.json -Encoding UTF8
I have an array of object which looks like this:
{
"resources": [
{
"name": "name1"
"type": "type1"
"....": "....."
},
{
"name": "name2"
"type": "type2"
"....": "....."
},
{
"name": "name3"
"type": "type1"
"....": "....."
}
]
}
and I want to remove a specific object from this array of objects. For example I want to remove Object where "type" equals "type2".
I have already tried to replace values with .Replace, however I can only replace single values and not the complete object.
Is it possible to delete or skip entire object with condition?
Convert the JSON to a custom object:
$fileJson = Get-Content -path/Template.json -Encoding UTF8
$data = $fileJson |ConvertFrom-Json
Use Where-Object to filter the resources array:
$data.resources = #($data.resources |Where-Object type -ne type2)
Convert the now modified object back to JSON and write to disk:
$data |ConvertTo-Json |Set-Content ./path/to/updatedTemplate.json -Encoding UTF8
I suggest to convert json into PowerShell objects, then make desired changes. then convert back to json if needed.
Example
$root = Get-Content -Path "C:\source.json" | ConvertFrom-Json
$root.resources = $root.resources | where type -eq 'type2'
$root | ConvertTo-Json -Depth 5 | Out-File "C:\destination.json"
I have not used PowerShell much. I have an API request which returns JSON that I need to turn into a CSV or xlsx file.
$output = Get-SurveyParticipents `
-url "https://orxsurveys.limequery.com/admin/remotecontrol" `
-session $sessionKey `
-id "5133965" `
-start "0" `
-limit "2" `
-unused $False `
-attributes ["completed", "usesleft"]
Write-Host($output | ConvertTo-Json)
{
"id": 1,
"result": [
{
"tid": "6",
"token": "35ddmyQTlNpzLat",
"participant_info": "#{firstname=Hsdfng; lastname=Gsdfh; email=gosdfdsfz.com}"
},
{
"tid": "7",
"token": "nQ_S838LjYT4mR6",
"participant_info": "#{firstname=Ofdlga; lastname=Yadfdfa; email=olsdfdsfivska#axsdfdsfnce.com}"
}
],
"error": null
}
The participant_info doesn't look like a normal JSON structure.
Also I am unsure how to turn this JSON into a CSV. Something like:
$output | ConvertTo-Json | Export-Csv -Path "c:\Scripts"
You don't need to do both Export-Csv and ConvertTo-Json. Export-Csv will convert a stream of powershell objects into a file containing CSV records.
Assuming the objects in the "results" array in your json output are what you want, you might try something like:
$output.result | Export-Csv -NoTypeInformation foo.csv
You are correct to say that participant_info is not Json. You'll have to process this yourself. ConvertFrom-StringData might be helpful.
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 one json file mytest.json like below I want to update values using PowerShell script
update.json
{
"update": [
{
"Name": "test1",
"Version": "2.1"
},
{
"Name": "test2",
"Version": "2.1"
}
]
}
I want to write a PowerShell script where if Name=="test1" I want to update Version= "3"
How can i do it using parameters?
Here is a way :
$a = Get-Content 'D:\temp\mytest.json' -raw | ConvertFrom-Json
$a.update | % {if($_.name -eq 'test1'){$_.version=3.0}}
$a | ConvertTo-Json -depth 32| set-content 'D:\temp\mytestBis.json'
According to #FLGMwt and #mikemaccana I improve the ConvertTo-Json with -depth 32 because the default depth value is 2 and for object deeper than 2 you will receive class informations in spite of objects.
I have also faced the same kind of issue. I was looking to change the records of the below JSON file
{
"SQS_QUEUE_URL": "https://que-url.com/server1",
"SQS_EVENTS_QUEUE_URL": "https://events-server.com/server1/development_events",
"REGION": "region1",
"BUCKET": "test-bucket",
"AE_WORK_PATH": "C:\\workpath\\path1",
"ENV": "env"
}
Finally, I managed to find the easiest way to generate a JSON file from Powershell.
$json = Get-Content "c:\users\bharat.gadade\desktop\test.json" | ConvertFrom-Json
$json.SQS_QUEUE_URL = "https://que-url.com/server2"
$json.SQS_EVENTS_QUEUE_URL = "https://events-server.com/Server2/development_events"
$json.REGION = "region1 "
$json.BUCKET = "test-bucket"
$json.AE_WORK_PATH = "C:\workpath\path1"
$json.ENV = "env"
$json | ConvertTo-Json | Out-File "c:\users\bharat.gadade\desktop\test.json"
I have a JSON data structured as following (there may be some mistakes here, the data I'm using is fine):
[{
"id": 12345,
"itemName": "some string",
"sellerId": 123,
"seller": "",
"categoryId": ,
"categoryPath": [
{
//more data
},
{
//more data
}
]},
{"id": 12346,
"itemName": "some other string",
"sellerId": 234,
"seller": "",
"categoryId": ,
"categoryPath": [
{
//more data
},
{
//more data
}
]
}]
I would like to convert it to csv so that the selected property names become csv headers and their value (depth 1 only) become data.
e.g
id,itemName,sellerId
12345,"some string",123
12346,"some other string",234
I've tried using hundreds of variations of
cat file.json | convertfrom-json | convertto-csv
but none have worked. All I get is csv data with objects names/types and I can't figure out how to make it use only selected properties of each object from json data.
In short you need to do something like this:
(Get-Content file.json -Raw | ConvertFrom-Json) | Select id,itemName,sellerId | Convertto-CSV -NoTypeInformation
The first problem was that Get-Content was passing individual lines to ConvertFrom-Json which is not what it wants. Using the -Raw switch passes it in its entirety.
The (Get-Content file.json -Raw | ConvertFrom-Json) needs to be in parentheses as that allows us to continue with the pipe. The properties are not accessible without doing this. It looks like it is trying to pass the entire object instead of its individual parts down the pipe.
-NoTypeInformation removes lines like this
#TYPE Selected.System.Management.Automation.PSCustomObject