You might not even realise it, but you're using a PowerShell feature called Member Enumeration which was introduced in PowerShell 3.0.
Basically, if you attempt to access a named property on an array, if the property doesn't exist on the array object itself then PowerShell will look for that property on all the items in the array and return those values in a new array instead.
For example:
PS> $csv = @"
Aman;Indore;789858585;23
Raman;Delhi;785458545;35
"@
PS> $data = $csv | ConvertFrom-Csv -Delimiter ";" -Header @("Name", "Location", "Mobile", "Age");
PS> $data
Name Location Mobile Age
---- -------- ------ ---
Aman Indore 789858585 23
Raman Delhi 785458545 35
PS> $data.Name
Aman
Raman
# note this returns an array of objects thanks to member enumeration
PS> $data.Name.GetType().FullName
System.Object[]
PS> $data.Name[0]
Aman
In your case, $data.Name
returns a new array containing the value of the Name
property on all the items in $data
- effectively @("Aman", "Raman")
. So, when you use $data.Name[0]
, you're retrieving the first item in the array created by member enumeration - i.e. Aman
- and all's well in the world...
Now, the catch is that if there's only one item in the array created by member enumeration it gets "unrolled" to be the value of the first item:
PS> $csv = @"
Aman;Indore;789858585;23
"@
PS> $data = $csv | ConvertFrom-Csv -Delimiter ";" -Header @("Name", "Location", "Mobile", "Age");
PS> $data
# Name Location Mobile Age
# ---- -------- ------ ---
# Aman Indore 789858585 23
# note this returns a single string because the "member enumeration" array
# gets unrolled if there's only one item
PS> $data.Name.GetType().FullName
System.String
PS> $data.Name
# Aman
PS> $data.Name[0]
# A
And in your case the $data.Name[0]
is equivalent to "Aman"[0]
which returns A
.
To fix this, rather than inadvertently use member enumeration by doing $data.Name[0]
, where the result can vary based on the number of items in the array, you can use one of the following:
PS> $data[0].Name
Aman
PS> @($data.Name)[0]
Aman
The first option is probably more performant in the general case, but the second is a useful workaround in some cases where the first won't work (e.g. when dealing with return values from functions / where-object
, etc).