Output CSV using Powershell - rest

I got a problem with understanding of output CSV file from powershell script!
I have a Request to restapi server and I'm getting a variable which contain 10 or more lines, like:
>$ExpenseDescription
Taxi to airport
Taxi to seaport
Taxi to spaceport
Taxi to home
And the I'm creating table
$tableExpenses=#"
Created On | Description | Expense Category
$ExpenseCreatedOnt | $ExpenseDescription |$ExpenseReport
$tableExpense|Out-File C:\Users\book.xls
$tableExpense|Out-File C:\Users\book.csv
And as output file I'm getting .xls and .csv!
So the problem is that I have 10 lines in variable $ExpenseDescriptionand the OutFile contain all 10 lines in 1 cell in book.xls!
How can I split them in code and make OutFile in format like this:
Created On | Description | Expense Category
10.10.2018|Taxi to airport| Money
11.10.2018|Taxi to seaport| Visa
Because now I'm having this in output
Created On | Description | Expense Category
10.10.2018 11.10.2018|Taxi to airport Taxi to seaport| Money Visa|
OK, I'll add more code)
WebRequest
$ReportURI = ("https://api.rest.com/data/query")
$ReportQuery =
#{"q"="SELECT Category,Description,CreatedOn from Expense"}
Try
{$ResponseReport = Invoke-RestMethod -Method Post -Uri $ReportURI -Headers #{"Authorization" = $SessionId} -Body ( $ReportQuery | ConvertTo-Json) -ContentType "application/json" -ErrorAction Stop}
Write-Host $ResponseReport}
ConvertTo-Json $ResponseReport
variables
$ExpenseCreatedOn = $ResponseReport.CreatedOn
$ExpenseDescription = $ResponseReport.Description
$ExpenseReport = $ResponseReport.Category.Name
table_format
$tableExpense=#"
Created On Description Expense Category
$ExpenseCreatedOn $ExpenseDescription $ExpenseReport
$tableExpense|Out-File C:\Users\book.xls
$tableExpense|Out-File C:\Users\book.csv

You're not outputting a CSV. With Out-File, you're exporting a text file.
Providing that your variables hold an array of strings, you could index into them to create an object, then use Export-Csv to export that:
foreach($i in 0..($ExpenseDescription.Count - 1)){
[array]$tableExpenses += [pscustomobject]#{
"Created On" = $ExpenseCreatedOnt[$i]
Description = $ExpenseDescription[$i]
"Expense Category" = $ExpenseReport[$i]
}
}
$tableExpenses | Export-Csv C:\Users\book.csv -NoType
$tableExpenses | Export-Csv C:\Users\book2.csv -NoType -Delimiter "|"

Related

Powershell - Using ConvertFrom-csv

