Some cmdlets, like Export-Csv and ConvertTo-Csv (described as: “Converts objects into a series of comma-separated value (CSV) variable-length strings.“) expect flat file as input. Meaning, if you supply any complex object like an embedded array, hash table or object, it will output nothing more than:

Which is is quiet useless and probably not what you expect. Something similar will also happen if you group objects (using Group-Object) as the group properties are embedded in a deeper Group object.

This cmdlet might help to resolve this as it recursively flattens every property of any embedded array, hash table or object to property at root of the object.



<Object[]> Flatten-Object [-Separator <String>] [-Base "" | 0 | 1] [-Depth <Int>] [-Uncut<Int>] [ToString <Type[]>]

Flatten-Object <Object[]> [[-Separator] <String>] [[-Base] "" | 0 | 1] [[-Depth] <Int>] [[-Uncut] <Int>] [[ToString] <Type[]>]


-Object[] <Object[]>

The object (or objects) to be flatten.

-Separator <String> (default: .)

The separator used between the recursive property names. .

-Depth <Int> (default: 5)

The maximal depth of flattening a recursive property. Any negative value will result in an unlimited depth and could cause a infinitive loop.

-Uncut <Int> (default: 1)

The number of object iterations that will left uncut. Further object properties will be limited to just the DefaultDisplayPropertySet. Any negative value will reveal all properties of all objects.

-Base "" | 0 | 1 (default: 1)

The first index name of an embedded array:

  • 1, arrays will be 1 based: <Parent>.1, <Parent>.2, <Parent>.3, …
  • 0, arrays will be 0 based: <Parent>.0, <Parent>.1, <Parent>.2, …
  • "", the first item in an array will be unnamed and than followed with 1: <Parent>, <Parent>.1, <Parent>.2, …

-ToString <Type[]= [String], [DateTime], [TimeSpan]> (default: [String], [DateTime], [TimeSpan])

A list of value types that will be converted to string rather the further flattened. E.g. a [DateTime] could be flattened with additional properties like Date, Day, DayOfWeek, etc. but will be converted to a single (String) property instead.

The parameter -Path is for internal use but could but used to prefix property names.


Flatten a custom object:

Flatten grouped objects:

$csv | Group Name | Flatten | Format-Table # https://stackoverflow.com/a/47409634/1701026

Flatten common objects:

$MyInvocation | Flatten-Object

Get-Process | Select -First 1 | Flatten-Object

Or a list (array) of system objects:

Get-Service | Flatten-Object -Depth 3 | Export-CSV Service.csv

Note that a command as below could take hours to complete:

Get-Process | Flatten-Object | Export-CSV Process.csv

Why? because it results in a table with a few hundred rows and several thousand columns. So if you if would like to use this for flatting process, you beter limit the number of rows (using the Where-Object cmdlet) or the number of columns (using the Select-Object cmdlet).

The Flatten-Object cmdlet was originally published at StackOverflow

Leave a Reply