Powershell ConvertFrom-Json accessing json value - json

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.

Related

How do I extract a JSON value if another value is higher than zero?

My current code:
Powershell -Noprofile "(Get-Content 'allacts.txt' | ConvertFrom-Json).activityid | Out-File -FilePath ids%filenum%.txt"
This queries the JSON file (allacts.txt) and extracts a single value, activityid.
However, I don't want all the activityids, just the ones where the value attendedpeoplecount is higher than 0. How can I work that if logic into this command?
Sample:
[
{
"activityid": 610228,
"attendedpeoplecount": 0
},
{
"activityid": 568168,
"attendedpeoplecount": 36
}
]
Current command on the above json would return
610228
568168
The desired output would be
568168
Using the Where-Object Cmdlet should get you what you need.
Powershell -Noprofile "((Get-Content 'allacts.txt' | ConvertFrom-Json) | Where-Object { $_.attendedpeoplecount -gt 0 }).activityid | Out-File -FilePath ids%filenum%.txt"
Update: Wrapped Get-Content and ConvertFrom-Json in parenthesis

How to remove an object from a JSON file in PowerShell

I am trying to remove an object from a JSON file using PowerShell.
I read in a JSON file that has some objects in it (C:\eventStaging.json = [{"server_name":"server1","date":"2021-08-13","user":"user1"},{"server_name":"server2","date":"2021-08-13","user":"user2"}] )
The plan is to loop through each object, add that object to another json file (C:\scheduledEvent.json) and then remove that same object from where it came from (C:\eventStaging.json).
Adding each object to a different json file is easy enough. Here is what I have:
$json = Get-Content 'C:\eventStaging.json' | Out-String | ConvertFrom-Json
foreach ($j in $json){
$EventStart = Get-Content 'C:\scheduledEventStart.json' | Out-String | ConvertFrom-Json
$eventStartList += $EventStart
$eventStartList += $j
$eventStartList | ConvertTo-Json -depth 100 | Out-File 'C:\scheduledEventStart.json'
}
My problem is removing the object $j from eventStaging.json.
I have tried:
$removeStaging = Get-Content 'C:\eventStaging.json' | Out-String | ConvertFrom-Json
$removeStaging.PSObject.Properties.Remove($j)
$removeStaging | ConvertTo-Json -depth 100 | Out-File 'C:\eventStaging.json' -Force
but $removeStaging is storing nothing.
I also tried:
[System.Collections.ArrayList]$removeStaging = Get-Content 'C:\eventStaging.json' | Out-String | ConvertFrom-Json
$newStaging = $removeStaging.Remove($j)
$newStaging | ConvertTo-Json -depth 100 | Out-File 'C:\eventStaging.json'
but again, $newStaging stores nothing..
Has anyone any guidance on this please?
If you have access to PowerShell Core, you can use ConvertFrom-Json -AsHashTable when removing the scheduled event from eventStaging.json to make this a bit easier:
$removeStaging = Get-Content -Raw 'C:\eventStaging.json' | ConvertFrom-Json -AsHashTable
$removeStaging.Remove($j)
$removeStaging | ConvertTo-Json -depth 100 | Out-File 'C:\eventStaging.json' -Force
With Windows PowerShell, your final attempt with the ArrayList conversion should have worked, assuming you are trying to remove a top-level element and not a sub-property of the element. Testing with the following code shows my json file is updated with the removed element:
# Create test json file
#{Name = 'Bender'; Age = 99}, #{Name = 'Dean'; Age = 98} | ConvertTo-Json | Out-File test.json
# Import JSON as ArrayList of PSCustomObjects
[System.Collections.ArrayList]$obj = Get-Content -Raw test.json | ConvertFrom-Json
# Remove one of the objects by reference
$obj.Remove($obj[1])
# Write the JSON to file, it will only have the one entry in it
$obj | ConvertTo-Json | Out-File test.json
If you update your question with a more complete sample of this area I can evaluate further but either of the above approaches should work.
Additionally, note I've removed your use of Out-String and instead used Get-Content -Raw. The -Raw parameter tells Get-Content to parse the file as a literal string instead of returning a collection of single-lines.

Replace only first occurrence

I have a PowerShell scripts which replaces
"version" : "xxx"
with
"version" : "myBuildNumber"
Now I encountered that I have multiple of these in my file.
I only want to replace the first occurrence.
I tried already Powershell - Replace first occurrences of String but it does not work with my regex.
Here's my script:
(Get-Content myFile.txt) -replace '(?<pre>"version"[\s]*:[\s]*)(?<V>"[^\"]*")', "`$1`"$Env:BUILD_VERSION`"" | Out-File myFile.txt
Since you are patching a JSON file, regex isn't the way to go. Instead you should parse the JSON, access and change the property you want and write it back:
$filePath = 'your_Path_To_project.json'
$json = (Get-Content $filePath -raw | ConvertFrom-Json)
$json.version = $Env:BUILD_VERSION
$json | ConvertTo-Json -Depth 10 | Set-Content $filePath

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

Convert CSV to JSON and JSON to CSV using PowerShell

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