Windows Server 2025 / PowerShell로 서버 상태를 조회하고 CSV로 내보내는 방법
서버 점검 결과는 화면에서 보는 데 그치지 않고 일정한 열 구조로 CSV에 저장하면 비교하기 쉽습니다. PowerShell로 OS·메모리·디스크 정보를 조회하고 서버 이름과 수집 시각을 함께 남기면 여러 서버의 상태를 같은 기준으로 정리할 수 있습니다.
수집할 항목과 저장 위치를 정합니다
이 예시는 각 서버의 로컬 Windows PowerShell 5.1에서 실행하는 스크립트입니다. 원격 인증을 동시에 구성하지 않고 수집과 파일 저장을 먼저 익힙니다. 서버별 CSV를 중앙에서 모을 때도 동일한 열 이름을 사용할 수 있습니다.
| 파일 | 주요 내용 |
|---|---|
| 서버 요약 CSV | 서버 이름, OS 버전, 부팅 시각, 물리 메모리 |
| 디스크 CSV | 서버 이름, 드라이브, 전체·여유 용량, 여유 비율 |
C:\LabReports 아래에 실행 시각과 임의 식별자를 포함한 새 폴더를 만듭니다. 기존 점검 파일을 덮어쓰지 않기 위한 구성입니다. 서버 이름과 내부 구성은 민감한 운영 정보가 될 수 있으므로 저장 폴더의 접근 권한과 보존 기간을 정하세요.
전체 스크립트를 저장하고 실행합니다
아래 전체 내용을 C:\LabScripts\Collect-LabInventory.ps1로 UTF-8 형식으로 저장합니다. Windows PowerShell 5.1에서 한글 주석을 추가한다면 편집기의 UTF-8 BOM 저장 여부도 확인하세요. 관리자 Windows 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)은 관리 정보를 조회하는 공통 모델입니다. 이 예시가 사용하는 클래스와 조회 원리는 컴퓨터 정보 수집 문서에서 확인할 수 있습니다. 메모리와 디스크의 GiB 계산에는 1GB 단위 상수를 사용합니다.
생성 파일과 값을 확인합니다
실행 마지막에 출력된 실제 폴더 경로를 아래 변수에 넣어 조회합니다. 실행 시각과 식별자가 달라지므로 예시 문자열을 그대로 쓰지 마세요.
$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
서버 요약에는 실행한 서버의 이름과 OS가, 디스크 파일에는 고정 디스크별 행이 있어야 합니다. VM에 할당한 메모리와 실제 조회 값이 다르면 동적 메모리 등 VM 설정도 함께 확인합니다. 호스트 전체 물리 메모리와 게스트 메모리를 혼동하지 않습니다.
CSV를 데이터로 다룰 때 주의합니다
Export-Csv는 객체의 속성을 열로 저장합니다. 저장 전에 Format-Table을 사용하면 서식 데이터가 저장될 수 있습니다. 이 예시는 -NoTypeInformation과 -Encoding UTF8을 명시해 Windows PowerShell 5.1에서도 의도를 드러냈습니다.
Import-Csv로 다시 읽은 값은 기본적으로 문자열입니다. 여유 공간을 수치로 비교할 때는 숫자로 변환해야 합니다. 쉼표, 소수점과 날짜 해석은 도구·지역 설정에 따라 달라질 수 있으므로 원본 CSV를 보존하고 가져오기 옵션을 확인하세요.
Import-Csv -LiteralPath (Join-Path $reportPath 'disks.csv') |
Where-Object { [double]$_.FreePercent -lt 20 } |
Select-Object ComputerName,Drive,FreePercent
20%는 이 실습의 필터 예시일 뿐 모든 서버의 경고 임계값이 아닙니다. 실제 운영에서는 절대 여유 공간과 증가 속도, 역할의 요구량을 함께 봅니다.
실패와 결과 보존을 관리합니다
경로 생성 또는 조회에 실패하면 오류를 확인하고 권한·저장 공간·클래스 지원 여부를 점검합니다. 파일 하나만 생겼다면 전체 성공으로 기록하지 마세요. 두 CSV의 존재와 내용이 확인되어야 이번 수집이 완료된 것입니다.
서버를 재부팅하지 않고 다시 수집하면 CollectedAt은 바뀌고 LastBoot는 유지되는지 비교할 수 있습니다. 임시 결과를 정리할 때는 스크립트가 만든 해당 실행 폴더만 선택하고, 다른 점검 파일이나 C:\LabReports 전체를 무심코 삭제하지 않습니다.









