15

In PowerShell I want to pass the name of a header in a CSV file into another function in the PowerShell script.

How can I retrieve the value-text of a header name into a variable in CSV?

e.g. if I have the following CSV data:

ID Name     Country
-- ----     -------
1  John     United States
2  Beatrice Germany
3  Jouni    Finland
4  Marcel   France

In the above example how can I retrieve the Country column value text as "Country" text into a variable in my script?

(Note: I am familiar with the notation $_.Country to retrieve the value of, for example, "Germany" from a row by importing the CSV in Powershell)

My specific issue is that currently I have the following function in my script:

function GetItemIdFromTitle([string]$LookupTitle, [ref]$LookupId)
{   
    $LookupField = $LookupList.Fields["DEPTCATEGORY"]   
    $LookupItem = $LookupList.Items | where {$_['DEPTCATEGORY'] -like "*$LookupTitle*"} 
    $LookupId.Value = $LookupItem.ID
}

This currently takes a string value -> $LookupTitle and uses that to find an item in a SharePoint list. As you can see in the script I am hard-coding in the column name as "DEPTCATEGORY". This is the column name that will be looked up to in the SharePoint list.

Instead of hard-coding the column name I want to pass in the name of the column for the corresponding $LookupTitle value and replace the hard-coded "DEPTCATEGORY".

I am calling the above function as follows:

#GET THE LOOKUP COLUMN ID       
GetItemIdFromTitle $_.DEPTCAT ([ref]$LookupIdValue)

( $_.DEPTCAT is the value from the row in the CSV column. )

Can I do something like

$myCountryColumnName = $_.Country.Property.Title 

or

$myCategoryColumnName = $_.DEPTCAT.Property.Name

to get the column name from the CSV?

motionpotion
  • 2,656
  • 6
  • 42
  • 60

6 Answers6

27

If you have an object in $obj, you could list all the property headers like this:

$obj | Get-member -MemberType 'NoteProperty' | Select-Object -ExpandProperty 'Name'

This is an array, so you can reference them individually like this:

($obj | Get-member -MemberType 'NoteProperty' | Select-Object -ExpandProperty 'Name')[0]

This would just give you the name of the first property for instance.

Raf
  • 9,681
  • 1
  • 29
  • 41
ojk
  • 2,502
  • 15
  • 17
  • I am looping through the rows in the CSV so I need to get the name of the column for the appropriate value in the row and then pass the column name to a function. – motionpotion Sep 10 '14 at 12:44
  • I don't really get what you are trying to do. If you are iterating through the rows and are accessing the values, you need the property name to do that. Could you give me an example with some more detail of what you are trying to do? – ojk Sep 10 '14 at 12:52
  • Try the amended answer – Raf Sep 10 '14 at 12:58
  • I added a more specific example to my question. – motionpotion Sep 10 '14 at 13:11
  • 1
    Ok, so you basically want to lookup the property name from a property value? I'm not really sure if this is possible, and I don't really get why you would need it. In one of your examples: `$myCountryColumnName = $_.Country.Property.Title` the property name in question is Country, but you already have that as you are using it in `$_.Country`, so why can't you just use `$myCountryColumnName = 'Country'`? – ojk Sep 10 '14 at 13:42
  • Because I wanted to get it from the name for the column in the CSV. It would be useful to do this where I don't know what the column names are but still need to import the CSV file. It would allow me to make the script more generic instead of hard-coding the column names in the script. – motionpotion Sep 10 '14 at 14:06
26

Assuming that you have already read in the CSV using Import-CSV you can examine the property of the resulting object. Similar to this answer but maintains column order in the resulting array

Examining the first row / element

$data = import-csv $path
$data[0].psobject.properties.name

So the second line will return a string array of the properties.

Matt
  • 45,022
  • 8
  • 78
  • 119
7

To get the column name from the csv, first, put the names of the column headers into an array (this will also allow you to loop through each column, if needed) ...

$inFilePath = "C:\path\to\file.csv"
$csvColumnNames = (Get-Content $inFilePath | Select-Object -First 1).Split(",")

... , secondly, index into the array by column position (index starts at 0). Given your original example it would be;

$myCountryColumnName = $csvColumnNames[2]
Adrian Torrie
  • 2,795
  • 3
  • 40
  • 61
  • 4
    Just a heads up, this solution isn't compliant with RFC-4180. It will break if there is escaped text within the CSV that contains commas. https://tools.ietf.org/html/rfc4180 – Joe the Coder Dec 04 '17 at 15:55
3

This is more of a general comment than an answer.

I needed to pull the first column header name from CSVs and I started with selecting the NoteProperty fields from Get-Member. This doesn't work because the order of the NoteProperty column header names might not match the order of the column headers in the CSV file.

futureSPQR's method will work every time because the text won't get reordered on you. Below is my one-liner version of his method to get the first column header name.

((Get-Content filename.csv)[0] -split(','))[0]
PM 77-1
  • 12,933
  • 21
  • 68
  • 111
Chris
  • 31
  • 3
  • This assumes that the `CSV` file will not have the type header that `export-csv` adds by default. If the `CSV` doesn't have that type header, you are good to go :) – Elliot Huffman Oct 16 '19 at 03:10
0
$f = Import-Csv "...csv"

Get-Member -InputObject $f[0] |
  Where-Object {$_.MemberType -eq "NoteProperty"} |
  select-object Name
ChrisF
  • 134,786
  • 31
  • 255
  • 325
0

If you're looking to check if a header name exists in the array, use below code

$Array | Get-member -MemberType 'NoteProperty'| where {$_.Name -eq "ColumnName"}
sbgib
  • 5,580
  • 3
  • 19
  • 26