Convert CSV to JSON and JSON to CSV using PowerShell - json

I have a CSV file that I am trying to convert to JSON using PowerShell.
The CSV file contains the following data.
web_url.csv
wikipedia,https://en.wikipedia.org/wiki/%s
wolframalpha,http://www.wolframalpha.com/input/?i=%s
drive,http://www.drive.google.com/
I would like to convert to json in the following format. Similarly how do you convert this json back to original csv in the format shown above?
web_url.json
{
"wikipedia": "https://en.wikipedia.org/wiki/%s",
"wolframalpha": "http://www.wolframalpha.com/input/?i=%s",
"drive": "http://www.drive.google.com/"
}
When I run the command,
Get-Content -path web_url.csv | ConvertFrom-Csv -Delimiter ',' |
ConvertTo-Json
it returns the following output which is not what I want.
[
{
"wikipedia": "wolframalpha",
"https://en.wikipedia.org/wiki/%s": "http://www.wolframalpha.com/input/?i=%s"
},
{
"wikipedia": "drive",
"https://en.wikipedia.org/wiki/%s": "http://www.drive.google.com/"
}
]

# PowerShell script
import-csv "SampleInput.csv" | ConvertTo-Json | Add-Content -Path "output.json"

Your csv doen't look like a "proper" csv to me: columns are swapped with rows. If you have control over input file, you may fix it there already:
#'
wikipedia,wolframalpha,drive
https://en.wikipedia.org/wiki/%s,http://www.wolframalpha.com/input/?i=%s,http://www.drive.google.com/
'# | ConvertFrom-Csv | ConvertTo-Json
If that is not possible, you just have to perform some extra steps to get what you need:
$propertyList = #'
wikipedia,https://en.wikipedia.org/wiki/%s
wolframalpha,http://www.wolframalpha.com/input/?i=%s
drive,http://www.drive.google.com/
'# | ConvertFrom-Csv -Header Name, Value
$properties = [ordered]#{}
foreach ($property in $propertyList) {
$properties.Add($property.Name, $property.Value)
}
New-Object PSObject -Property $properties | ConvertTo-Json
And back, again - some extra work is required:
(#'
{
"wikipedia": "https://en.wikipedia.org/wiki/%s",
"wolframalpha": "http://www.wolframalpha.com/input/?i=%s",
"drive": "http://www.drive.google.com/"
}
'# | ConvertFrom-Json).PSObject.Properties |
Select-Object Name, Value |
ConvertTo-Csv -NoTypeInformation |
Select-Object -Skip 1

what about this ?
$csv=#"
wikipedia,https://en.wikipedia.org/wiki/%s
wolframalpha,http://www.wolframalpha.com/input/?i=%s
drive,http://www.drive.google.com/
"#
$obj= $csv |convertfrom-csv -delim ',' -Header "name","url"
#$obj
$json=$obj |convertto-json
#$json
$csv2 =$json |convertfrom-json |select -expand syncroot |convertto-csv -NoTypeInformation -Delimiter ','
#$csv2

Related

Powershell ConvertFrom-Json accessing json value

I have a json file that I'd like to convert to csv. However, the actual value is nested inside reading key that I need to access. It returns System.Object[] in which I know I have to access this, but I don't know how.
the following is the result.json file,
{"totalNumberOfReadings":1488,
"readings":
[
{"meterNumber":"xxxxx","date":"2022-02-01 00:00","reading":0.0,"status":"AsRequested"},
{"meterNumber":"xxxxx","date":"2022-01-31 23:30","reading":0.0,"status":"As Requested"},
{"meterNumber":"xxxxx","date":"2022-01-31 23:00","reading":0.0,"status":"As Requested"},
{"meterNumber":"xxxxx","date":"2022-01-31 23:00","reading":0.0,"status":"As Requested"},
]
}
My script is like this
C:\> (Get-Content -Raw result.json | ConvertFrom-Json) | ConvertTo-Csv -NoTypeInformation
the output is this
"totalNumberOfReadings","readings"
"1488","System.Object[]"
This is just the summary/metadata. I want the actual content inside the key's value, how to access the value?
Either use member access:
(Get-Content -Raw result.json | ConvertFrom-Json).readings | ConvertTo-Csv -NoTypeInformation
...or only pipeline commands:
Get-Content -Raw result.json | ConvertFrom-Json | ForEach-Object readings | ConvertTo-Csv -NoTypeInformation
ForEach-Object readings is the short form of ForEach-Object -MemberName readings.

marge embedded JSON objects with powershell

I have following ConvertFrom-Json output from JSON file:
Id : 1
ItemName : TestFile
SharingInformation : {#{RecipientEmail=complianceadmin#dev.onmicrosoft.com; ResharePermission=Read}, #{RecipientEmail=test#dev.onmicrosoft.com; ResharePermission=Read}}
I would like to save this data to .csv file in following manner as columns:
Id : 1
ItemName : TestFile
Users : (read) test#dev.domain.com ; (write) test2#dev.domain.com
as columns.. Here you can find part of my actual PS code (which do not work properly when there is more than one embedded values):
$JSONFile = $ExctratedFile | ConvertFrom-Json
$psObjectForCsv = $JSONFile | ForEach-Object {
[PSCustomObject]#{
"id"=$_.Id
"ItemName"=$_.ItemName
"RecipientEmail"=$_.SharingInformation.RecipientEmail
"ResharePermission"=$_.SharingInformation.ResharePermission
}
}
$psObjectForCsv | Export-Csv -path $fileName -Force -NoTypeInformation
}
do you have any ideas how to achieve this?
Thank you for your help!
Regards
You can format the SharingInformation in any form you like.
Try
$JSONFile = $ExctratedFile | ConvertFrom-Json
$result = $JSONFile | ForEach-Object {
# output a formatted string "(permission) emailaddress"
$users = foreach ($shareInfo in $_.SharingInformation) {
'({0}) {1}' -f $shareInfo.ResharePermission, $shareInfo.RecipientEmail
}
[PSCustomObject]#{
id = $_.Id
ItemName = $_.ItemName
Users = $users -join "; "
}
}
$result | Export-Csv -Path $fileName -Force -NoTypeInformation

