The main difference between DataTable and a list of PowerShell objects is the fact that for a DataTable all item properties, including the item types, are the same for each ‘column’ were a list of PowerShell objects has all properties, including the type, defined with each specific item. This means that a list of PowerShell objects could have e.g. a DataTime object and a Int16 in the same column which is not possible in a DataTable (unless you convert them both to a string).

In this known fact lies also the trap for most of the currently available ConvertTo-DataTable cmdlets on the internet as they presume the column type of DataTable on only the first object (row). Therefore a simple custom object as below either causes an error or values to be parsed to strings:

Similar issues occur when the first object contains items that are $Null, where the whole column is often presumed as a String type but should be e.g. a DateTime type:

The solution would be to find the best fitted (smallest) common type of all the object in a column which will take time and isn’t always that simple to define. Take e.g. two types like UInt16 and Int16, you can’t take either of the types because one type doesn’t completely contain the other type. The smallest value of a UInt16 is 0 whereas the smallest value of a Int16 is -32768 and the largest value of a UInt16 is 65535 whereas the largest value of a Int16 is 32767. Meaning, in this case the best fitted (smallest) common type is neither of the original types but either: UInt32 or Int32*.

The ConvertTo-DataTable cmdlet below will automatically resolve the best fitted (smallest) common type and used that for the column type.

* The cmdlet purposed here, will take it preference (signed vs. unsigned) based on with type is found first



<Object> | ConvertTo-DataTable [-ColumnType] <HashTable>


[-Object] <Object>

The object(s) to be converted to a DataTable.

[-ColumnType] <HashTable>

Type definition of each column by name: @{<ColumnName> = <Type>; ...}


Converting a custom object to a data table

$DataTable = $MyObject | ConvertTo-DataTable

Defining the column types:

$DataTable = $MyObject | ConvertTo-DataTable -ColumnType @{Name = [String]; Value = [Int64]; Date = [DateTime]}

Convert (PowerShell) process object

$DataTable = Get-Process 'PowerShell' | ConvertTo-DataTable

Convert User Language List

$DataTable = Get-WinUserLanguageList | ConvertTo-DataTable

Leave a Reply