Powershell Out-GridView from JSON file - json

I want to load a JSON file and show it in a powershell GridView. I was hoping this would work:
'[{"a":1,"b":2},{"a":3,"b":4},{"a":5,"b":6}]' | ConvertFrom-Json | Out-GridView
But that just shows me this unhelpful view:
How can I transform the list into something the grid view understands?

('[{"a":1,"b":2},{"a":3,"b":4},{"a":5,"b":6}]' | ConvertFrom-Json) | Out-GridView
# or
$converted = '[{"a":1,"b":2},{"a":3,"b":4},{"a":5,"b":6}]' | ConvertFrom-Json
$converted | Out-GridView
This is a peculiarity of ConvertFrom-Json and anything that uses it implicitly (like Invoke-RestMethod). It doesn't seem to pass objects along the pipeline as you would expect, so you must complete the pipeline to get the objects, and then use them afterwards.
One way to do that is to assign it to a variable, another way is to wrap it in parentheses ( ).
I am not certain why this is the case, but I imagine it's an implementation detail about what it does internally and how it returns its objects.
I was trying to see if I could dig more into this, using ForEach-Object to see what's going wrong, but instead it actually just worked, so here's another way to get it working, but in a single pipeline (by using a superfluous ForEach-Object):
'[{"a":1,"b":2},{"a":3,"b":4},{"a":5,"b":6}]' | ConvertFrom-Json | ForEach-Object { $_ } | Out-GridView
# non-scrolling
'[{"a":1,"b":2},{"a":3,"b":4},{"a":5,"b":6}]' | ConvertFrom-Json | % { $_ } | ogv

Related

Can't combine col selection with CSV conversion

I've successfully been using jq for a while now, to take a JSON payload, select some of the columns, re-name the columns, and finally, create a JSON file. This is awesome bc I do not need a majority of the columns in the input dataset. Here is an example of one of those working commands:
curl -s https://c2.scryfall.com/file/scryfall-bulk/default-cards/default-cards-20220314210303.json
| jq '[.[] | {oracle_id: .oracle_id, scryfall_id: .id, rarity: .rarity, set_code: .set, latest_price: .prices.usd, scryfall_url: .scryfall_uri, art_crop_url: .image_uris.art_crop, is_digital: .digital, is_promo: .promo, is_variation: .variation}]' > Desktop/printings.json
However, what I really need is to have this data in CSV format. I have been manually working around this by feeding the output of the command above into a free web tool for converting to CSV. But I recently learned that jq can output CSV itself, so I would like to streamline this so I can just get CSV data from jq in the first place. I read the jq documentation, and reviewed several Stack Overflow threads to learn how this works. But none of the examples I've found for generating CSV data with jq involve selecting specific columns or re-naming those columns. So I've not been able to get this to work.
I tried this command below, where I am attempting to 1) read in the JSON file from the scryfall.com endpoint, then 2) map the keys as rows and columns to prep to convert to the CSV format, and 3) apply a filter selecting each of the 10 columns I need. (I could not figure out the column re-naming part, so I removed that part for now, for the sake of simplicity):
curl -s https://c2.scryfall.com/file/scryfall-bulk/default-cards/default-cards-20220314210303.json
| jq -r '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | .oracle_id | .id | .rarity | .set | .prices.usd | .scryfall_uri | .image_uris.art_crop | .digital | .promo | .variation | #csv' > Desktop/printings.csv
The result is this error:
jq: error (at <stdin>:67121): Cannot index array with string "oracle_id"
I'm not sure why "| .oracle_id" would be indexing anything. My intent is to filter the data. However, I think my struggle is an algorithmic one. Should I try to use pipes to sequence the different steps of selecting columns and generating the csv? Or should I combine them? If I need to separate the steps, what order do they need to come in? I understnad that the #csv filter at the end must take an array as input, but that's where I start to lose the plot.
Since the input JSON file is a freely-available, public dataset, you should be able to try this out to see if you get the same error output I showed above.
In general, you should try breaking out each "group" and testing separately, to see if it is mapping as you expect it to.
$cols maps out all the keys across all records while $rows are all the values of the records. You already have the rows and records you wanted so pass to #csv. Though keep in mind arrays passed to #csv must be all strings.
(map(keys) | add | unique) as $cols
| map(. as $row | $cols | map($row[.] | tostring)) as $rows
| $cols, $rows[]
| #csv
This however selects all mapped columns. If you only want a subset of them, just change the $cols variable to be what columns you want from the data. You might want to separate the value mapping from this since you have some nested values.
["oracle_id", "id", "rarity", "set", "price", "scryfall_uri", "image_uri", "digital", "promo", "variation"],
(.[] | [.oracle_id, .id, .rarity, .set, .prices.usd, .scryfall_uri, .image_uris.art_crop, .digital, .promo, .variation])
| #csv
jqplay

