어떤 수업을 찾고 있나요?

예: PowerShell, 네트워크, XSS, Step 138

전체 커리큘럼 둘러보기 →

PowerShell

Step 5. 시스템 정보 수집 — 내 컴퓨터의 건강검진표

Step 5예상 실습 시간 · 2–3시간

Level 0 — 컴퓨터 조작법과 구조 이해 | 난이도 ★★☆☆☆ | 예상 소요 시간: 2–3시간

선수 조건: Step 4 완료. Windows PowerShell 5.1 또는 Windows의 PowerShell 7에서 진행합니다.

  • 준비물: 본인 소유 또는 실습 허가를 받은 Windows PC와 PowerShell.
  • 이번 실습에서 바뀌는 것: 새 실습 폴더와 텍스트 보고서만 만듭니다. 시스템 정보를 조회하며 프로세스를 종료하거나 서비스를 변경하지 않습니다.
  • 결과물: 기본 보고서와 미션 보고서. 운영체제, 메모리, 프로세스, 서비스, 저장 공간을 읽고 설명할 수 있으면 성공입니다.

장애나 침해 사고를 조사할 때는 먼저 어떤 시스템인지, 무엇이 실행 중인지, 저장 공간이 얼마나 남았는지 확인합니다. 오늘은 그 조사에 필요한 시스템 정보 수집을 연습합니다. 제목의 ‘건강검진표’는 비유입니다. 이 보고서는 특정 시점의 관찰 기록이며, 악성코드가 없거나 컴퓨터가 정상이라는 판정서는 아닙니다.

전체 조회 결과에는 장치 이름, 사용자 이름, 경로 등이 포함될 수 있습니다. 실습 보고서는 본인 PC에 보관하고, 화면을 공유할 때는 필요한 항목만 남기세요. 이 수업에서는 외부 서버로 보고서를 전송하지 않습니다.


1. 학습 목표

  • Get-ComputerInfo에서 필요한 OS·하드웨어 속성을 고릅니다.
  • 프로세스와 서비스의 차이를 설명하고 실행 중인 서비스를 셉니다.
  • 파일 시스템 드라이브의 남은 공간을 읽습니다.
  • 같은 UTF-8 인코딩으로 보고서를 만들고 내용을 덧붙인 뒤 다시 읽어 확인합니다.

2. 배경 지식 — 오늘 쓸 도구와 개념

오늘의 도구 한눈에 보기

도구 무엇을 관찰하나
Get-ComputerInfo OS와 하드웨어 속성. Windows 전용 명령입니다.
Get-Process 현재 조회 가능한 프로세스와 메모리·CPU 시간
Get-Service Windows 서비스와 상태
Get-PSDrive 현재 PowerShell 세션의 드라이브
Format-List, Out-File 선택한 정보를 목록 모양의 텍스트로 저장

2-1. 컴퓨터의 네 가지 자원

CPU는 연산, 메모리는 실행 중 작업 공간, 디스크는 저장, 네트워크는 통신을 맡습니다. 오늘은 OS·메모리·프로세스·서비스·드라이브 공간을 관찰합니다. 네트워크 정보는 Step 6에서 다룹니다. 이번 명령만으로 네 자원의 성능을 모두 측정하는 것은 아닙니다.

2-2. 프로세스와 서비스

프로세스는 실행 중인 프로그램의 인스턴스입니다. 사용자가 실행할 수도 있고 운영체제나 다른 프로그램이 만들 수도 있습니다. 서비스는 Windows 서비스 관리자가 관리하는 기능입니다. 자동·수동·트리거 등 시작 조건이 다르며, 설치되어 있어도 중지 상태일 수 있습니다. 여러 서비스가 하나의 프로세스를 공유하기도 하므로 서비스 수와 프로세스 수는 같지 않습니다.

