PowerShell 的 Export-Csv
命令和 PowerShell 的 Import-Csv
命令允许管理员通过 foreach 循环导入 CSV 文件,使用 Export-Csv
来追加 CSV 文件并将数组导出到 CSV 文件,还有更多功能。
在本文中,您将学习到许多常见的情景,可以使用 PowerShell 来管理 CSV 文件,比如:
- 使用 PowerShell 读取 CSV 文件
- 使用 PowerShell 保存 CSV 文件
- 在运行
Export-CSV
之前格式化输出 - 追加到 CSV 文件
- 将差异追加到现有文件
Export-CSV
和#TYPE
字符串
如果您不熟悉 CSV 文件的内部工作原理,它们是遵循标准格式的文本文件,表中的值通过逗号分隔。您可以使用 Export-Csv
命令在 PowerShell 中创建 CSV 文件,并将一个或多个对象传递给它。
下面的命令查找前两个正在运行的进程,并将生成的对象传递给 Export-Csv
命令。然后,Export-Csv
命令在系统驱动器的根目录(很可能是 C:\)中创建名为 processes.csv 的 CSV 文件。
现在使用记事本打开processes.csv。您应该在顶部看到"Name","SI","Handles","VM"
作为标题。您还会看到#TYPE System.Diagnostics.Process
,目前可能并不太明白。别担心,我们将在这篇文章中解释这个字符串。
使用Import-Csv读取CSV文件
想要更多类似的技巧吗?查看我的个人PowerShell博客。
PowerShell有几个命令可以让您读取文本文件。这些命令是Get-Content
和Import-Csv
。这两个cmdlet在技术上以相同的方式读取文件。但是Import-Csv
更进一步。Import-Csv
了解不仅是文本文件而且是CSV文件的底层结构。
由于CSV文件遵循特定的模式,Import-Csv
了解CSV模式。此cmdlet不仅从磁盘读取文本文件,还将CSV文件中的行转换为PowerShell对象。
非CSV文件
通常,CSV的数据是由逗号分隔的,但有时CSV(在那时技术上不是CSV)的数据是用不同的分隔符分隔的。这些分隔符有时可能是制表符或分号。
如果您有使用不同分隔符的 CSV 文件,您可以使用 Delimiter
参数。该参数告诉 Import-Csv
不要查找逗号,这是默认的,而是要查找另一个值。
例如,如果您有一个制表符分隔的文件,您可以像下面这样读取文件:
添加标题
A common Import-Csv
parameter is Header
. This parameter lets you specify the property names of the objects created by this cmdlet.
默认情况下,Import-Csv
cmdlet 会将 CSV 文件的顶部行视为标题。然后,它会将这些值转换为每行(对象)的属性。但是,如果您有一个没有标题行的 CSV 文件,您可以使用 Header
参数来自定义一个标题。
Header
参数会阻止 Import-CSV
使用您的第一行作为标题,还会为您省去手动打开 CSV 文件以自己添加标题的麻烦。
为了演示这种行为,打开记事本并复制/粘贴下面的文本。这段文本将代表一个包含三行两列的数据集。
将文本文件保存为 test.csv。不要忘记启用文件类型扩展名,或者用双引号括起文件,以免意外将其保存为以 .csv.txt 结尾的文件!
现在,使用 Import-CSV
读取最近创建的 CSV 文件,不带 Header
参数,并检查输出。
请注意,它将第一行用作对象属性。 A
和 1
不是你想要用作对象属性的“标签”。 A
、b
和 c
是字母,而 1
、2
和 3
是数字。你需要像下面这样使用 Header
参数来定义它们:
使用 PowerShell 保存 CSV 文件
如果你需要从 PowerShell 对象创建或保存 CSV 文件,也可以采取另一种方式。虽然 Import-Csv
命令将 CSV 文件“转换”为 PowerShell 对象,Export-Csv
则相反。这个命令将 PowerShell 对象“转换”为 CSV 文件。
通过使用 Export-Csv
保存 CSV 文件,你可以稍后查看或在其他系统中使用该数据。
例如,我可以通过将 Get-Process
管道传递给 Export-Csv
命令来保存计算机上所有正在运行的进程。
Export-Csv
命令本质上很简单,但是有一些需要注意的地方。
在运行 Export-CSV 之前格式化输出
如你所见,Export-Csv
本身进行“原始”转换。它不会添加任何特殊的富文本格式,也不会添加任何颜色等。
最常见的问题之一是在导出到 CSV 之前尝试使输出看起来更漂亮。许多用户在导出到 CSV 之前会尝试使输出看起来更好。但是我将向你展示这样做会使事情变得更糟。
你可以在 Microsoft Excel 中打开 CSV 文件并施加斜体、加粗、添加颜色等等,但如果将文件保存为 CSV 格式(而不是 Excel 工作簿),所有格式将被删除。CSV 文件简单来说并不足够“智能”
。请记住,CSV 文件只是由逗号(或有时是制表符)分隔的纯文本文件。将 Import-Csv
管道传递给 Format-*
PowerShell cmdlet 将无法按预期工作。
根据 Microsoft Export-Csv 文档:“在将对象发送到 Export-CSV
cmdlet 之前,请勿格式化对象。如果 Export-CSV
收到格式化的对象,则 CSV 文件将包含格式属性而不是对象属性。”
为什么会这样呢?
打开 PowerShell 窗口并创建一些虚拟数据。让我们使用本文第一部分介绍的 Get-Process
示例。但这次,将输出分配给一个变量。然后,将这些进程对象传递给 Format-Table
cmdlet。

