Skip to content

/flags/powershell/export-csv-notypeinformation

Export-Csv -NoTypeInformation: remove the #TYPE line from CSV files

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
PowerShell
command
Export-Csv
flag
-NoTypeInformation (-NTI)
default
type line written in Windows PowerShell 5.1; omitted in PowerShell 6+

In Windows PowerShell 5.1, Export-Csv and ConvertTo-Csv write a first line such as #TYPE System.Management.Automation.PSCustomObject before the header. Excel and most CSV readers show it as data. Add -NoTypeInformation:

powershell
Get-Process | Select-Object Name, Id, CPU | Export-Csv processes.csv -NoTypeInformation

PowerShell 6 and later do not write the type line by default (-NoTypeInformation is still accepted and does nothing); use -IncludeTypeInformation there if you want it.

See the difference

powershell
$rows = [pscustomobject]@{ Name = 'alpha'; Size = 1 }, [pscustomobject]@{ Name = 'beta'; Size = 2 }
$rows | Export-Csv default.csv
'--- Export-Csv (Windows PowerShell 5.1):'
Get-Content default.csv
$rows | Export-Csv clean.csv -NoTypeInformation
'--- Export-Csv -NoTypeInformation:'
Get-Content clean.csv
'--- default encoding in 5.1 with a non-ASCII value:'
[pscustomobject]@{ City = 'Zürich' } | Export-Csv city.csv -NoTypeInformation
(Get-Content city.csv)[1]

Output

--- Export-Csv (Windows PowerShell 5.1):
#TYPE System.Management.Automation.PSCustomObject
"Name","Size"
"alpha","1"
"beta","2"
--- Export-Csv -NoTypeInformation:
"Name","Size"
"alpha","1"
"beta","2"
--- default encoding in 5.1 with a non-ASCII value:
"Z?rich"

Other Export-Csv parameters that matter

ParameterUse
-Delimiter ";"separator for regional Excel versions that expect semicolons
-UseCultureuse the list separator of the current culture
-Encoding UTF85.1 default is ASCII (non-ASCII characters become ?); UTF8 writes a BOM in 5.1. PowerShell 7 defaults to UTF-8 without BOM
-Appendadd rows to an existing file (columns must match, or use -Force)
-NoClobberdo not overwrite an existing file
-UseQuotes AsNeeded (PowerShell 7)quote only fields that need it; 5.1 always quotes every field

When to use it

Add -NoTypeInformation to every Export-Csv and ConvertTo-Csv call in scripts that may run in Windows PowerShell 5.1: reports for Excel, files loaded into a database, data sent to another system. The #TYPE line is a PowerShell convention that no other CSV reader understands, so it becomes a bogus first row or breaks header detection. Because PowerShell 6 and later accept the switch and ignore it, writing it is safe on every version; the short alias -NTI works too.

Nested values do not survive

CSV is flat. Each property is converted to a string, so an array or an object becomes its .NET type name. Flatten it with a calculated property first:

powershell
$o = [pscustomobject]@{ Name = 'web01'; Tags = @('prod', 'eu') }
'--- array property as is:'
$o | ConvertTo-Csv -NoTypeInformation
'--- joined with a calculated property:'
$o | Select-Object Name, @{ n = 'Tags'; e = { $_.Tags -join ';' } } | ConvertTo-Csv -NoTypeInformation

Output

--- array property as is:
"Name","Tags"
"web01","System.Object[]"
--- joined with a calculated property:
"Name","Tags"
"web01","prod;eu"

For data with nesting, export JSON instead and set a sufficient ConvertTo-Json -Depth.

Pitfalls

  • Format cmdlets before export. Format-Table and Format-List produce formatting records; exporting them writes columns such as ClassId2e4f51ef21dd47e99d3c952918aff9cd. Use Select-Object.
  • Columns come from the first object. Export-Csv writes the header from the properties of the first object. Later objects with extra properties lose them, so select the same property list for every object.
  • Append with different columns. -Append fails with "Cannot append CSV content to the following file" when a new object lacks one of the existing columns; -Force writes it anyway, leaving that column empty and dropping properties that have no column.
  • Encoding. In 5.1 the default encoding replaces non-ASCII characters with ?, as the first example shows. Pass -Encoding UTF8 for names with accents; in PowerShell 7 the default is already UTF-8 without a BOM. Excel may need the BOM to detect UTF-8, which is why 5.1's UTF8 value is often what Excel users want.

FAQ

Is -NoTypeInformation needed in PowerShell 7?

No. Since PowerShell 6.0 Export-Csv and ConvertTo-Csv omit the #TYPE line by default. The switch is still accepted, so scripts that must run in both 5.1 and 7 can keep it.

Why does a column contain System.Object[] instead of my values?

Export-Csv converts each property to a string with ToString(). Arrays and nested objects turn into their type name, so join them or pick a sub-property with a calculated property before exporting.

Does the #TYPE line matter when I read the file back with Import-Csv?

Import-Csv skips it and uses it to tag the imported objects with the original type name prefixed by CSV: (for example CSV:System.Management.Automation.PSCustomObject). Without it, the objects are plain CSV objects; the property values are the same strings either way.

Sources