Transposing a CSV file using PowerShell - powershell

I have a CSV file that has a static number of columns (with headers) and a dynamic number of rows and I need convert it to another CSV which has a static number of rows and a dynamic number of columns (with or without headers).
Here is an example of what the before and after would look like in a spreadsheet. Please keep in mind that the top section would represent my input data and the bottom section is the desired state.
Of course this is a small subset as I could have a user that has 50 groups and a user which may only have 1 group associated with it. This leaves me with not knowing the number of columns in advance so it has to be dynamic.
I have tried using what I found on this post, but I am running into an issue trying to modify the code to fit my needs. The closest I have been able to do is create a row for each unique user ID but instead of having the corresponding group names in columns next to each user, they are set as the headers and no values for the users.

If you don't require headers or defined columns you could simply collect the values from the second column in a hashtable of arrays where you use the values from the first column as keys:
$data = #{}
Import-Csv 'C:\path\to\input.csv' | ForEach-Object {
$data[$_.UserID] += #($_.GroupName)
}
Then you can export the data to a text file like this:
$data.Keys | ForEach-Object {
$_ + ',' + ($data[$_] -join ',')
} | Set-Content 'C:\path\to\output.txt'

Related

How to select first column of CSV file without column name in Powershl [duplicate]

This question already has an answer here:
How to read the first column of a CSV file with powershell
(1 answer)
Closed 5 months ago.
Having issues selecting a specific column within a .CSV file in powershell without using the column name. Basically, I have a 5 column spreadsheet where I want to grab the values within the first column but do not want to rely on the column name as it might defer if I use another spreadsheet.
Is there anyway of selecting a column by number or index value and NOT name?
Inspect the properties on the object parsed from the first row by accessing the hidden psobject memberset:
$firstColumnName = $null
Import-Csv whoKnows.csv |ForEach-Object {
if($null -eq $firstColumnName){
# first row, grab the first column name
$firstColumnName = #($_.psobject.Properties)[0].Name
}
# access the value in the given column
$_.$firstColumnName
}

Extract specific values from cells from a CSV

I have to combine a lot of files , mostly CSV, already have code to combine however I need first to trim the desired csv files so I can get the data that I want. Each CSV has first 2 columns of 8 rows which contain data that I want. and then just below those there is a row that generates 8 columns. I am only having issue grabbing data from the first 8 rows of the 2 columns.
Example of the csv first 3 rows:
Target Name: MIAW
Target OS: Windows
Last Updated On: June 27 2019 07:35:11
This is the data that I want, the first 3 rows are like this, with 2 columns. My idea is to store the 3 values of the 2nd column each into a variable and then use it with the rest of my code.
As I only have a problem extracting the data, and since the way the CSV are formated there is no header at all, it is hard to come up with an easy way to read the 2nd column data. Below is an example, this of course will be used to process several files so it will be a foreach, but I want to come up first with the simple code for 1 file so I can adapt it myself to a foreach.
$a = MIAW-Results-20190627T203644Z.csv
Write-Host "$a[1].col2"
This would work if and only if I had a header called col2, I could name it with the first value on the 2nd column but the issue is that that value will change for CSV file. So the code I tried would not work for example if I were to import several files using:
$InFiles = Get-ChildItem -Path $PSScriptRoot\ *.csv -File |
Where-Object Name -like *results*
Each CSV will have a different value for the first value on the 2nd column.
Is there an easier way to just grab the 3 rows of the second column that I need? I need to grab each one and store each in a different variable.

Extract columns from a csv file with fields containing delimited values

I am trying to extract certain fields from a csv file, having comma separated values.
The issues is , some of the fields also contains comma and the fields are not enclosed within quotes. Given the scenario, how can i extract the fields.
also,only one of the field contains comma within values, and i don't need that. e.g: I want to extract the first 2 columns and the last 5 columns from the data set of 8 columns , where the third column contains values with comma
PS: Instead of down voting i would suggest to come ahead and post your
brilliant ideas if you have any.
Solution:
$path = "C:\IE3BW0047A_08112017133859.csv"
Get-Content $path| Foreach {"$($_.split(',')[0,1,-8,-7,-6,-5,-4,-3,-2,-1] -join '|')"} | set-content C:\IE3BW0047A_08112017133859_filter.csv

Import-Csv, Sort Imported Data and Counting Total Variables after Sort

I am attempting to write a powershell script importing a large csv of data. I am trying to sort the objects column by date range and counting the objects in the column. I imported the data and assigned values however when I ask for the count of the total value in the columns it counts each individual object rather than the sum of the remaining. I believe this is because it's within the foreach cmdlet.
Any ideas? I am newer to powershell.
CSV format,
ID FirstName LastName Date
1 jOHN SMITH 8/8/2016
$users=Import-Csv data.csv
foreach ($user in $users) {
$FileID=$user.ID
$FileFIRST_NAME=$user.FIRST_NAME
$FileLAST_NAME=$user.LAST_NAME
$FileDATE=$user.DA
write-host $FileFIRST_NAME.count
}
Within the foreach loop (note that this is the foreach statement, not the cmdlet), each $user is a single row from within $users (which is an array of rows).
So asking for the .Count of any property (column) of a single row, will return 1. The loop will run that N times where N is the number of rows you have, so you will see 1 many times.
You don't need the loop at all to get a count of the rows:
$users=Import-Csv data.csv
$users.Count
Since columns are a property of rows in this scenario, a count of any column will be the same as the count of the number of rows, so there's no reason to do so.

Compare rows against a date column and return matches

I have a CSV. It has 7 or 8 columns but I need to compare 2 against each other. An email column against a date column. The two columns I need have headers of "email" and "passwordlastset".
I'd like to just do an Import-Csv and where row(s) match $inactive I need it to grab those email addresses and send an email. I already have the email code ready I just need a good way to grab my list of emails against the column that has the dates. The following isn't working. I need some guidance on this if possible.
$daysInactive = 14
$inactive = (Get-Date).AddDays("-$daysInactive")
$Users = Import-Csv c:\query.csv | where {$_.passwordlastset -eq $inactive}
It would be nice to do like above but if I need to import the original CSV and dump a new one that is fine.
Where am I going wrong?
As requested here are csv headers:
headers
I need to take all entries in the email column that meet a date in the passwordlastset column.