Expand PSobjects to export to csv - 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

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.

Parse/Extract JSON data in CSV file

I've hundreds of rows in CSV file while contains JSON data like below. Below is a sample of each row.
{"Id":"value","RecordType":"value","CreationTime":"value","Operation":"value"}
I tried to convert the same into CSV as below but no luck as of now.
Expected format of CSV file:
id RecordType CreationTime Operation
value value value value
$properties = #('Id', 'RecordType', 'CreationTime', 'Operation')
(Get-Content -Path-to_CSVfile -Raw | ConvertFrom-Json) |
Select-Object -Property $properties |
Export-Csv -NoTypeInformation -Path $path-to-new-csv-file
If someone has an idea about this please help me. I tried ConvertTo-Json but it's failing with error:
ConvertFrom-Json : Invalid JSON primitive: "id"
Here are the first two rows of CSV data.
{"Id":"ac325bc9-97f0-4b29-8fc4-90b80b945f6c","RecordType":20,"CreationTime":"2019-09-14T08:07:22","Operation":"AnalyzedByExternalApplication","OrganizationId":"f38a5ecd-2813-4862-b11b-ac1d563c806f","UserType":0,"UserKey":"3fee8456-6d20-4794-8219-5a7c381e965f","Workload":"PowerBI","UserId":"abcd#mail.com","ClientIP":"000.000.50.177","UserAgent":"MSOLAP 15.0 Client","Activity":"AnalyzedByExternalApplication","ItemName":"Other","DatasetName":"XYZ Driven Company","ObjectId":"Other","IsSuccess":true,"RequestId":"6836be8e-6e97-4bc9-a838-bf6e7b71e0c8","ActivityId":"7E92AE6A-F548-448D-93A8-6F5736DEA085"}
{"Id":"3a20c8a9-ef44-483a-b9c0-43e10deae9ae","RecordType":20,"CreationTime":"2019-09-14T08:07:20","Operation":"AnalyzedByExternalApplication","OrganizationId":"f38a5ecd-2813-4862-b11b-ac1d563c806f","UserType":0,"UserKey":"3fee8456-6d20-4794-8219-5a7c381e965f","Workload":"PowerBI","UserId":"abcd#mail.com","ClientIP":"000.000.50.177","UserAgent":"MSOLAP 15.0 Client","Activity":"AnalyzedByExternalApplication","ItemName":"Other","DatasetName":"XYZ Driven Company","ObjectId":"Other","IsSuccess":true,"RequestId":"02e5d772-057b-45b6-ae60-22b7fa610f98","ActivityId":"7E92AE6A-F548-448D-93A8-6F5736DEA085"}
I'm looking this data in another CSV file as below. Each value after ":" should insert into CSV as rows.
Id RecordType CreationTime Operation OrganizationId UserType UserKey Workload UserId ClientIP UserAgent Activity ItemName DatasetName ObjectId IsSuccess RequestId ActivityId
ac325bc9-97f0-4b29-8fc4-90b80b945f6c 20 2019-09-14T08:07:22 AnalyzedByExternalApplication f38a5ecd-2813-4862-b11b-ac1d563c806f 0 3fee8456-6d20-4794-8219-5a7c381e965f PowerBI abcd#mail.com 000.000.50.177 MSOLAP 15.0 Client AnalyzedByExternalApplication Other xyz Driven Company Other TRUE 6836be8e-6e97-4bc9-a838-bf6e7b71e0c8 7E92AE6A-F548-448D-93A8-6F5736DEA085
3a20c8a9-ef44-483a-b9c0-43e10deae9ae 20 2019-09-14T08:07:20 AnalyzedByExternalApplication f38a5ecd-2813-4862-b11b-ac1d563c806f 0 3fee8456-6d20-4794-8219-5a7c381e965f PowerBI abcd#mail.com 000.000.50.177 MSOLAP 15.0 Client AnalyzedByExternalApplication Other XYZ Driven Company Other TRUE 02e5d772-057b-45b6-ae60-22b7fa610f98 7E92AE6A-F548-448D-93A8-6F5736DEA085
Correct data from CSV when opened in text editor.
"{""Id"":""ac325bc9-97f0-4b29-8fc4-90b80b945f6c"",""RecordType"":20,""CreationTime"":""2019-09-14T08:07:22"",""Operation"":""AnalyzedByExternalApplication"",""OrganizationId"":""f38a5ecd-2813-4862-b11b-ac1d563abchrf"",""UserType"":0,""UserKey"":""3fee8456-6d20-4794-8219-5a7c38abcdfe"",""Workload"":""Pxyswer"",""UserId"":""abcd#mail.com"",""ClientIP"":""123.456.50.177"",""UserAgent"":""MSOLAP 15.0 Client"",""Activity"":""AnalyzedByExternalApplication"",""ItemName"":""Other"",""DatasetName"":""ABCD Driven Company"",""ObjectId"":""Other"",""IsSuccess"":true,""RequestId"":""6836be8e-6e97-4bc9-a838-bf6e7b71e0c8"",""ActivityId"":""7E92AE6A-F548-448D-93A8-6F5736DEA085""}"
If your input file contains just that single example data row the code you posted will work. If the input file contains multiple statements like that your code will not work, because it'd be invalid JSON data.
Valid JSON:
{"Id":"value","RecordType":"value","CreationTime":"value","Operation":"value"}
Valid JSON:
[
{"Id":"value","RecordType":"value","CreationTime":"value","Operation":"value"},
{"Id":"value","RecordType":"value","CreationTime":"value","Operation":"value"}
]
Invalid JSON:
{"Id":"value","RecordType":"value","CreationTime":"value","Operation":"value"}
{"Id":"value","RecordType":"value","CreationTime":"value","Operation":"value"}
To convert the latter kind of input data you need to convert each row as a separate JSON document:
$properties = 'Id', 'RecordType', 'CreationTime', 'Operation'
Get-Content 'C:\path\to\input.csv' |
ConvertFrom-Json |
Select-Object $properties |
Export-Csv 'C:\path\to\output.csv' -NoType
To export all input fields except particular ones you'd define the properties to exclude rather than the ones to include:
$exclude = 'foo', 'bar'
Get-Content 'C:\path\to\input.csv' |
ConvertFrom-Json |
Select-Object -Properties * -Exclude $exclude |
Export-Csv 'C:\path\to\output.csv' -NoType
Edit:
Apparently your input file is a CSV with only one column and no header, so you can import it via Import-Csv, but you need to specify the column header yourself. Expand the field to get the individual JSON values, then proceed as described above.
$properties = 'Id', 'RecordType', 'CreationTime', 'Operation'
Import-Csv 'C:\path\to\input.csv' -Header foo |
Select-Object -Expand foo |
ConvertFrom-Json |
Select-Object $properties |
Export-Csv 'C:\path\to\output.csv' -NoType
If you want all JSON values exported, simply omit the Select-Object $properties step.