Modifying JSON file using data from CSV in PowerShell

I'm trying to modify some specific values in a .json file based on two columns in a .csv file. If the current value in the .json file is identical to the one in the left column, I want to change it to the one in the right column.
This is my first time with PowerShell though, so I'm struggling to figure out how to go about doing this. I feel like my solution is not only wrong, but is using a double for loop when it might not need to. Here's what I have so far.
$jsonData = Get-Content -Path $jsonFile | ConvertFrom-Json
$csvData = Get-Content -Path $csvFile | Select-Object -Skip 1 # Skipping the header
foreach ($jsonItem in $jsonData.'Placeable List') {
foreach ($csvRow in $csvData) {
$splitRow = $csvRow -split ","
$lCol = $splitRow[0]
$rCol = $splitRow[1]
$currentItem = $jsonItem.'value'.'Appearance'.'value'
if ($currentItem -eq $lCol) {
$currentItem -eq $rCol
}
}
}
I managed to figure it out.
$csvData = Get-Content -Path $csvFile | Select-Object -Skip 1 # Skipping the header
$jsonData = Get-Content -Path $jsonFile -raw | ConvertFrom-Json
foreach($csvRow in $csvData) {
$splitRow = $csvRow -split ","
$lCol = $splitRow[0]
$rCol = $splitRow[1]
foreach($item in $jsonData.'Placeable List'.value) {
$item.Appearance | % {
if ($_.value -eq $lCol) {
$_.value = $rCol
}
}
}
}
$jsonData | ConvertTo-Json -depth 32 | Set-Content $jsonFile

Convert JSON to CSV using PowerShell