공격자가 서비스를 등록해 지속 실행에 악용할 수 있어 조사 대상이 됩니다. 하지만 낯선 이름이나 높은 개수만으로 악성이라고 판단할 수는 없습니다. 오늘은 조회만 하고, 삭제·중지·시작 유형 변경은 하지 않습니다.

2-3. 베이스라인 — 비교할 수 있게 남기는 기록

베이스라인은 비교 기준입니다. 수집 시간, 사용 중인 프로그램, 조회 오류를 함께 기록해야 다음 관찰과 비교할 수 있습니다. 첫 보고서가 정상 상태라는 보장은 없습니다. 서비스 개수 변화는 기존 서비스의 시작·중지로도 생기므로, 새 서비스 등록을 뜻한다고 단정하지 마세요.


3. 따라 하기

3-1. 전체 정보와 필요한 속성 — Get-ComputerInfo

Get-ComputerInfo

수집에 시간이 걸릴 수 있습니다. 출력은 속성 이름 : 값 형태이며 환경별로 다릅니다. 다음은 읽는 법을 보여 주는 예시로, 여러분 PC에서 같은 값이 나올 필요는 없습니다.

OsName                : Microsoft Windows 11 Pro
OsVersion             : 10.0.26200
CsTotalPhysicalMemory : 16576139264
  • OsName: 운영체제 이름과 에디션.
  • OsVersion: 운영체제 버전 문자열. Windows 11에서도 10.0으로 시작할 수 있습니다.
  • CsTotalPhysicalMemory: 시스템이 보고한 총 물리 메모리 바이트 수. 예시 값은 약 16.58 GB 또는 15.44 GiB입니다. 하드웨어 예약 등의 이유로 구매한 메모리의 표기 용량과 다를 수 있습니다.

이번에 사용할 세 속성만 요청합니다:

Get-ComputerInfo -Property OsName, OsVersion, CsTotalPhysicalMemory

Step 3의 Get-ComputerInfo | Select-Object OsName, OsVersion, CsTotalPhysicalMemory도 표시할 속성을 고르는 방법입니다. 다만 뒤쪽의 Select-Object는 이미 앞 명령이 수행한 조회를 되돌리거나 조회 오류를 해결하지 않습니다.

3-2. 현재 프로세스 — 메모리 상위 목록

Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 5 ProcessName, Id, WorkingSet64

WorkingSet64는 프로세스의 작업 집합 크기(바이트)입니다. 최대 5개 프로세스를 큰 값부터 보여 줍니다. 앱 하나가 여러 프로세스를 만들 수 있으므로 ‘앱별 총 메모리 상위 5개’와는 다릅니다. Id는 프로세스 ID입니다.

892,345,600바이트라면 약 892.35 MB 또는 851.01 MiB입니다. 작업 관리자의 열과 정의가 다를 수 있습니다. 브라우저가 위에 나온다는 이유만으로 정상이라고 판정하지도, 낯선 이름이 있다는 이유만으로 악성이라고 판정하지도 마세요. 실제 식별에는 실행 파일 경로·서명·실행 맥락 같은 추가 근거가 필요합니다.

3-3. 서비스 목록 — Get-Service

Get-Service

Status는 상태, Name은 내부 이름, DisplayName은 표시 이름입니다. Running은 실행 중, Stopped는 중지이며 이외에 Paused나 전환 중 상태도 있습니다. 실행 중인 항목만 고릅니다:

Get-Service | Where-Object {$_.Status -eq "Running"}

예측해 보기: 위 명령 뒤에 | Measure-Object를 붙이면 무엇을 셀까요? 정답은 그 조회에서 반환된 실행 중 서비스 수입니다. 정상 개수에 대한 보편적인 100–200개 기준은 없습니다. 조회 오류가 있으면 일부 결과일 수 있습니다.

3-4. 드라이브의 남은 공간 — Get-PSDrive

Get-PSDrive -PSProvider FileSystem

