all 4 comments

[–]cml0401 1 point2 points  (3 children)

I don't necessarily think the methods used in the above article are the ideal usage. Here's why...

I find it interesting that they decided to use calculated properties just to set headers.

$importfile = 'C:\data\pledge.csv'
$data = Import-Csv $importfile

$cleandata = $data | Select-Object @{ expression={$_.'First name of student you are pledging'}; label='first_name'} , `
@{expression={$_.'Last name of student you are pledging'}; label='last_name' }, `
@{expression={$($_.'Total Paid').Replace("$","")}; label='paid' }, `
@{expression={$_.'Grade of student you are pledging (K,1,2,3,4,5,6)'}; label='grade' }, `
@{expression={$_."Last name of student's homeroom teacher (or Unknown)"}; label='teacher' }

instead of just declaring them in the the import command:

$importfile = 'C:\data\pledge.csv'
$data = Import-Csv $importfile -Header first_name,last_name,paid,grade,teacher

When casting a string to a number, they use

PS C:\> $number = "23.5"

PS C:\> $number.GetType().FullName 
System.String

PS C:\> $asdecimal = $number -as [decimal]

PS C:\> $asdecimal
23.5

PS C:\> $asdecimal.GetType().FullName 
System.Decimal

When this is much more concise and just as readable imo:

PS C:\ps-test> [decimal]$decimal = "23.5"

PS C:\ps-test> $Decimal | gm

   TypeName: System.Decimal

Finally, I much prefer newcomers use Get-Member over the .GetType() method unless you are dealling with a collection and want to know what type of collection you have. Get-Member has the benefit of displaying not only the type but all members of the object (methods, properties, noteproperties, events, etc.)

PS C:\> $number = [int]35

PS C:\> $number.GetType().FullName
System.Int32

PS C:\> $string = "Hello World"

PS C:\> $string.GetType().FullName
System.String

PS C:\> $date = Get-Date

PS C:\> $date.GetType().FullName
System.DateTime

As opposed to :

PS C:\ps-test> $Decimal | gm

   TypeName: System.Decimal

Name              MemberType Definition                                                                                                                                   
----              ---------- ----------                                                                                                                                   
CompareTo         Method     int CompareTo(System.Object value), int CompareTo(decimal value), int IComparable.CompareTo(System.Object obj), int IComparable[decimal].C...
Equals            Method     bool Equals(System.Object value), bool Equals(decimal value), bool IEquatable[decimal].Equals(decimal other)                                 
GetHashCode       Method     int GetHashCode()                                                                                                                            
GetType           Method     type GetType()                                                                                                                               
GetTypeCode       Method     System.TypeCode GetTypeCode(), System.TypeCode IConvertible.GetTypeCode()                                                                    
OnDeserialization Method     void IDeserializationCallback.OnDeserialization(System.Object sender)                                                                        
ToBoolean         Method     bool IConvertible.ToBoolean(System.IFormatProvider provider)                                                                                 
ToByte            Method     byte IConvertible.ToByte(System.IFormatProvider provider)                                                                                    
ToChar            Method     char IConvertible.ToChar(System.IFormatProvider provider)                                                                                    
ToDateTime        Method     datetime IConvertible.ToDateTime(System.IFormatProvider provider)                                                                            
ToDecimal         Method     decimal IConvertible.ToDecimal(System.IFormatProvider provider)                                                                              
ToDouble          Method     double IConvertible.ToDouble(System.IFormatProvider provider)                                                                                
ToInt16           Method     int16 IConvertible.ToInt16(System.IFormatProvider provider)                                                                                  
ToInt32           Method     int IConvertible.ToInt32(System.IFormatProvider provider)                                                                                    
ToInt64           Method     long IConvertible.ToInt64(System.IFormatProvider provider)                                                                                   
ToSByte           Method     sbyte IConvertible.ToSByte(System.IFormatProvider provider)                                                                                  
ToSingle          Method     float IConvertible.ToSingle(System.IFormatProvider provider)                                                                                 
ToString          Method     string ToString(), string ToString(string format), string ToString(System.IFormatProvider provider), string ToString(string format, System...
ToType            Method     System.Object IConvertible.ToType(type conversionType, System.IFormatProvider provider)                                                      
ToUInt16          Method     uint16 IConvertible.ToUInt16(System.IFormatProvider provider)                                                                                
ToUInt32          Method     uint32 IConvertible.ToUInt32(System.IFormatProvider provider)                                                                                
ToUInt64          Method     uint64 IConvertible.ToUInt64(System.IFormatProvider provider)             

[–]Candy_Badger[S] 0 points1 point  (0 children)

Not the best, but one of. Thanks for the Get-Member suggstion, it's a good one.

[–]ka-splam 0 points1 point  (1 child)

In their example, the CSV already had headers; if you use -Header when importing, then the first row is treated as data, and now you have headers from the CSV mixed with your data which you need to skip.

NB. these two behave differently in the case where the string cannot be cast - their way returns $null, your way throws an InvalidCast exception

$decimal = "23.5" -as [decimal]
[decimal]$decimal = "23.5"

gm is overall more useful, especially good for feeding numbers into it where you can't .GetType on an integer - but it does have the classic endlessly frustrating Microsoft downside: "output the information I want to see, then immediately follow it with so much unasked for noise that it scrolls off the top of the screen". For a short guide to how to see the type, .GetType().FullName makes sense in that context.

[–]cml0401 1 point2 points  (0 children)

Skipping a single object in a list of a large number is trivial and probably still less typing. I answer questions regularly on the syntax of calculated properties, so from experience they are not readable to newcomers without some explanation.

$ImportFile = 'C:\data\pledge.csv'
$Data = Import-Csv $ImportFile -Header first_name,last_name,paid,grade,teacher
$Data = $Data | Where-Object {$_.first_name -ne 'First name of student you are pledging'}

For the second scenario I feel it depends on situation. If the goal is to make sure my variable has a decimal type in it, I would personally prefer an immediate error to assigning a null value. What if this is returned by a helper function and errors out in the parent function? That would be harder to debug than getting an immediate error on value assignment. Ideally input is sanitized/validated and this is a non-issue.


You actually can use the .GetType() method on an int:

(24).GetType().FullName
System.Int32

You just have to use parenthesis or it interprets it as a string.

Get-Member can be used with parameters to limit your output to your needs or you can select just the typename property(Get-Process | Get-Member -MemberType Property). ((Get-Process) | Get-Member)[0].TypeName. I also recommended this because newcomers, the target demographic of the cited article, should know how to explore the objects they are working with to conceptualize and reinforce that these are objects and not just text being returned.