I have a sample JSON-formatted here which converts fine if I use something like: https://konklone.io/json/
I've tried the following code in PowerShell:
(Get-Content -Path $pathToJsonFile | ConvertFrom-Json)
| ConvertTo-Csv -NoTypeInformation
| Set-Content $pathToOutputFile
But the only result I get is this:
{"totalCount":19,"resultCount":19,"hasMore":false,"results":
How do I go about converting this correctly in PowerShell?
By looking at just (Get-Content -Path $pathToJsonFile) | ConvertFrom-Json it looks like the rest of the JSON is going in to a results property so we can get the result I think you want by doing:
((Get-Content -Path $pathToJsonFile) | ConvertFrom-Json).results |
ConvertTo-Csv -NoTypeInformation |
Set-Content $pathToOutputFile
FYI you can do ConvertTo-Csv and Set-Content in one move with Export-CSV:
((Get-Content -Path $pathToJsonFile) | ConvertFrom-Json).results |
Export-CSV $pathToOutputFile -NoTypeInformation
You have to select the results property inside your CSV using the Select-Object cmdlet together with the -expand parameter:
Get-Content -Path $pathToJsonFile |
ConvertFrom-Json |
Select-Object -expand results |
ConvertTo-Csv -NoTypeInformation |
Set-Content $pathToOutputFile
I was getting my json from a REST web api and found that the following worked:
Invoke-WebRequest -method GET -uri $RemoteHost -Headers $headers
| ConvertFrom-Json
| Select-Object -ExpandProperty <Name of object in json>
| ConvertTo-Csv -NoTypeInformation
| Set-Content $pathToOutputFile
I end up with a perfectly formatted csv file
Trying to use Mark Wrang's answer failed for me. While Piemol's comment from Jan 30 '19 solved a basic problem with Mark Wrang's answer, it also didn't work for me.
JSON strings do not always represent rectangular data sets. They may contain ragged data. For example, the Power BI activities log outputs JSON that contains different members depending on variables like what activities occurred in the requested data or what features were available at the time.
Using Piemol's comment, I processed this JSON:
[
{
"a": "Value 1",
"b": 20,
"g": "Arizona"
},
{
"a": "Value 2",
"b": 40,
"c": "2022-01-01T11:00:00Z"
},
{
"a": "Value 3",
"d": "omicron",
"c": "2022-01-01T12:00:00Z"
},
{
"a": "Value 4",
"b": 60,
"d": "delta",
"e": 14,
"c": "2022-01-01T13:00:00Z"
}
]
The script produced this CSV:
"a","b","g"
"Value 1","20","Arizona"
"Value 2","40",
"Value 3",,
"Value 4","60",
Notice that columns c, d, and e are missing. It appears that Export-CSV uses the first object passed to determine the schema for the CSV to output.
To handle this, use the UnifyProperties function:
function UnifyProperties {
$Names = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
$InputCollected = #($Input)
$InputCollected.ForEach({
foreach ($Name in $_.psobject.Properties.Name) { $Null = $Names.Add($Name) }
})
$inputCollected | Select-Object #($Names)
}
$pathToInputFolder = (New-Object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path + "\" + "PowerBIActivities\combined\"
$pathToInputFile = $pathToInputFolder + "Activities.json"
$pathToOutputFile = $pathToInputFolder + "Activities.csv"
$content = Get-Content -Path $pathToInputFile -Raw
$psObj = ConvertFrom-Json -InputObject $content
$psObj | UnifyProperties | Export-CSV $pathToOutputFile -NoTypeInformation

Expand PSobjects to export to csv

How can I convert the PSobjects returned by Get-Help to strings and export to csv?. I think this is an easy one, but I can't quite get the format I'm looking for. From reading previous answers, I was trying:
Get-Help Get-Content | Select-Object -First 1 -Property #{
Name="temp"
Expression = { $_.Name,$_.Synopsis,$_.syntax,$_.Description }
} | Select-Object -ExpandProperty temp
Which is almost what I want, except it looks like the fields are arrays not strings. I am trying to have just one string for each element, ie (Name, Synopsis, Syntax, etc).
If I try to export that to csv, I get the lengths of the objects instead of the objects themselves:
Get-Help Get-Content | Select-Object -First 1 -Property #{
Name="temp"
Expression = { $_.Name,$_.Synopsis,$_.syntax,$_.Description }
} | Select-Object -ExpandProperty temp | export-csv -NoType -Path $env:HOME\test.txt
I suppose you want to export each property in a seperate column (your script currently only exports one). To do this, you have to select each property. For Syntax and Description I used the Out-String cmdlet to convert it to a string and removed all \r\n to get a valid CSV:
Get-Help Get-Content | Select-Object -First 1 |
Select-Object Name, Synopsis,
#{l='Syntax'; e={($_.Syntax | out-string) -replace "`r?`n"}},
#{l='Description '; e={($_.Description | out-string)-replace "`r?`n"}} |
Export-Csv -Path $env:HOME\test.txt -NoTypeInformation