如何用PowerShell生成仅含单次表头的磁盘信息CSV文件?
问题解决:PowerShell导出CSV去除重复表头
原代码问题分析
- 重复表头原因:每次循环针对单个
$data对象执行ConvertTo-Csv,该命令会为单个对象生成完整的表头+数据行,多次执行Add-Content就会重复写入表头。 - 循环逻辑冗余:在
$oPack.Volumes循环内重复创建$data,但最终仅保留最后一个volume对应的磁盘数据;从期望输出看,你需要每个磁盘对应多次数据(匹配volume数量),但原代码的输出方式导致表头重复。
修正后的代码
$path = 'C:\Users\Desktop\Test.csv' # 清理目标文件 If (Test-Path $path) { Remove-Item $path -Verbose } else { Write-Host "$path not found" } # 加载VDS程序集并获取磁盘信息 [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Storage.Vds") | Out-Null $oVdsServiceLoader = New-Object Microsoft.Storage.Vds.ServiceLoader $oVdsService = $oVdsServiceLoader.LoadService($null) $oVdsService.WaitForServiceReady() $oVdsService.Reenumerate() $cPacks = $oVdsService.Providers | ForEach-Object {$_.Packs} # 初始化数组存储所有数据对象 $allDiskData = @() foreach($oPack in $cPacks) { If($oPack.Status -eq "Online" -and $oPack.Volumes -ne $null) { foreach($oDisk in $oPack.Disks) { foreach($oVolume in $oPack.Volumes) { # 将每个磁盘-卷对应的对象添加到数组 $data = [PSCustomObject]@{ 'DiskGuid' = $oDisk.DiskGuid 'Name' = $oDisk.FriendlyName } $allDiskData += $data } } } } # 一次性转换为CSV并写入文件,仅生成一次表头 $allDiskData | ConvertTo-Csv -Delimiter "|" -NoTypeInformation | Set-Content $path
修正说明
- 统一收集数据:创建
$allDiskData数组,将所有需要导出的磁盘对象存入其中,避免多次转换CSV导致重复表头。 - 一次性写入文件:用
Set-Content替代多次Add-Content,通过ConvertTo-Csv一次性处理所有数据,只会生成一次表头。 - 简化对象创建:使用
[PSCustomObject]代替New-Object psobject,语法更简洁高效。
可选优化(若无需按卷重复磁盘数据)
如果期望每个磁盘仅输出一次,而非匹配卷的数量重复,可去掉最内层的$oVolume循环:
$path = 'C:\Users\Desktop\Test.csv' If (Test-Path $path) { Remove-Item $path -Verbose } else { Write-Host "$path not found" } [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Storage.Vds") | Out-Null $oVdsServiceLoader = New-Object Microsoft.Storage.Vds.ServiceLoader $oVdsService = $oVdsServiceLoader.LoadService($null) $oVdsService.WaitForServiceReady() $oVdsService.Reenumerate() $cPacks = $oVdsService.Providers | ForEach-Object {$_.Packs} $allDiskData = @() foreach($oPack in $cPacks) { If($oPack.Status -eq "Online" -and $oPack.Volumes -ne $null) { foreach($oDisk in $oPack.Disks) { $data = [PSCustomObject]@{ 'DiskGuid' = $oDisk.DiskGuid 'Name' = $oDisk.FriendlyName } $allDiskData += $data } } } $allDiskData | ConvertTo-Csv -Delimiter "|" -NoTypeInformation | Set-Content $path
内容的提问来源于stack exchange,提问作者Shan
相关产品推荐
相关产品推荐