ConvertFrom-Json output doesn't work for Select-Object

I am using PowerShell 4 to make a series of web requests. From one call I get a generic array - for the sake of discussion it looks like this
$data = '[{"Id":"1","Name":"One"},{"Id":"2","Name":"Two"}]'
I am trying to parse this data to pull out the Name properties. However, when I use the following call it writes a line with Name and no information under it:
$data | ConvertFrom-Json | Select-Object Name
But if I save the object to an intermediate object like this it works:
$o1 = $data | ConvertFrom-Json
$o1 | Select-Object Name
I get the proper output.
The object types are different but I don't understand why. Here's output from relevant Get-Member calls:
$test | ConvrtFrom-Json | gm
TypeName: System.Object[]
and
$o1 | gm
TypeName: System.Management.Automation.PSCustomObject
Can anyone help me understand what I'm doing wrong in terms of my collection management? I'd like to be able to do this in one statement.
It seems like the parentheses are needed for some mysterious reason, as OP pointed out in the comment. Adding parentheses was the fix for me as well.
I am not sure why this breaks without parens, but I can confirm that code without parens is not an issue when executed in powershell core.

Can I assign Variables from selected Row using out-gridview -passthru

I'm very new to PowerShell and I'm trying to build on older batch files that I made into PowerShell and add some features.
At the moment I have a CSV file which I've used in the pass as a sort of "environment" file, previously I would do batch jobs against this CSV file.
I have a line
Import-Csv "csvfile" | select-object -property * | out-gridview -passthru
The CSV file is built something like:
Name,location,folder
Test,e,Testsite
Test1,c,windows
test2,c,temp
Basically I want to select one of the grows and click Okay and assign the 3 items to variables.. $foldername,$driveLetter,$destinationDirectory
I've looked high and low and I can't seem to manage it I did find one example on StackOverflow which I shamelessly copied, massaged and got to work ... but that gridview is prebuilt by the OP of that post and doesn't have things like the piping to grid-view.-Passthru has (Filter & scroll bar) but I was able to assign variables using this method but my CSV is pretty huge and I want to be able to have it auto size itself and filter / scroll.
You need to use the -OutPutMode Single option of Out-Gridview to restrict selection to a single item from the gridview.
Import-Csv "csvfile" |
select-object -property * |
out-gridview -OutputMode Single -Title 'Select a row' |
ForEach-Object {
$foldername,$driveLetter,$destinationDirectory = $_.Name,$_.location,$_.folder
}

Export the result to CSV Azure PowerShell Warnign Sign

I am assuming this warning is causing problem.
WARNING: GeoReplicationEnabled property will be deprecated in a future
release of Azure PowerShell. The value will be merged into the
AccountType property
because when I did this command
Get-AzureWebsite | export-csv -Path "C:\Users\km\Desktop\AzureProject\Hello Pay-As-You-Go-Website.csv"
my CSV file is totally fine
SO the problem I am having is
When I execute this command
Get-AzureStorageAccount | Format-Table -Property StorageAccountName, Location, AccountType, StorageAccountStatus
The result is like this
StorageAccountName Location AccountType
StorageAccountStatus
--------------------- --------- ------------ -------------------- HelloSushi East US Standard_GRS Created
WARNING: GeoReplicationEnabled property will be deprecated in a future
release of Azure PowerShell. The value will be merged into the
AccountType property.
and I add this code to move this result to CSV like this
Get-AzureStorageAccount | Format-Table -Property StorageAccountName, Location, AccountType, StorageAccountStatus | export-csv -Path "C:\Users\km\Desktop\AzureProject\Susco Pay-As-You-Go-Storage.csv"
but I checked on CSV.file, it is totally does not make sense. it is not same one.
so ,
I would like to show the result exactly on CSV like when I did this code
Get-AzureStorageAccount | Format-Table -Property StorageAccountName, Location, AccountType, StorageAccountStatus
How can I do that?
Try Out-File instead of Export-CSV it is giving the exact same output as console
==
You can't do a Format-List to Export-Csv, this link explains it.

how to grab specific json nested values in powershell?

I have this command here:
(Get-Content output.json -Raw | ConvertFrom-Json) | Convertto-CSV -NoTypeInformation
that pulls json file and puts all the top levels into a csv format. however, i want some nested values inside there as well. I know there is a command -depth that wlil pull all values at a certain depth, but I only wnat to specify a certain one. For example, if I want to pull /data/1/structure/name, how would I get that value specifically as well?
Use Select-object:
(Get-Content output.json -Raw |Select value1,Valu2,Valu | ConvertFrom-Json) | Convertto-CSV -NoTypeInformation