Format-Table
使用 Format-Table
,你现在可以看到一个清晰的表格输出。
现在将此输出保存到另一个变量中。
现在使用 Get-Member
查看 $a
和 $b
变量值的属性。这个 cmdlet 将帮助你理解为什么这两个看似相似的对象不以相同的方式导出到 CSV 文件:


Format-Table
‘s many object typesGet-Process
的直接输出返回:TypeName: System.Diagnostics.Process
,而Format-Table
的输出完全不同。它返回许多不同类型的对象,具有不同的属性。
如果在控制台中查看$a
和 $b
,输出看起来是相同的。这种行为是由于PowerShell的格式化系统。
这如何影响Export-Csv
的输出?
Export-Csv
将每个对象视为原样读取。当您将输出管道传递给Format-*
命令时,您正在更改Export-CSV
收到的输入。这然后影响保存到新CSV文件中的输出。
如果要将输出管道传递给Export-Csv
命令,不要将输出管道传递给任何Format-*
命令。
请记住,CSV 文件专注于数据,而不是格式。
追加到CSV文件
有时,您可能希望添加到现有文件,而不是完全创建一个新文件。默认情况下,Export-Csv
将覆盖通过Path
参数指定的任何文件。
如果需要将数据追加到CSV中,请使用Append
参数。
让我们说你有一个循环,你想要将每个处理过的对象保存到CSV中。对于每次迭代,你有一个不同的对象想要保存到CSV文件中。由于你重复调用Export-Csv
,如果你不使用Append
参数,它会覆盖CSV文件。没有Append
参数,你将只得到最后一个对象,这在大多数情况下不是期望的输出。
下面的例子是查找前五个正在运行的进程。然后,它进入一个PowerShell Import-Csv
foreach 循环,并将Name
和ProductVersion
属性逐个记录到test.csv文件中。
如果不使用Append
参数,你会发现CSV文件中只会显示第五个进程。
追加差异到CSV文件
可以只将属性差异追加到现有的CSV文件中,使用Export-Csv
。这意味着如果CSV行的列和要记录的对象不同,那么可以追加它们。
要仅追加差异到CSV文件,你需要同时使用Append
和Force
参数。根据Microsoft文档的说法:“当Force
和Append
参数结合使用时,包含不匹配属性的对象可以被写入CSV文件。仅写入匹配的属性到文件中,不匹配的属性被丢弃。”
展示一下,创建一个具有两个属性的对象;Name
和 Age
。
现在创建另一个具有 Name
和 Zip
属性的对象。
每个对象具有不同的属性。
接下来,从第一个对象创建一个 CSV 文件,然后尝试在 CSV 中不使用 Force
参数追加第二个对象。你将收到一个错误。

Export-Csv
without Force
然而,如果你使用 Force
参数,Export-Csv
就会很好地工作。
然而,你会注意到在 CSV 文件中 Zip
列已经消失了。要谨慎使用 Force
。它可能不会提供预期的输出。
Export-CSV
和 #TYPE
字符串
默认情况下,使用 Export-CSV
而不带额外参数会在你的 CSV 文件顶部包含一个 #TYPE
字符串。然后这个字符串后面跟着 Export-Csv
接收到的对象类型。
大多数情况下,这个字符串在消耗输出时实际上是没有用的。这个字符串只是在你需要保持属性和值来自的对象类型时才会存在。
要移除这个字符串,使用 NoTypeInformation
参数。此参数会从 CSV 中完全删除这个字符串。
注意,截至 PowerShell Core,这已经不再必要。
总结
使用Import-CSV
和Export-CSV
PowerShell 命令让您轻松处理 CSV 文件。这是两个有用的命令,您在处理对象和 CSV 文件时应经常使用。
我希望通过我在这里展示的解释和示例,您能够清楚地了解何时可以利用这些命令来使自己受益。
想要更多这样的技巧吗?查看我的个人 PowerShell 博客。