I'm brand new to Powershell. I have a variable that contains comma separated values. What I want to do is read each entry in the csv string variable, and assign it to a variable. I am using ConvertFrom-csv to separate the data with headers.
How can I assign each value to a variable, or even better, use ConvertTo-csv to create a new csv string which only has, for example, columns 2/3/6/7 in it?
I would ultimately want to write that data out to a new csv file.
Here is my test code:
#Setup the variable
$Data = "test1,test2,test3,1234,5678,1/1/2021,12/31/2021"
$Data | ConvertFrom-csv -Header Header1,Header2, Header3, Header4, Header5, Header6, Header7
# Verify that an object has been created.
$Data |
ConvertFrom-csv -Header Header1,Header2, Header3, Header4, Header5, Header6, Header7 |
Get-Member
#Show header1
Write-Host "--------Value from $Data----------------------------------------"
$Data[0] #doesn't work, only displays the first character of the string
Write-Host "-----------------------------------------------------------------"
Let me suggest a different approach. If you use ConvertFrom-Csv and assign the result of a variable ($data), this will be an array of Custom Objects. You can run this through a loop that steps through the elements of the array , one at a time, and then through an inner loop that steps through the properties of each object one at a time, setting a variable with the same name as the field header and the same value as the current record's value.
I don't have code that does exactly what you want. But I'm including code that I wrote a few years back that does something similar only using Import-Csv instead of ConverFrom-Csv.
Import-Csv $driver | % {
$_.psobject.properties | % {Set-variable -name $_.name -value $_.value}
Get-Content $template | % {$ExecutionContext.InvokeCommand.ExpandString($_)}
}
Focus on the first inner loop. Each property of the current object will have a name that came from the header and a value that came from the current record of the Csv file. You can ignore the line that says ExpandString. That's just what I choose to do with the variables once they have been defined.
How can I assign each value to a variable, or even better, use ConvertTo-Csv to create a new csv string which only has, for example, columns 2/3/6/7 in it?
This is one way of automating this:
# Define the CSV without headers
$Data = "test1,test2,test3,1234,5678,1/1/2021,12/31/2021"
# Set the number of headers needed
$headers = $Data.Split(',') | ForEach-Object -Begin { $i = 1 } -Process {
"Header$i"; $i++
}
# Set the desired columns we want
$desiredColumns = 2,3,6,7 | ForEach-Object { $_ - 1 } | ForEach-Object {
$headers[$_]
}
# Convert to CSV and filter by Desired Columns
$Data | ConvertFrom-Csv -Header $headers | Select-Object $desiredColumns
Result
Header2 Header3 Header6 Header7
------- ------- ------- -------
test2 test3 1/1/2021 12/31/2021
Result as CSV
$Data | ConvertFrom-Csv -Header $headers |
Select-Object $desiredColumns | ConvertTo-Csv -NoTypeInformation
"Header2","Header3","Header6","Header7"
"test2","test3","1/1/2021","12/31/2021"

How can I store the headers of a CSV file in an array?

I have looked around and it should be fairly simple , the code I found was like this:
$headers = import-csv $file |
select-object -first 1 | foreach-object { $_.PSObject.Properties } |
select-object -expandproperty Name
but did not work, checking teh $headers will show as empty or null , i have another array which I use to check by using write-host , and the other array works fine, but the one created with the code above does not at all.
I just want to store on $headers an array that has the headers of the csv file.

How do I get the data results from Invoke-RestMethod into CSV file?