-PSProvider FileSystem으로 파일 시스템 드라이브만 고릅니다. 옵션 없이 Get-PSDrive를 실행하면 Alias·Env·Registry 같은 다른 공급자도 나타납니다. 파일 시스템 목록에도 네트워크 드라이브나 같은 저장소를 가리키는 임시 드라이브가 포함될 수 있으므로 용량을 단순 합산하지 마세요.

Name   Used (GB)   Free (GB)   Provider     Root
----   ---------   ---------   --------     ----
C         547.69      376.91   FileSystem   C:\

표는 출력 형식을 설명하는 예시입니다. 기본 표가 GB로 표시하는 값은 1,073,741,824바이트 단위의 값입니다. 뒤의 보고서는 Used와 Free 속성을 바이트 그대로 저장해 단위를 분명히 합니다. 빈 값은 0바이트라고 해석하지 마세요.

남은 공간이 부족하면 저장·로그 기록·업데이트에 문제가 생길 수 있습니다. ‘20% 미만 경고’는 운영자가 정할 수 있는 예시일 뿐 공통 기준은 아닙니다. 절대 남은 용량, 증가 속도, 필요한 업데이트 용량도 봅니다. 이 명령은 디스크 고장이나 SMART 상태를 검사하지 않습니다.

3-5. 정보를 모아 기본 보고서 만들기

새 실습 폴더를 만들고 기본 보고서를 시작합니다. $systemlab은 폴더 경로, $basicReport는 파일 경로를 담는 이름입니다. 변수는 Step 7에서 자세히 배우며 지금은 블록을 순서대로 실행하세요. 영문 제목을 사용해 한글·영문 수업의 실행 결과 구조를 통일했습니다.

$systemlab = Join-Path $HOME ('infosec-step05-' + [guid]::NewGuid().ToString('N'))
New-Item -ItemType Directory -Path $systemlab -ErrorAction Stop
Set-Location -LiteralPath $systemlab
$basicReport = Join-Path $systemlab 'report-basic.txt'
Get-Date -Format o | Out-File -LiteralPath $basicReport -Encoding UTF8
"=== OS and physical memory (bytes) ===" | Out-File -LiteralPath $basicReport -Append -Encoding UTF8
Get-ComputerInfo -Property OsName, OsVersion, CsTotalPhysicalMemory |
  Format-List OsName, OsVersion, CsTotalPhysicalMemory |
  Out-File -LiteralPath $basicReport -Append -Encoding UTF8 -Width 4096
pwd
  • Get-Date -Format o: 시간대 차이를 구분할 수 있도록 날짜·시간과 오프셋을 기록합니다.
  • 첫 Out-File은 새 보고서를 시작하고, 이후의 -Append는 끝에 덧붙입니다. 시작 블록을 다시 실행하면 다른 새 폴더가 생깁니다.
  • -Encoding UTF8을 처음부터 끝까지 맞춥니다. 5.1과 7의 기본 인코딩 차이를 피하기 위한 것입니다.
  • Format-List는 긴 열을 옆으로 압축하는 대신 속성별 목록으로 표시합니다. -Width 4096은 저장할 때의 줄 너비입니다. 이것도 모든 종류의 객체를 무손실 보관하는 기능은 아닙니다.

같은 세션에서 다음 블록을 이어 실행합니다:

"=== Top 5 processes by working set (bytes) ===" | Out-File -LiteralPath $basicReport -Append -Encoding UTF8
Get-Process | Sort-Object WorkingSet64 -Descending |
  Select-Object -First 5 ProcessName, Id, WorkingSet64 |
  Format-List | Out-File -LiteralPath $basicReport -Append -Encoding UTF8 -Width 4096

