0

I have the following in a script:

$Loc = Read-Host "Please select a location number"
$ImpCSV = Import-Csv -Delimiter ";" -Path "file.csv" -Header loc,add | Where-Object {$_.loc -eq "$Loc"}
Foreach ($CIM in $ImpCSV) {$LocInfo = $CIM}

This seems to create some sort of hash/array/something variable for $Loc=1. If I enter:

$LocInfo.add

It gives me the value of that key(?) as it should in a hash table, but if I do:

$LocInfo

I get:

loc        : [1]
add       : [some value]

Which is not the usual hash output. This is what one should look like:

Name         Value
----              -----
loc              [1]
add            [some value]

The issue this is first causing me is that if I try to edit an entry using $LocInfo.Set_Item("add", "HI"), it does nothing. Also, I created a table to display those variables creating new-objects, but the new -property command won't take $LocInfo.add, returning a "@{loc=1; add=some value}" if not giving me a syntax error. What I had to do was:

Set-Variable -Name add -Value $LocInfo.add

This sets add to [some value] and then I can put that in the new-object field without any issue.

This is additionally problematic because my script loops so they can add another location (loc) number (let's say 2) and pull up that location's data as necessary. If the new location they are searching has say the add (Address) missing, instead of creating a blank $LocInfo.add and then a blank $add, it skips it, meaning when the new-object is created again, it uses the $add from the previous run, [some value]; ie both loc 1 and 2 have the same $add value.

What that heck did I create, and how can I do anything with it? Is there a better way to pull variables from a CSV file that won't screw me up like this? Did I break Powershell? I've looked all over and I can't find this kind of variable arrangement.

This is the error I get when I try to do a Set_Item:

Method invocation failed because [System.Management.Automation.PSCustomObject] does not contain a method named 'Set_Item'.
At line:1 char:1
+ $LocInfo.Set_Item("add", "HI")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : InvalidOperation: (Set_Item:String) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound

I've created objects using New-Object, and even those display like a hash table, ie with a header and multiple columns depending on the object size.

2
  • I'm starting to answer it myself...after a few hours of searching the web. Commented Oct 27, 2014 at 8:47
  • Please consider marking one of the answers as the solution. Commented Jan 31, 2024 at 22:17

3 Answers 3

2

First thing: If you are ever not sure about the type of an object you can just check and object's type with GetType(). Import-Csv command returns a System.Object[] where a command like this @{Letter="Test"}.GetType().FullName would return System.Collections.Hashtable. .FullName returns the just the strings I am using in these examples.

Appears that you are trying to collect your output with the Where-Object using this line Foreach ($CIM in $ImpCSV) {$LocInfo = $CIM} The couple of issues I see with that are your keep overwriting $LocInfo with $CIM. At the end of the loop you will only have one variable. If you are trying to keep all of them would need to append each item and declare $LocInfo as an array.

$LocInfo = @()
....
Foreach ($CIM in $ImpCSV) {$LocInfo += $CIM}

But unless you have more code that you are not showing this appears redundant as you would have $LocInfo and $ImpCSV populated with the same data. You could just do away with the for loop altogether and just do this.

$Loc = Read-Host "Please select a location number"
$ImpCSV = Import-Csv -Delimiter ";" -Path "file.csv" -Header loc,add | Where-Object {$_.loc -eq "$Loc"}

I have changed nothing except remove the last line.

Sign up to request clarification or add additional context in comments.

4 Comments

Typos happen. No biggie.
I tried it this way and it did generate an array, but $LocInfo[0] gives me: <br> loc : 1<br>add : [somevalue]<br> and $LocInfo[1] gives me nothing. And yes, I am not giving all the data, as the reason it displays as list is because I have about 12 entries. I was hoping to do $LocInfo[0] giving me entry one, [1] giving me entry two, etc..instead this way [0] gives me the entire psobject as a list, but I can still do a $LocInfo.add and I get [some value]. And yes I can see where creating the $ImpCSV and then doing the Foreach the way I currently have it is redundatnt as both are PSobjects.
@user3377627 please update your post with some sample data from file before import
@user3377627 and the output produced by that sample input.
1

Import-Csv reads a CSV file and transforms it into a list of custom objects with the CSV columns as properties. However, objects with just 2 properties should be displayed in table format by default:

PS C:\> cat 'C:\test.csv'
1,foo
2,bar
3,baz
PS C:\> $csv = Import-Csv 'C:\test.csv' -Header loc,add | ? {$_.loc -eq '2'}
PS C:\> $csv

loc        add
---        ---
2          bar

You should only get output in list format if you pipe the object(s) into the Format-List cmdlet:

PS C:\> $csv | Format-List

loc : 2
add : bar

or if the objects have 5 or more properties:

PS C:\> cat 'C:\test2.csv'
1,foo,a,a,a
2,bar,b,b,b
3,baz,c,c,c
PS C:\> Import-Csv 'c:\test2.csv' -Header loc,add,f3,f4 | ? {$_.loc -eq '2'}

loc        add        f3        f4
---        ---        --        --
2          bar        b         b

PS C:\> Import-Csv 'c:\test2.csv' -Header loc,add,f3,f4,f5 | ? {$_.loc -eq '2'}

loc : 2
add : bar
f3  : b
f4  : b
f5  : b

You can enforce tabular output for objects that would normally be displayed in list format by piping them into the Format-Table cmdlet:

PS C:\> Import-Csv 'C:\test2.csv' -Header loc,add,f3,f4,f5 |
>> ? {$_.loc -eq '2'} | Format-Table
>>

loc        add        f3        f4        f5
---        ---        --        --        --
2          bar        b         b         b

Note, however, that formatting cmdlets like Format-List or Format-Table are intended for displaying data. Don't use them if you want to further process the object(s).

Comments

0

Does converting the result of import-csv into custom object like this help?

$ImpCSV = Import-Csv -Delimiter ";" -Path "file.csv" -Header loc,add | Where-Object {$_.loc -eq "$Loc"} | %{[pscustomobject]@{LOC=$_.LOC;ADD=$_.ADD}}

or

$ImpCSV = Import-Csv -Delimiter ";" -Path "file.csv" -Header loc,add | Where-Object {$_.loc -eq "$Loc"} | %{new-object -TypeName PSCustomObject -Property @{LOC=$_.LOC;ADD=$_.ADD}}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.