I'm trying to get the results (data) from a REST call into a CSV file.
My code is:
$results = Invoke-RestMethod -Method Get -Uri $url -Header $bearer -ContentType 'application/json'
$results
and it comes back with:
data
----
{#{type=flight-offer; id=1559566119876--1838046263; offerItems=System.Object[]}, #{type=flight-offer; id=15595...
I want to get the values from each offerItems object into a CSV file.
Expand the data property and export the nested objects to a CSV:
$results |
Select-Object -Expand data |
Export-Csv 'C:\path\to\output.csv' -NoType
However, since your data objects apparently contain an array (offerItems=System.Object[]) you'll have to mangle that array into a string first, e.g. like this:
... |
Select-Object -Expand data |
Select-Object *,#{n='offerItems';e={$_.offerItems -join ','}} -Exclude offerItems |
...
The merge operation may differ depending on what kind of data the array holds.

PowerShell export multiple objects as csv

I have two columns of data the first is a string array the second is actually an object. I am looking for a simple way of exporting this as a csv. I have a version with a foreach loop that builds each string up but it seams like over kill. I have been trying to use select and select object to get it out somehow. Note I am just a beginner at powershell so I may be missing something.
My first attempt:
$data | Select-Object -ExpandProperty reports | Select -ExpandProperty data | Select -ExpandProperty rows | Format-Table $_.dimensions
Results in:
dimensions metrics
---------- -------
{New Visitor, "Mozilla} {#{values=System.Object[]}}
My second one went as far as looping
foreach ($report in $data.reports) {
"Rows:" + $report.data.rows.Count
foreach ($row in $report.data.rows) {
$output = ""
foreach($dim in $row.dimensions) {
$output += $dim + $seporator
}
foreach($met in $row.metrics) {
foreach($v in $met.values) {
$output += $v + $seporator
}
}
#| Out-File -Append C:\Users\linda_l\Documents\debug.txt
$output
}
}
There is a potential for a lot of data here so I would really like to avoid the string building solution.
Note: Data comes from the Google Analytics reporting api
$data = Invoke-RestMethod -ContentType 'application/json' -Uri "https://analyticsreporting.googleapis.com/v4/reports:batchGet?access_token=$($token.access_token)" -Method POST -Body $analyticsRequest
reports : {#{columnHeader=; data=}}
From comment:
$data | Export-Csv -Path "C:\Users\linda_l\Documents\debug2.csv"
System.Management.Automation.PSCustomObject reports System.Object[]
Optimal output csv
New Visitor,S40 Ovi Browser,1,2
New Visitor,Safari,3,4
Note its up on Github steps for getting a refreshtoken
Data is coming from the Google analytics reporting API

Powershell pscustomobject format-table new row instead of one line

I have a very large JSON response for employees that I am trying to get into table format, export to CSV and eventually insert into SQL Server. I was able to determine how to get all of my variables from the json file, however now I am getting all of my values inserted on one row for each column instead of a new row for each employee.
Also, when I export to CSV the value turns into System.Object[].
$json1 = Invoke-webRequest -Uri $Workeruri -Certificate $cert -Headers $WorkerHeader | convertfrom-json
$table = [PSCustomObject] #{
associateOID = $json1.workers.associateOID
workerID = $json1.workers.workerID.idValue
GivenName = $json1.workers.person.legalName.givenName
MiddleName = $json1.workers.person.legalName.middleName
FamilyName1 = $json.workers.person.legalName.familyName1
} |format-table -autosize
$table | export-csv $filepath -NoTypeInformation
The columns are a small sample, there are actually probably 100 columns. However, my response returns like this:
associateOID workerID givenName
------------ -------- ---------
{1,2,3,4,5...} {a,b,c,d,e...} {Lebron James, Micheal Jordan, Steph Curry...}
I would like it to return:
associateOID workerID givenName
------------ -------- ---------
1 A Lebron James
2 B Micheal Jordan
3 C Steph Curry
Also, when exporting to CSV the response has the correct columns, but all columns return with: System.Object[].
Also, my fields that have ints and dates are not returning data. How can I fix that as well?
I have tried using sort-object, group-object, for-each loops. Nothing has worked.
you can try like this:
$json1 = Invoke-webRequest -Uri $Workeruri -Certificate $cert -Headers $WorkerHeader | ConvertFrom-Json
$table = $json1 | ForEach-Object {
[PSCustomObject] #{
associateOID = $_.workers.associateOID
workerID = $_.workers.workerID.idValue
GivenName = $_.workers.person.legalName.givenName
MiddleName = $_.workers.person.legalName.middleName
FamilyName1 = $_.workers.person.legalName.familyName1
}
}
$table | Export-Csv $filepath -NoTypeInformation
$table | Format-Table -AutoSize
Your snippet takes all the values for each column and stores them in a single object instead of iterating on the object collection converted from JSON.
Also, once you use Format-Table, data is formatted for display but not usable in the pipeline anymore. That's why I've separated display on screen and CSV export.
#sodawillow almost had it, assuming that json1.workers is the list of objects that contains your workers.
$json1 = Invoke-webRequest -Uri $Workeruri -Certificate $cert -Headers $WorkerHeader | ConvertFrom-Json
$table = $json1.workers | ForEach-Object {
[PSCustomObject] #{
associateOID = $_.associateOID
workerID = $_.workerID.idValue
GivenName = $_.person.legalName.givenName
MiddleName = $_.person.legalName.middleName
FamilyName1 = $_.person.legalName.familyName1
}
}
$table | Export-Csv $filepath -NoTypeInformation
$table | Format-Table -AutoSize