$serviceErrors = @()
$serviceSnapshot = @(Get-Service -ErrorAction Continue -ErrorVariable serviceErrors)
"=== Service query ===" | Out-File -LiteralPath $basicReport -Append -Encoding UTF8
"Query errors: $($serviceErrors.Count)" | Out-File -LiteralPath $basicReport -Append -Encoding UTF8
"Running: $(($serviceSnapshot | Where-Object {$_.Status -eq 'Running'} | Measure-Object).Count)" |
  Out-File -LiteralPath $basicReport -Append -Encoding UTF8

"=== FileSystem drives (Used / Free in bytes) ===" | Out-File -LiteralPath $basicReport -Append -Encoding UTF8
Get-PSDrive -PSProvider FileSystem | Format-List Name, Root, Used, Free |
  Out-File -LiteralPath $basicReport -Append -Encoding UTF8 -Width 4096

$serviceSnapshot에는 한 번 조회한 서비스 목록을 담습니다. 그 목록에서 Running을 세므로 ‘조회 시점의 값’을 보고서에 적습니다. $serviceErrors는 서비스 조회 오류를 모으며, Query errors가 0이 아니면 개수는 불완전할 수 있습니다. 오류를 없애려고 서비스를 조작하거나 관리자 실행을 무조건 시도하지 마세요. 다른 조회에서 오류가 보이거나 값이 비어 있어도 해당 부분은 확인되지 않은 것으로 기록합니다.

완성한 파일을 읽어 시간 → OS → 메모리 상위 프로세스 → 서비스 조회 → 드라이브 순서인지 확인합니다:

Get-Content -LiteralPath $basicReport -Encoding UTF8

화면에서 보기 좋은 표와 저장된 파일은 같다고 가정하지 마세요. 파일을 다시 읽어 제목, 속성 이름, 값이 실제로 남았는지 확인하는 것까지가 보고서 작성입니다. 출력 분량은 PC마다 다릅니다.


4. 미션과 연습문제

미션 — 내 PC 관찰 보고서

  1. 기본 보고서를 보존하고 같은 실습 폴더에 report-complete.txt를 만드세요.
  2. 첫 줄에 제목과 별칭을 넣고, 시간과 기존 섹션을 모두 포함하세요.
  3. 누적 CPU 시간(초) 상위 최대 3개 프로세스를 추가하세요. 현재 CPU 사용률(%)과 구별하세요.
  4. 하나의 서비스 조회 목록에서 Running·Stopped 수와 조회 오류 수를 기록하세요.
  5. 파일을 다시 읽고 무엇을 관찰했고 무엇은 아직 모르는지 본인 말로 설명하세요. 실제 시스템 정보가 담긴 원본을 그대로 공개할 필요는 없습니다.

연습문제

문제 1. Select-Object로 필요한 열을 고르는 것과 원래 조회 오류를 해결하는 것은 어떻게 다른가요?

문제 2. 서비스 수와 프로세스 수가 같지 않은 이유는 무엇인가요? 낯선 서비스가 곧 악성인가요?

문제 3. 보고서 중간에서 -Append를 빼면 어떻게 되나요?

문제 4. Free를 확인하면 디스크가 고장 나지 않았다고 판정할 수 있나요? 20% 경고는 모든 PC의 기준인가요?

문제 5. CPU = 120은 현재 CPU 사용률 120%인가요?


해설과 완료 기준 · 펼치기/접기

5. 모범 답안과 완료 기준

미션 해설 — 모든 섹션을 한 번에 작성

3-5를 실행한 같은 세션에서 다음 전체 블록을 실행합니다. 첫 줄은 미션용 파일 경로를 정합니다. 이 블록을 다시 실행하면 그 미션 파일만 새 내용으로 다시 만들며, 기본 보고서는 남습니다.

$completeReport = Join-Path $systemlab 'report-complete.txt'
"My PC system snapshot (Author: Learner)" | Out-File -LiteralPath $completeReport -Encoding UTF8
Get-Date -Format o | Out-File -LiteralPath $completeReport -Append -Encoding UTF8

