/flags/powershell/export-csv-notypeinformation
Export-Csv -NoTypeInformation: remove the #TYPE line from CSV files
- 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:
Get-Process | Select-Object Name, Id, CPU | Export-Csv processes.csv -NoTypeInformationPowerShell 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
$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
| Parameter | Use |
|---|---|
| -Delimiter ";" | separator for regional Excel versions that expect semicolons |
| -UseCulture | use the list separator of the current culture |
| -Encoding UTF8 | 5.1 default is ASCII (non-ASCII characters become ?); UTF8 writes a BOM in 5.1. PowerShell 7 defaults to UTF-8 without BOM |
| -Append | add rows to an existing file (columns must match, or use -Force) |
| -NoClobber | do 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:
$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 -NoTypeInformationOutput
--- 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-TableandFormat-Listproduce formatting records; exporting them writes columns such asClassId2e4f51ef21dd47e99d3c952918aff9cd. UseSelect-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.
-Appendfails with "Cannot append CSV content to the following file" when a new object lacks one of the existing columns;-Forcewrites 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 UTF8for 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'sUTF8value 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
- learn.microsoft.comlearn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/export-csv
- learn.microsoft.comlearn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertto-csv
- learn.microsoft.comlearn.microsoft.com/en-us/powershell/scripting/whats-new/differences-from-windows-powershell