Windows Server 2025 / サーバー情報をCSVへ書き出す

サーバー情報をCSVにすると、同じ列で点検結果を比較できます。コンピューター名と採取時刻を必ず含め、OS、メモリ、ディスクをどのサーバーから取得したか分かるようにします。

出力内容と保管先を決める

最初は各サーバーのWindows PowerShell 5.1でローカル実行し、遠隔認証の問題とファイル出力を分離します。server.csvにはOS、起動時刻、メモリを、disks.csvには固定ディスクの容量と空き領域を出力します。

C:\LabReportsの下に日時と短い識別子を付けた新しいフォルダーを作り、前の結果を上書きしません。内部名や構成は運用情報なので、保存先の権限と保持期間も決めます。

完全なスクリプトを保存して実行する

次をC:\LabScripts\Collect-LabInventory.ps1としてUTF-8で保存します。Windows PowerShell 5.1で日本語コメントを加えるならBOM付きUTF-8の扱いも確認します。追加モジュールは不要で、管理者PowerShellから実行します。

$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)の管理クラスを利用しています。コンピューター情報を収集する公式例と同じ考え方です。メモリとディスクは1GB定数による二進単位で計算します。

二つのファイルの内容を確かめる

スクリプトが最後に表示した実際のフォルダーパスを入力します。毎回名前が変わるため、例の日時をそのまま使わないでください。

$reportPath = Read-Host 'スクリプトが表示した出力フォルダー'
Import-Csv -LiteralPath (Join-Path $reportPath 'server.csv') | Format-List
Import-Csv -LiteralPath (Join-Path $reportPath 'disks.csv') | Format-Table

server.csvが実行したサーバーを指し、disks.csvに固定ディスクの行があることを確認します。動的メモリを使うVMでは、構成値と採取時の割り当てが違う場合があります。ゲストの値とホスト全体の物理メモリを混同しません。

CSVをデータとして比較する

Export-Csvはプロパティを列にします。Export-Csvの仕様を確認し、Format-Tableを前に入れないでください。5.1の例ではNoTypeInformationとUTF-8を明示しています。

Import-Csv -LiteralPath (Join-Path $reportPath 'disks.csv') |
    Where-Object { [double]$_.FreePercent -lt 20 } |
    Select-Object ComputerName,Drive,FreePercent

Import-Csvの値は通常文字列なので、容量比較の前に数値へ変換します。20%は抽出方法の例で、運用上の警告値とは限りません。絶対容量、増加速度、用途も考慮します。表計算ソフトへ読み込むときは小数点や日時の解釈を確認し、元のCSVを残します。

部分的な失敗と再実行を確認する

片方のファイルができただけで完了としません。両方の存在、列、行の内容を確認し、失敗した場合は権限、空き容量、問い合わせクラスを調べます。

再起動せずにもう一度採取し、CollectedAtが変わりLastBootが同じことを比較します。整理するときは該当する実行フォルダーだけを特定し、LabReports全体や別の日の記録を消さないようにします。