"=== OS and physical memory (bytes) ===" | Out-File -LiteralPath $completeReport -Append -Encoding UTF8
Get-ComputerInfo -Property OsName, OsVersion, CsTotalPhysicalMemory |
  Format-List OsName, OsVersion, CsTotalPhysicalMemory |
  Out-File -LiteralPath $completeReport -Append -Encoding UTF8 -Width 4096

"=== Top 5 processes by working set (bytes) ===" | Out-File -LiteralPath $completeReport -Append -Encoding UTF8
Get-Process | Sort-Object WorkingSet64 -Descending |
  Select-Object -First 5 ProcessName, Id, WorkingSet64 |
  Format-List | Out-File -LiteralPath $completeReport -Append -Encoding UTF8 -Width 4096

"=== Top 3 processes by cumulative CPU time (seconds) ===" | Out-File -LiteralPath $completeReport -Append -Encoding UTF8
Get-Process | Where-Object {$null -ne $_.CPU} | Sort-Object CPU -Descending |
  Select-Object -First 3 ProcessName, Id, CPU |
  Format-List | Out-File -LiteralPath $completeReport -Append -Encoding UTF8 -Width 4096

$serviceErrors = @()
$serviceSnapshot = @(Get-Service -ErrorAction Continue -ErrorVariable serviceErrors)
"=== Service query ===" | Out-File -LiteralPath $completeReport -Append -Encoding UTF8
"Query errors: $($serviceErrors.Count)" | Out-File -LiteralPath $completeReport -Append -Encoding UTF8
"Running: $(($serviceSnapshot | Where-Object {$_.Status -eq 'Running'} | Measure-Object).Count)" |
  Out-File -LiteralPath $completeReport -Append -Encoding UTF8
"Stopped: $(($serviceSnapshot | Where-Object {$_.Status -eq 'Stopped'} | Measure-Object).Count)" |
  Out-File -LiteralPath $completeReport -Append -Encoding UTF8

"=== FileSystem drives (Used / Free in bytes) ===" | Out-File -LiteralPath $completeReport -Append -Encoding UTF8
Get-PSDrive -PSProvider FileSystem | Format-List Name, Root, Used, Free |
  Out-File -LiteralPath $completeReport -Append -Encoding UTF8 -Width 4096
Get-Content -LiteralPath $completeReport -Encoding UTF8

완료 확인: 첫 줄 제목이 남아 있고 OS·메모리·CPU 누적 시간·Running·Stopped·조회 오류·드라이브 항목이 모두 있어야 합니다. 조회 시점이 달라 두 보고서의 수치가 꼭 같을 필요는 없습니다. 같은 물리 디스크가 여러 드라이브로 보일 수도 있습니다.

연습문제 정답

정답 1. Select-Object는 전달받은 객체에서 표시하거나 넘길 속성을 고릅니다. 앞 명령의 실패를 해결하거나 이미 수행한 수집을 줄이지 않습니다.

정답 2. 프로세스는 실행 인스턴스, 서비스는 Windows 서비스 관리자가 관리하는 기능입니다. 중지된 서비스도 있고 여러 서비스가 프로세스를 공유할 수도 있습니다. 이름만으로 악성 여부를 판정할 수 없습니다.

정답 3. 해당 출력이 파일을 덮어씁니다. 보고서 시작 지점에서만 의도적으로 새로 쓰고 이후에는 같은 인코딩으로 Append합니다.

정답 4. Free는 공간 관찰에 쓰는 값으로 하드웨어 고장 진단이 아닙니다. 경고 기준은 환경과 증가 속도에 맞게 정해야 합니다.

정답 5. 프로세스 시작 이후 사용한 누적 프로세서 시간 120초입니다. 현재 사용률이 아닙니다.