How to get via Powershell AD computer owner attributes like email and account name?

I have a computers that have assigned to users as managedby, I want to get list in JSON format where hostname is a key, and user attributes are values.
But I stuck to get that in one command :/ and put that in json, so use csv for a while.
I run these 2 commands succesfuly:
Get-ADComputer -Filter * -property managedby | select name, managedby > C:\Windows\Temp\computerowners.csv
Get-ADUser -Filter * -SearchBase 'CN=My User,DC=example,DC=com' -Properties SamAccountName | Format-Table -Property Name, samaccountname, userprincipalname -AutoSize
where search base is managedby value from first one.
I expect to have output like that:
hostname, name, samaccountname, userprincipalname
I try to combine above 2 commands like that:
Get-ADComputer -Filter * -property managedby | foreach {get-aduser -Filter * -SearchBase $managedby -Properties name, samaccountname, userprincipalname} | select name, samaccountname, userprincipalname > C:\Windows\Temp\computerowners.csv
but it want work - as not pickup managedby properly as I understand... any help with saving that in json will be more than welcome.
You didn't define the variable $managedby that you use in the ForEach-Object loop, hence the variable is $null. You need to use the property ManagedBy of the current object in the pipeline ($_.ManagedBy).
With that said, you're making the whole thing way more complicated than it needs to be. PowerShell can do a lot of the heavy lifting for you if you allow it to. Get-ADUser can read from the pipeline, so all you need to do is pass the owner's distinguished name. You also don't need to explicitly specify the properties Name, SamAccountName and UserPrincipalName, because Get-ADUser returns them by default. Plus, since you want CSV output anyway, use Export-Csv instead of the redirection operator.
Get-ADComputer -Filter * -Property managedby |
Select-Object -Expand ManagedBy |
Get-ADUser |
Select-Object Name, SamAccountName, UserPrincipalName |
Export-Csv C:\Windows\Temp\computerowners.csv -NoType
To include the computername in the output adjust the above code as follows:
Get-ADComputer -Filter * -Property managedby |
ForEach-Object {
$computer = $_.Name
if ($_.ManagedBy) { Get-ADUser $_.ManagedBy } else { '' }
} |
Select-Object #{n='ComputerName';e={$computer}}, Name, SamAccountName,
UserPrincipalName |
Export-Csv C:\Windows\Temp\computerowners.csv -NoType
To get a datastructure that can be exported to JSON using the computername as the key for the nested user attributes a different approach would be more elegant, though. Collect all relevant user attributes in a hashtable with the computername as the key:
$computers = #{}
Get-ADComputer -Filter * -Property managedby | ForEach-Object {
$computers[$_.Name] = if ($_.ManagedBy) {
Get-ADUser $_.ManagedBy | Select-Object Name, SamAccountName, UserPrincipalName
} else {
New-Object -Type PSObject -Property #{
Name = ''
SamAccountName = ''
UserPrincipalName = ''
}
}
}
Then create an object from that hashtable and convert it to JSON:
New-Object -Type PSObject -Property $computers | ConvertTo-Json
This should get you pretty far:
Get-ADComputer -Filter * -Property ManagedBy,CN | ForEach-Object {
# only query AD if there actually is a manager
if ($_.ManagedBy) {
$manager = $_.ManagedBy | Get-ADUser
} else {
$manager = $null
}
# return a custom object with 4 properties
[pscustomobject]#{
hostname = $_.CN
name = $manager.Name
samaccountname = $manager.SamAccountName
userprincipalname = $manager.UserPrincipalName
}
}
Note: Any value created in a script block and not explicitly captured in a variable or explicitly discarded via Out-Null automatically becomes a return value of that block. In this case, the ForEach-Object body will emit a series of PSCustomObject instances.
Use the result in any way you like, for example format it as JSON or CSV.
Related reading
How do I return a custom object in Powershell that's formatted as a table?
Jonathan Medd's Blog: PowerShell v3 – Creating Objects With [pscustomobject]

Export Matches array object to CSV in Powershell

I have a powershell script to find particular instances and then export them to CSV. Here's an example of the way the code works
$items = "Hello Tim", "Hola Bob", "Hello Susan"
$filter = $items | Select-String -Pattern "Hello"
$filter | Select-Object Line, Matches | Export-Csv "C:\log.csv"
Invoke-Item "C:\log.csv"
When I run the Select-Object in PS, it's nicely formatted info like this:
However, when I export to CSV, it exports the whole object and writes it as the following string: System.Text.RegularExpressions.Match[]
How can I get it to export just the first match or a listing of all matches into a single field when writing to CSV?
Here is one way using a PSObject:
$items = "Hello Tim", "Hola Bob", "Hello Susan"
$filter = $items | Select-String -Pattern "Hello"
$filter | % {New-Object PSObject -property #{
Line = $_.Line
Matches = $_.Matches.Groups[0].Value}
} | Export-Csv "C:\log.csv" -NoTypeInformation
Quickly note that Matches is an array which may create issues exporting to a csv.
Try joining the array into a string with a chosen delimiter. I used "::" in my example.
$filter | Select Line, #{Expression={$_.Matches -join "::"}; Label="Matches"} | Export-Csv "C:\log.csv"

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