how to grab specific json nested values in powershell? - json

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

Related

Error trying to get data from JSON file in PowerShell [duplicate]

The txt file is just a bunch of UNC paths, i am trying to get a list of UNC paths from this text file put into another text file after the test-path is validated. it shows the validated paths on screen but the text file does not populate.
$cfgs = Get-Content .\cfgpath.txt
$cfgs | % {
if (Test-Path $_) { write-host "$_" | Out-File -FilePath c:\temp\1.txt -Append }
}
To complement Zam's helpful answer with background information:
Write-Host writes to the host[1] (typically, the console aka terminal), which bypasses PowerShell's success output stream and therefore sends nothing trough the pipeline.
See the bottom section of this answer for when Write-Host is appropriate; in short: you should generally only use it for display-only output.
Write-Output is the appropriate cmdlet for producing data output, but it is rarely necessary, because you can rely on PowerShell's convenient implicit output behavior, as shown in Zam's answer and explained in this answer.
Also, your command will perform much better if you simply pipe the % (ForEach-Object) command's output as a whole to a single Out-File call, rather than calling Out-File -Append for each input path.
Instead of using % with conditional explicit output, you can more elegantly implement your command with the Where-Object cmdlet:
Get-Content .\cfgpath.txt |
Where-Object { Test-Path $_ } |
Out-File -FilePath c:\temp\1.txt
Also note that for saving strings to a file it is more efficient to use Set-Content instead of
Out-File, though note that in Windows PowerShell the default output character encoding differs (no longer a concern in PowerShell [Core] 6+, which consistently defaults to BOM-less UTF-8); see this answer for when to choose which cmdlet.
By contrast, Out-File and > (its effective alias) use PowerShell's formatting system to write for-display representations of any non-string input objects to the output file, the same way that output renders to the display by default.
In other words: To save objects to a file in a way that is suitable for later programmatic processing, you need to use a structured file format, such as CSV (Export-Csv) or JSON (ConvertTo-Json, combined with Set-Content).
[1] In PowerShell 5.0 and higher, Write-Host now writes to a new stream, the information stream (number 6), which by default prints to the host. See about_Redirection.
Therefore, a 6> redirection now technically does allow you to send Write-Host output through the pipeline (though doing so is not a good idea) or capture / redirect it; e.g.,
Write-Host hi 6>&1 | % { "[$_]" }. Note that the type of the objects output by this redirection is System.Management.Automation.InformationRecord.
Write-Host only writes to the console. I believe what you want there is Write-Output.
$cfgs = Get-Content .\cfgpath.txt
$cfgs | % {
if (Test-Path $_) { write-output "$_" | Out-File -FilePath c:\temp\1.txt -Append }
}
Additionally you can just omit the Write-Output and that works too.
$cfgs = Get-Content .\cfgpath.txt
$cfgs | % {
if (Test-Path $_) { "$_" | Out-File -FilePath c:\temp\1.txt -Append }
}

Powershell Out-GridView from JSON file

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

Refer to .CSV for filenames, then Locate and Delete Files Recursively

I'm trying to write a PowerShell script which refers to a CSV file for a list of banned file names (mostly games) and removes them from my users' home folders. I've got it working in the root or target directory, but cannot seem to make it recursive, so that it drills-down through subfolders, despite trying to utilise the -recurse parameter.
As you'll see, I'm not much of a coder, but am trying to learn and better myself. My PS script looks like this:
cd "C:\Test user"
Import-Csv "C:\Games.csv" | foreach {Remove-Item $_.Game -Verbose -Recurse}
and my CSV file looks like this:
Game,Game1.swf,Game2.swf,Game3.swf
Any advice as to what I am missing in order to make this work recursively would be hugely appreciated. Thank you all in advance for being so generous with your time.
You're misunderstanding the structure of CSVs. Essentially CSV is a way to store tabular data (data organized in rows and columns). Your file would have to have the following structure if you want it to work with the code you posted:
Game
Game1.swf
Game2.swf
Game3.swf
The data you posted is just a comma-separated list of values. To process this string you need something like this:
(Get-Content "C:\Games.csv") -split ',' | Remove-Item -Verbose -Recurse
or perhaps like this (if you want to skip the first element):
(Get-Content "C:\Games.csv") -split ',' |
Select-Object -Skip 1 |
Remove-Item -Verbose -Recurse
Edit: If you need to recursively search a folder tree for files from your CSV and then delete just the files you'd do it like this:
$root = 'C:\root\folder'
$items = (Get-Content "C:\Games.csv") -split ',' | Select-Object -Skip 1
Get-ChildItem $root -Recurse -Force |
Where-Object { $items -contains $_.Name } |
Remove-Item -Verbose

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.

Merge CSV files with filtering

I've started to play around with PowerShell some time ago, in order to filter some logs one of my servers is creating.
The individual log is a CSV in text file, where first line is some info about the process creating it. Headers are on the 2nd line, and the actual things are on the 3rd. There are about 15 properties, but I only need couple of them.
Here is what works for me flawlessly on one file:
Import-csv file.txt | Select-Object -Skip 1 -Property prop1, prop2, prop3, prop4, prop5 | Export-csv result.csv -NoTypeInformation
But, whatever I tried to use for multiple files (let's say, all .txt files in said folder, since the logs are created per day, and grouped in folders), it doesn't work for me, and I suspect it's because of the different first line, which I try to skip the same way, but I then get empty merged CSV file with only prop1 as 1st column
Any help is appreciated, thanks!
If the headers are actually on the second line, not the first, then you should probably do
Get-Content file.txt | Select-Object -Skip 1 | ConvertFrom-Csv | Export-Csv result.csv -NoTypeInformation
Because this strips the first line before it gets parsed as CSV.
If you want to merge multiple files in the same way, you can do that similarly:
Get-ChildItem *.txt | ForEach-Object {
Get-Content $_ | Select-Object -Skip 1 | ConvertFrom-Csv
} | Export-Csv result.csv -NoTypeInformation