완료 체크리스트

  • [ ] OS 세 속성을 골라 읽고 바이트와 GiB를 구별했습니다.
  • [ ] 서비스와 프로세스, 누적 시간과 사용률을 설명했습니다.
  • [ ] 기본 보고서와 전체 미션 보고서를 별도 파일로 만들었습니다.
  • [ ] 파일을 다시 읽어 제목과 모든 섹션, 조회 오류 여부를 확인했습니다.
  • [ ] 보고서가 정상 판정이나 악성코드 검사 결과는 아니라는 점을 설명했습니다.

6. 자주 막히는 지점과 해결

Get-ComputerInfo가 느리거나 실패함: 잠시 기다린 뒤 오류 대상과 메시지를 확인하세요. -Property로 필요한 속성을 요청할 수 있지만 모든 오류나 지연을 해결한다는 뜻은 아닙니다. 빈 필드는 확인되지 않은 값입니다. 다른 OS용 PowerShell에서는 이 Windows 전용 명령을 쓸 수 없습니다.

앞에 쓴 내용이 사라짐: 중간 명령의 Append 누락인지 확인합니다. 위의 전체 미션 블록은 제목부터 모든 섹션을 다시 만들어 순서 누락을 줄입니다. 중요한 파일을 대상으로 덮어쓰기 연습을 하지 마세요.

이름이 …으로 잘림: Out-File도 표시 형식을 적용하므로 파일에서도 잘릴 수 있습니다. 필요한 속성을 고른 뒤 마지막 표시 단계에서 Format-List를 쓰고 저장 너비를 조절하세요. 저장 파일을 다시 읽어 확인해야 합니다. Format-List 뒤에서 원래 데이터의 정렬·필터링을 하지 마세요.

숫자 단위가 혼란스러움: 1 GB는 1,000,000,000바이트, 1 GiB는 1,073,741,824바이트입니다. PowerShell의 1GB 상수는 후자의 크기이므로 16576139264 / 1GB는 약 15.44입니다.

서비스 조회 오류 또는 낯선 이름: 오류가 있으면 목록이 완전하다고 보지 않습니다. 서비스 개수가 많거나 이름을 모른다는 이유만으로 중지하지 마세요. 보고서 수치는 조회 중에도 변할 수 있습니다.

$systemlab이 비어 있음: PowerShell을 새로 열었다면 변수는 이전 세션에서 사라졌습니다. 3-5의 시작 블록부터 다시 실행해 새 실습 폴더를 준비하세요.


7. 요약

작업 핵심
OS·메모리 정보 Get-ComputerInfo로 필요한 속성을 요청
프로세스 WorkingSet64는 바이트, CPU는 누적 초
서비스 조회한 목록과 오류를 함께 기록
저장 공간 FileSystem 드라이브의 Free 확인, 중복 저장소 합산 주의
보고서 새 파일 → 같은 UTF8로 Append → 다시 읽어 검증

목록을 얻고, 필요한 속성을 고르고, 저장된 결과를 확인합니다. 수치를 설명할 때는 수집 시점·단위·조회 범위도 함께 말하세요. Step 6에서는 네트워크 정보를 관찰합니다.


실습 검증 기록

2026-09-10, Windows 11에서 Windows PowerShell 5.1.26100.9444와 PowerShell 7.6.5로 본문의 실행 코드 전체를 순서대로 실행했습니다. OS·프로세스·서비스·파일 시스템 조회, 두 보고서의 제목·섹션·인코딩, 전체 미션 재실행 후 기본 보고서 보존을 확인했습니다. 실제 장치 이름과 경로가 담긴 원본 보고서는 공개하지 않았습니다. 다른 PC의 값이나 권한, 하드웨어 상태를 검증한 기록은 아닙니다.

Microsoft: Get-ComputerInfo · Get-Service · Get-PSDrive · Out-File · Format-List

한 단계 더 가까이

수업을 마쳤나요?

본문의 완료 기준을 확인한 뒤 직접 표시하세요.

화면이나 링크에 문제가 있나요? 알려주세요.
다음 수업