Windows Server 2025 / How to Export Server and Disk Inventory to CSV
CSV reports make server checks easier to compare when their columns stay consistent. Query operating system, memory, and disk information with PowerShell, and include the computer name and collection time so each result has a clear source.
Choose fields and a protected output location
Run this example locally on each server in Windows PowerShell 5.1. Learn collection and file output separately from remote authentication. Identical column names later make reports from several servers easier to combine.
| File | Contents |
|---|---|
| server.csv | Computer name, collection time, OS version, boot time, and memory |
| disks.csv | Computer name, drive, capacity, free space, and free percentage |
Each run creates a new timestamped folder with a short identifier under C:\LabReports to avoid overwriting earlier results. Server names and internal configuration may be sensitive operational information; define folder access and retention.
Save and run the complete script
Save the following as C:\LabScripts\Collect-LabInventory.ps1 using UTF-8. If adding non-ASCII comments for Windows PowerShell 5.1, check the editor’s UTF-8 BOM setting. Run from an elevated Windows PowerShell window; no additional module is needed.
$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
Common Information Model (CIM) supplies the management classes queried here. Microsoft’s computer information collection examples explain the approach. Memory and storage calculations use the binary 1GB constant.
Verify both generated files
Use the actual folder path printed at the end of your run. Its timestamp and identifier differ every time, so do not substitute a literal example folder:
$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
The summary should identify the server on which you ran the script. The disk report should contain rows for its fixed disks. If guest memory differs from the VM setting, consider dynamic memory and the current allocation. Do not confuse a guest’s memory with the host’s total physical memory.
Handle CSV as data
Export-Csv writes object properties as columns. Format-Table before export can save formatting objects instead. The script explicitly selects -NoTypeInformation and UTF-8 encoding for Windows PowerShell 5.1.
Import-Csv normally returns string properties. Convert a field to a number before comparing capacity values. Spreadsheet locale, decimal separators, and date interpretation may differ; keep the original CSV and choose import settings deliberately.
Import-Csv -LiteralPath (Join-Path $reportPath 'disks.csv') |
Where-Object { [double]$_.FreePercent -lt 20 } |
Select-Object ComputerName,Drive,FreePercent
The 20% threshold is a filter example, not a universal alert policy. Operational thresholds should also consider absolute free space, growth, and workload requirements.
Handle partial failure and preserve useful results
If directory creation or a query fails, check privileges, free space, and class support. One output file is not complete success: verify that both exist and contain expected data.
Collect again without restarting the server. CollectedAt should change while LastBoot remains the same. When cleaning up, identify only the folder created by the relevant run; do not casually delete the entire LabReports tree or other inspection records.









