Windows Server 2025 / 将服务器和磁盘清单导出为 CSV
使用 PowerShell 查询操作系统、内存和磁盘信息,再通过 Export-Csv 导出为 CSV(逗号分隔值)文件,即可生成便于比较的服务器清单。保持列名一致,并加入计算机名称和采集时间,可以辨别每条记录来自哪台服务器、哪次采集。
选择字段与受保护的输出位置
请在需要采集清单的服务器上,使用 Windows PowerShell 5.1 本地运行本例。先掌握数据采集和文件输出,再单独处理远程身份验证。多台服务器使用相同的列名,有利于后续合并报告。
| 文件 | 内容 |
|---|---|
| server.csv | 计算机名称、采集时间、操作系统、版本、上次启动时间和内存 |
| disks.csv | 计算机名称、采集时间、驱动器、容量、可用空间和可用百分比 |
每次运行都会在 C:\LabReports 下新建带时间戳和短标识符的文件夹,将结果与之前的报告分开保存。服务器名称和内部配置可能属于敏感运维信息,请明确文件夹的读取权限和报告保留期限。
保存并运行完整脚本
先创建 C:\LabScripts,将完整代码保存为 C:\LabScripts\Collect-LabInventory.ps1,并确认扩展名不是 .ps1.txt。使用 UTF-8 编码;如果添加中文或其他非 ASCII 字符,应选择带字节顺序标记(BOM,byte order mark)的 UTF-8,参阅 Windows PowerShell 字符编码说明。在该服务器上选择“以管理员身份运行”打开 Windows PowerShell,本例只使用 Windows PowerShell 5.1 自带的模块。如果执行策略阻止运行文件,请遵守组织批准的执行与签名要求,不要通过关闭保护措施绕过限制。
$runLabel = (Get-Date -Format 'yyyyMMdd-HHmmss') + '-' + ([guid]::NewGuid().ToString('N').Substring(0,6))
$reportDirectory = Join-Path 'C:\LabReports' $runLabel
New-Item -ItemType Directory -Path $reportDirectory -Force -ErrorAction Stop | Out-Null
$os = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop
$computer = Get-CimInstance Win32_ComputerSystem -ErrorAction Stop
$collectedAt = (Get-Date).ToString('o')
[pscustomobject]@{
ComputerName = $env:COMPUTERNAME
CollectedAt = $collectedAt
OS = $os.Caption
Version = $os.Version
LastBoot = $os.LastBootUpTime
MemoryGiB = [math]::Round($computer.TotalPhysicalMemory / 1GB,2)
} | Export-Csv -LiteralPath (Join-Path $reportDirectory 'server.csv') -NoTypeInformation -Encoding UTF8
Get-CimInstance Win32_LogicalDisk -Filter 'DriveType=3' -ErrorAction Stop | ForEach-Object {
[pscustomobject]@{
ComputerName = $env:COMPUTERNAME
CollectedAt = $collectedAt
Drive = $_.DeviceID
SizeGiB = [math]::Round($_.Size / 1GB,2)
FreeGiB = [math]::Round($_.FreeSpace / 1GB,2)
FreePercent = if ($_.Size -gt 0) { [math]::Round(100 * $_.FreeSpace / $_.Size,1) } else { $null }
}
} | Export-Csv -LiteralPath (Join-Path $reportDirectory 'disks.csv') -NoTypeInformation -Encoding UTF8
Write-Output $reportDirectory
Set-Location 'C:\LabScripts'
.\Collect-LabInventory.ps1
公共信息模型(CIM,Common Information Model)提供本例查询的管理类,Microsoft 的计算机信息采集示例介绍了这种查询方法。代码中的 1GB 是二进制常量,等于 1,073,741,824 字节;MemoryGiB、SizeGiB 和 FreeGiB 的单位为 GiB(吉比字节),FreePercent 则表示百分比。脚本不会修改服务或服务器配置,但会创建输出文件夹和 CSV 文件。
验证生成的两份文件
使用本次运行结束时实际输出的文件夹路径。Read-Host 提示输入时,请输入或粘贴该路径,不要加引号。时间戳和标识符每次都会变化,因此不要套用其他运行结果中的示例文件夹:
$reportPath = Read-Host 'Report directory printed by the script'
Import-Csv -LiteralPath (Join-Path $reportPath 'server.csv') | Format-List
Import-Csv -LiteralPath (Join-Path $reportPath 'disks.csv') | Format-Table
确认 server.csv 包含所查询计算机的一行记录,disks.csv 包含它的本地逻辑驱动器记录。两份文件中的 ComputerName 和 CollectedAt 应相互对应,其他列也应与脚本一致。MemoryGiB 根据 Win32_ComputerSystem 的 TotalPhysicalMemory 计算,表示所查询系统报告的值。虚拟机的动态内存和当前分配可能造成它与预期配置不同;该值既不是宿主机的全部物理内存,也不保证精确反映已安装内存条的总容量。
将 CSV 作为数据处理
Export-Csv 将对象属性写入各列。若在导出前插入 Format-Table,传下去的会是格式化记录,因此应区分 PowerShell 对象、管道与显示格式。-NoTypeInformation 用于省略类型信息头;在 Windows PowerShell 5.1 中,-Encoding UTF8 会生成带 BOM 的 UTF-8 文件。
Import-Csv 通常将字段读为文本属性,即使内容看起来像数字。进行数值比较前,应先转换为数值类型。电子表格的区域设置可能影响小数分隔符或日期解释,因此请保留原始 CSV,并在导入时明确选择分隔符、编码和数据类型。下面的筛选以有效的数值百分比为前提:
Import-Csv -LiteralPath (Join-Path $reportPath 'disks.csv') |
Where-Object { [double]$_.FreePercent -lt 20 } |
Select-Object ComputerName,Drive,FreePercent
20% 只是筛选示例,不是通用告警策略;实际阈值还应考虑可用空间绝对值、增长速度和工作负载。如果 Size 无效或不大于零,导致 FreePercent 为空,请在筛选前单独检查该行。将空字符串转换为 double 可能得到 0,但这不能证明实际可用空间为 0%。
处理部分失败并保留有效结果
如果创建文件夹或查询失败,请检查权限、可用空间和管理类是否可用。脚本最后输出了路径,并不等于所有导出操作都已成功。必须确认两份文件均已生成,列名符合预期且包含数据;只有一份文件不算完整结果。
在两次采集之间不重启服务器,再运行一次脚本。CollectedAt 应变化,而未重启时 LastBoot 应保持相同。清理时,请准确识别准备删除的那次运行所创建的文件夹,不要删除整个 LabReports 目录树或其他检查记录。




