12

I am trying to put together a PowerShell script that will read data from a CSV (it is actually tab separated and not CSV but for SO, we'll use commas) and import that data into a PowerShell multidimensional array. My CSV has the following data:

EmpID,Name,Dept
12345,John,Service
56789,Sarah,Sales
98765,Chris,Director

My script is as follows:

$temp=gc "temp.csv"
$array=@()

$temp | Foreach{
    $elements=$_.split(",")
    $array+= ,@($elements[0],$elements[1],$elements[2])
}

foreach($value in $array)
{
    write-host "EmpID =" $value[0] "and Name =" $value[1] "and Dept =" $value[2]
}

The above works, but I would like is to be able to refer to the array elements by a more proper name because there are a lot more elements than are shown above and this gets confusing. To do this, I’ve tried to use hash tables, defining new objects, members, types, etc. but they never seem to work properly. I may be wrong but I feel like I’m running in a circle and now I may be lost. Basically, what I want to do is, instead of using:

write-host "EmpID =" $value[0] "and Name =" $value[1] "and Dept =" $value[2]

I would like to replace the above with something like this:

write-host "EmpID =" $value.EmpID "and Name =" $value.Name "and Dept =" $value.Dept

Is this possible? If so, can someone point me in the correct direction? The CSV is coming from another source and comes with the header row anyway (it can’t be removed except by manually editing the CSV). So I would like to use the header row to name the array columns but I don’t have to use it. My primary question (goal) here is to at least be able to name the different columns. It can be done either dynamically by using the first row imported from the CSV or by entering the names into the script itself.

Thanks

SOSidb
  • 564
  • 1
  • 13
  • 25

2 Answers2

22

You don't need to add the the Import-Csv content to an array. Import-Csv imports the data into a hash table as objects.

Hash tables store "key-value pairs." So, in hash tables you do not use a numeric index to address individual elements, but rather the key you assigned to a value.

$csv = Import-Csv "temp.csv"

foreach($item in $csv)
    {
    "EmpID = $($item.EmpID) and Name = $($item.Name) and Dept = $($item.Dept)"
    }
andrewsi
  • 10,807
  • 132
  • 35
  • 51
Legatus72
  • 221
  • 2
  • 2
13

You're working too hard. Import-CSV will work with comma separation by default, and you could handle tab delimited using -Delimiter. From there you can reference the columns by name.

Import-CSV "temp.csv" | Write-Host "EmpID=" + $_.EmpID
Tim Ferrill
  • 1,648
  • 1
  • 12
  • 15
  • 2
    Thanks for the tip. I was too busy looking too hard at unnecessary things. And yes, I am working too hard and can't wait for a vacation (three more weeks - YEAH). By using Import-CSV, I can import the CSV data directly into the array (with the header row being the names for the array elements). With your tip, by using `$array = @(Import-CSV "temp.csv")` I can produce the desired results using `$array.Name` Awesome - thanks again – SOSidb Jun 03 '14 at 13:09
  • Also, Write-Host doesn't accept pipeline inputs, but you could do `Import-CSV "temp.csv" | ForEach-Object {Write-Host "EmpID=" + $_.EmpID}` – bfhd Sep 27 '18 at 04:40