PowerShell
Step 2. 파일 다루기 — 만들고, 복사하고, 옮기고, 지우기
Level 0 — 컴퓨터 조작과 구조의 이해 | 난이도 ★☆☆☆☆ | 예상 소요 시간 2~3시간
전제: Step 1 완료 (파워쉘 열기,
pwd/ls/cd). 오늘도 윈도우 파워쉘에서 진행합니다.
- 준비물: 윈도우 PC, 파워쉘.
- 안전: 오늘의 모든 실험은 처음에 만드는 전용 연습 폴더 안에서만 합니다. 이번 수업에서 만든 일회용 파일만 다룹니다. 위치를 잘못 잡으면 다른 파일에 영향을 줄 수 있으므로 작업 전에
pwd로 확인하세요. - 주의:
Set-Content와Copy-Item의 덮어쓰기,Move-Item의 이동,Remove-Item의 삭제에 주의합니다. 파워쉘의 삭제는 휴지통을 거치지 않습니다. 휴지통의 되돌리기 기능으로 복원할 수 없으며 별도 백업이 없다면 복구를 보장할 수 없습니다. 그래서 오늘은 "지우는 법"보다 "안전하게 지우는 법"을 더 열심히 배웁니다.
파일 복사는 마우스로도 됩니다. 그런데 "이 폴더에서 .txt 파일만 300개 골라 복사해 줘"처럼 여러 파일을 조건으로 골라 반복하는 작업은 명령으로 간결하게 표현할 수 있습니다. "매일 밤 로그를 백업 폴더로 옮겨 줘"는 자동화해야 하고, 원격 서버에서는 명령줄로 작업하는 경우도 많습니다. 보안 실무에서 파일 조작은 "문서 정리"가 아니라 증거 다루기입니다 — 오늘은 직접 만든 텍스트로 기본 동작을 배웁니다. 실제 사고의 증거 파일이나 악성코드는 이 수업의 대상으로 사용하지 않습니다.
1. 학습 목표
이 챕터를 끝내면 다음을 할 수 있습니다:
New-Item으로 파일과 폴더를 만든다Set-Content/Get-Content로 파일에 내용을 쓰고 읽는다Copy-Item(복사)과Move-Item(이동)의 차이를 구분해 쓴다- 와일드카드(
*)로 조건에 맞는 파일만 골라 작업한다 - 삭제 전
-WhatIf로 대상을 미리 확인하는 안전 습관을 쓴다
2. 배경 지식 — 오늘의 도구와 개념
오늘의 도구 한눈에 보기
| 구분 | 내용 |
|---|---|
| 언어·환경 | Windows PowerShell 5.1 또는 PowerShell 7, Windows 파일 시스템. 일반 사용자 권한으로 진행합니다. |
| 오늘의 명령어 | New-Item(만들기), Set-Content/Add-Content/Get-Content(쓰기·붙이기·읽기), Copy-Item(복사), Move-Item(이동), Remove-Item(삭제) |
| 오늘의 옵션 | -WhatIf(미리보기), -Recurse(하위까지), -Exclude(제외) |
| 필요한 개념 | 확장자, 와일드카드(*, ?), "복사 vs 이동", 영구 삭제의 의미 |
2-1. 확장자 — 파일의 꼬리표
파일 이름의 마지막 . 뒷부분을 확장자라고 합니다. report.txt의 .txt, setup.exe의 .exe처럼요. 확장자는 용도를 짐작하는 이름표입니다. 이름을 바꿔도 실제 파일 형식이 바뀌는 것은 아니며, 확장자만으로 안전성을 판단할 수 없습니다.
| 확장자 | 종류 |
|---|---|
.txt |
텍스트 문서 |
.exe |
실행 프로그램 |
.ps1 |
파워쉘 스크립트 |
.zip |
압축 파일 |
.log |
로그(기록) 파일 |
보안 주의점 하나: 탐색기 설정에 따라 알려진 파일 형식의 확장자가 숨겨질 수 있습니다. 그래서 견적서.pdf처럼 보이는 파일이 사실은 견적서.pdf.exe(실행 파일!)인 함정이 악성코드 유포의 고전 수법입니다. 탐색기 설정에서 "파일 확장명 표시"를 켜 두는 것 — 초보가 할 수 있는 가장 쉬운 보안 강화입니다. CLI에서는 ls를 치면 확장자가 항상 다 보이니 자연히 이 습관이 생깁니다.
2-2. 와일드카드 — "아무 글자나"의 기호
*(별표)는 "그 자리에 아무 글자나 몇 글자든 올 수 있다"는 특수 기호입니다. 트럼프의 조커 같은 겁니다.
| 패턴 | 뜻 | 걸리는 예 |
|---|---|---|
*.txt |
끝이 .txt인 모든 것 | a.txt, 일기.txt |
log* |
log로 시작하는 모든 것 | log1.txt, logfile.zip |
report?.txt |
report + 한 글자 + .txt | report1.txt, reportA.txt |
이 기호가 오늘의 핵심 무기입니다. "300개 중 txt만" 같은 조건 선택이 이걸로 됩니다.
3. 따라 하기
3-1. 새 연습 폴더 만들기
다른 파일과 섞이지 않도록 실행할 때마다 고유한 이름의 폴더를 만듭니다. 아래 준비 코드를 일반 PowerShell 창에 입력하세요. 긴 이름은 자동으로 만들어지므로 직접 외우지 않아도 됩니다.
$practice = Join-Path $HOME ('infosec-step02-' + [guid]::NewGuid().ToString('N'))
New-Item -ItemType Directory -Path $practice -ErrorAction Stop
Set-Location -LiteralPath $practice
pwd
$practice에는 이번 실습 폴더의 전체 경로를 저장합니다. Join-Path는 경로를 연결하고, GUID는 이름 충돌을 피하기 위한 고유 식별자입니다. Directory는 폴더, File은 파일을 뜻합니다. 오류가 나오면 다음 작업으로 넘어가지 마세요.
출력된 경로를 메모하세요. 창을 닫으면 $practice 변수는 사라집니다. 이어서 하려면 메모한 폴더를 확인하고 $practice에 그 경로를 다시 넣습니다. 개인 문서나 내려받은 파일을 이 연습 폴더에 넣지 않습니다.
3-2. 만들기·덮어쓰기·이어 쓰기
빈 파일을 만들고 내용을 기록합니다. 각각 실행한 뒤 출력을 확인하세요.
New-Item -ItemType File test.txt
Set-Content test.txt "hello security" -Encoding UTF8
Get-Content test.txt -Encoding UTF8
hello security
New-Item 직후에는 길이가 0바이트입니다. Set-Content는 기존 내용을 교체합니다. 다음 두 명령으로 교체와 추가의 차이를 비교합니다.
Set-Content test.txt "second line" -Encoding UTF8
Get-Content test.txt -Encoding UTF8
Add-Content test.txt "third line" -Encoding UTF8
Get-Content test.txt -Encoding UTF8
second line
third line
마지막 읽기 결과는 두 줄입니다. -Encoding UTF8은 한글을 포함한 문자를 같은 방식으로 읽고 쓰기 위한 지정입니다. 5.1의 UTF8은 BOM을 포함하고 7의 UTF8은 기본적으로 BOM을 포함하지 않으므로 텍스트가 같아도 바이트 수는 다를 수 있습니다. 이 수업은 임의의 파일 크기 숫자 대신 실제 내용을 확인합니다.
3-3. 복사 — 원본과 사본 확인
Copy-Item test.txt backup.txt
Get-Content test.txt -Encoding UTF8
Get-Content backup.txt -Encoding UTF8
ls
test.txt와 backup.txt가 모두 남아 있고 각각 두 줄이 읽혀야 합니다. 복사하기 전에 같은 이름의 대상이 이미 있는지 확인하세요. 일반 파일의 Copy-Item은 기존 대상을 덮어쓸 수 있습니다.
실제 증거 보존에는 해시, 메타데이터, 수집 기록과 적절한 수집 도구 등이 필요합니다. 이 텍스트 복사 연습을 포렌식 증거 수집 절차 전체로 간주하지 마세요.
3-4. 폴더 안으로 복사
New-Item -ItemType Directory backup
Copy-Item test.txt backup
ls backup
backup이 실제 폴더로 존재하므로 사본은 .\backup\test.txt에 생깁니다. 목적지 폴더가 없으면 같은 명령이 backup이라는 파일을 만들 수 있습니다. 폴더 생성이 실패했다면 이유를 먼저 확인하세요.
3-5. 이동과 이름 변경 — 경로의 역슬래시
Move-Item test.txt .\backup\moved.txt
ls
ls backup
현재 폴더에는 test.txt가 없어지고, backup 안에는 moved.txt와 앞에서 복사한 test.txt가 있어야 합니다.
backup\moved.txt의 \가 폴더와 파일 이름을 나눕니다. 이를 빼서 backupmoved.txt로 쓰면 현재 폴더에서 이름만 바뀝니다. 이동 후에는 원래 위치와 목적지를 둘 다 확인하세요.
Move-Item backup.txt renamed.txt
ls
같은 폴더에서 backup.txt를 renamed.txt로 바꾸었습니다. 목적지에 같은 이름이 있거나 이동이 실패하면 성공했다고 가정하지 말고 오류와 양쪽 파일을 확인합니다.
3-6. 와일드카드로 선택한 뒤 복사
New-Item -ItemType File a.txt, b.txt, c.txt, a.log, b.log
ls *.txt
Copy-Item *.txt backup
ls backup
이 시점의 현재 폴더에서 선택되는 것은 a.txt, b.txt, c.txt, renamed.txt입니다. backup에는 앞서 만든 moved.txt와 test.txt도 남아 있습니다. *.txt는 이름 패턴이므로 실제 작업에서는 같은 이름 패턴의 폴더가 섞이지 않았는지도 확인해야 합니다.
이번에는 이름이 a로 시작하는 항목을 복사합니다. 아래의 backup2 생성도 실습의 필수 단계입니다.
New-Item -ItemType Directory backup2
ls a*
Copy-Item a* backup2
ls backup2
backup2에는 a.log와 a.txt가 있어야 합니다. 다음 절에서 이 폴더만 삭제합니다.
참고: ?의 세부 매칭은 사용한 옵션과 파일 시스템에 따라 다를 수 있습니다. 이번 환경의 ls report?.txt는 report1.txt와 reportA.txt를 골랐고, Get-ChildItem -Filter report?.txt는 report.txt도 포함했습니다. 같은 패턴처럼 보여도 작업 전 실제 목록을 확인하세요.
3-7. 삭제 — 미리보기와 실제 결과 확인
먼저 pwd가 3-1에서 기록한 연습 폴더인지 확인합니다. Remove-Item은 휴지통으로 보내지 않습니다. -WhatIf는 실행 계획을 보여 줄 뿐 백업이나 되돌리기 기능이 아닙니다. -LiteralPath는 경로를 이름 그대로 해석하여 * 같은 문자를 와일드카드로 처리하지 않습니다.
pwd
Remove-Item -LiteralPath .\renamed.txt -WhatIf
ls renamed.txt
미리보기 뒤에도 파일이 남아 있어야 합니다. 대상이 이번 실습에서 만든 renamed.txt 한 개임을 확인한 뒤 실행합니다.
Remove-Item -LiteralPath .\renamed.txt
ls
다음은 새로 만든 두 파일만 대상으로 하는 와일드카드 연습입니다.
New-Item -ItemType File victim1.txt, victim2.txt
ls .\victim*.txt
Remove-Item .\victim*.txt -WhatIf
ls .\victim*.txt
두 파일이 아직 남아 있는지 확인하세요. 미리보기에 다른 파일이 나오면 멈추고 패턴을 고칩니다. 파일 목록은 미리보기 후에도 바뀔 수 있습니다.
Remove-Item .\victim*.txt
ls .\victim*.txt
이번 실습의 두 파일만 사라져 목록이 비어야 합니다. 폴더 삭제에서는 전체 경로와 모든 하위 내용을 먼저 확인합니다. 다음 검사는 대상이 기록한 연습 폴더 바로 아래의 backup2인지 검사합니다.
$discard = (Resolve-Path -LiteralPath '.\backup2').Path
if ($discard -ne (Join-Path $practice 'backup2')) { throw 'Check the practice folder.' }
$discard
Get-ChildItem -LiteralPath $discard -Recurse
Remove-Item -LiteralPath $discard -Recurse -WhatIf
backup2 안에 이번에 복사한 a.txt와 a.log만 있는지 확인한 뒤 아래 한 줄을 실행합니다. -Recurse는 하위 항목까지 삭제하므로 개인 파일이나 다른 경로로 바꾸어 시험하지 마세요.
Remove-Item -LiteralPath $discard -Recurse
ls
backup2가 사라졌는지 확인합니다. 실습 최상위 폴더와 나머지 결과물은 보관합니다.
4. 미션과 연습문제
미션 — 파일 관리자 시험
Set-Location -LiteralPath $practice로 이번 실습 폴더로 돌아와 다음을 수행하세요. 이미 project를 만들었다면 기존 결과를 먼저 확인하세요.
project라는 폴더를 만들고 들어가세요.- 그 안에
plan.txt,memo.txt,data.csv,run.log네 파일을 만드세요. plan.txt에 "This is the plan."라고 내용을 쓰고, 읽어서 확인하세요.archive폴더를 만들고, .txt 파일만 그곳에 복사하세요. (plan.txt원본은 남아 있어야 합니다.)run.log를archive폴더로 이동하세요. (원본 위치에는 없어야 합니다.)data.csv를-WhatIf로 삭제 시뮬레이션한 뒤, 진짜로 삭제하세요.- 마지막에
ls와ls archive결과가 이렇게 되는지 확인하세요:- 현재 폴더:
plan.txt,memo.txt,archive - archive 안:
plan.txt,memo.txt,run.log
- 현재 폴더:
연습문제
문제 1. Copy-Item과 Move-Item의 차이를 한 문장으로 설명하세요.
문제 2. 현재 폴더에 a.txt, b.txt, c.log가 있습니다. Copy-Item *.* backup 대신 .log만 빼고 복사하고 싶습니다. 먼저 비어 있는 backup 폴더를 만든 조건에서 두 가지 방법을 써 보세요. 다른 파일이나 폴더는 없는 예시입니다.
문제 3. Remove-Item *.txt -WhatIf를 쳤더니 지우려던 파일 외에 notes.txt까지 목록에 나왔습니다. 어떻게 해야 할까요?
문제 4. Set-Content a.txt "첫째" -Encoding UTF8 다음에 Set-Content a.txt "둘째" -Encoding UTF8를 쳤습니다. a.txt의 내용은? 이어 붙이려면 어떤 명령을 써야 할까요?
해설과 완료 기준 · 펼치기/접기
5. 모범 답안과 완료 기준
미션 해설
아래는 처음 수행하는 미션의 순서입니다. 위에서 이미 만든 project에 다시 실행하여 덮어쓰지 마세요.
Set-Location -LiteralPath $practice
New-Item -ItemType Directory project -ErrorAction Stop
cd project
New-Item -ItemType File plan.txt, memo.txt, data.csv, run.log
Set-Content plan.txt "This is the plan." -Encoding UTF8
Get-Content plan.txt -Encoding UTF8
New-Item -ItemType Directory archive
Copy-Item *.txt archive
Move-Item run.log .\archive\run.log
Remove-Item -LiteralPath .\data.csv -WhatIf
미리보기 대상이 project\data.csv 한 개인지 확인한 뒤 마무리합니다.
Remove-Item -LiteralPath .\data.csv
ls
ls archive
최종 결과: 현재 폴더에는 archive, memo.txt, plan.txt. archive 안에는 memo.txt, plan.txt, run.log. plan.txt의 원본과 사본에서 같은 문장이 읽혀야 하며, data.csv는 없어야 합니다.
연습문제 해답
문제 1 해답. 복사(Copy-Item)는 원본이 그대로 남고, 이동(Move-Item)은 원본이 사라지고 대상 위치로 옮겨갑니다. (같은 폴더 안 Move-Item은 "이름 바꾸기"가 됩니다.)
문제 2 해답.
- 방법 1 (와일드카드):
Copy-Item *.txt backup - 방법 2 (제외 옵션):
Copy-Item * backup -Exclude *.log,backup(목적지 폴더 자체도 제외합니다)
문제 3 해답. -WhatIf를 떼지 말고 멈춥니다. WhatIf는 그 시점에 예상되는 대상을 보여 줍니다. 이후 파일 목록이 바뀌거나 권한 오류가 날 수도 있습니다. 패턴을 좁혀서(예: 파일명 공통 부분만 victim*.txt처럼) 다시 -WhatIf로 확인한 뒤, 정확한 목록이 나올 때만 진짜 실행합니다. 이것이 WhatIf를 쓰는 이유입니다.
문제 4 해답. 내용은 둘째뿐입니다 — Set-Content는 덮어쓰기입니다. 이어 붙이려면 Add-Content a.txt "둘째" -Encoding UTF8를 씁니다.
완료 기준 체크리스트
- [ ]
New-Item으로 파일과 폴더를 둘 다 만들 수 있다 - [ ]
Set-Content로 쓰고Get-Content로 확인하는 사이클을 할 수 있다 - [ ] 복사(Copy)와 이동(Move)의 차이를 설명할 수 있다
- [ ]
*.txt같은 와일드카드로 파일을 골라 작업할 수 있다 - [ ] 삭제 전에
-WhatIf로 미리 보는 습관을 체험했다 - [ ] 미션 1~7의 최종 상태를 정확히 만들었다
6. 흔한 실수와 해결
벽 1. "중요한 파일을 Remove-Item으로 지웠다!"
중요한 파일을 잘못 지웠다면 해당 저장장치에 새로 쓰는 작업을 줄이고 백업·스냅샷의 복원 가능 여부부터 확인하세요. 복구를 보장할 수 없으므로 예방이 우선입니다:
- 지우기 전
ls로 대상 확인 - 와일드카드로 지울 땐 반드시
-WhatIf먼저 - 중요한 건 지우지 말고
Move-Item으로 "휴지 폴더"에 옮기는 습관
벽 2. Copy-Item을 쳤더니 원본이 아니라 엉뚱한 게 생겼다
대상 폴더가 없는 상태에서 Copy-Item a.txt backup처럼 치면, 파워쉘이 backup을 폴더가 아니라 새 파일 이름으로 알아듣는 경우가 있습니다. 폴더로 복사할 때는 대상 폴더를 먼저 만들고(New-Item -ItemType Directory backup), 복사 후 ls backup으로 확인까지 한 세트로 하세요.
벽 3. 경로에 공백이 있어서 명령이 깨진다
Step 1의 규칙 그대로입니다: Copy-Item "my file.txt" backup처럼 따옴표로 감싸세요. 오늘부터 파일/폴더 이름을 지을 때 공백 대신 -나 _를 쓰는 습관도 CLI 생활을 편하게 합니다. (그래서 개발자들의 파일명에 언더스코어가 많은 겁니다.)
벽 4. 와일드카드가 생각보다 많이(적게) 선택된다
*가 잡아내는 범위를 확신할 수 없을 때는, 지우거나 덮기 전에 선택만 먼저 해 보세요: ls *.txt. 이 목록으로 예상 대상을 점검하되, 실제 명령의 옵션과 실행 시점에 따라 결과가 달라질 수 있으므로 작업 후에도 확인하세요. "선택 확인 → 작업" 순서를 몸에 배도록 하세요.
벽 5. Move-Item으로 옮겼는데 원본이 없어서 당황했다
이동은 원본이 사라지는 게 정상입니다. 원본을 남기고 싶었던 거라면 그건 복사(Copy-Item)의 일이었습니다. 옮긴 위치를 까먹었다면 ls를 이리저리 치지 말고, ↑ 키로 방금 친 명령을 다시 보세요 — 거기 목적지가 적혀 있습니다.
7. 정리
오늘 배운 명령어
| 명령 | 하는 일 | 예 |
|---|---|---|
New-Item |
파일/폴더 만들기 | New-Item a.txt, New-Item -ItemType Directory dir |
Set-Content |
내용 쓰기 (덮어쓰기) | Set-Content a.txt "글" -Encoding UTF8 |
Add-Content |
내용 이어 붙이기 | Add-Content a.txt "글" -Encoding UTF8 |
Get-Content |
내용 읽기 | Get-Content a.txt -Encoding UTF8 |
Copy-Item |
복사 (원본 남음, 같은 이름 덮어씀) | Copy-Item *.txt backup |
Move-Item |
이동/이름 바꾸기 (원본 사라짐) | Move-Item a.txt .\backup\b.txt |
Remove-Item |
삭제 (휴지통 없음) | Remove-Item *.log -WhatIf |
핵심 개념
| 개념 | 한 줄 요약 |
|---|---|
| 확장자 | 파일 종류의 꼬리표. 항상 보이게 하라 |
와일드카드 * |
"아무 글자나" — 조건 선택의 무기 |
| -WhatIf | 실행 전 시뮬레이션. 삭제의 안전벨트 |
| -Recurse | 폴더째 통째로 (하위까지) |
명령어보다 중요한 감각
"지우기 전에 보고, 보고 나서 지운다." 그리고 "분석은 사본으로, 원본은 보존." 이 두 문장은 파일 조작을 넘어 침해 대응 실무의 철칙입니다.
삭제와 안전한 데이터 소거는 다른 작업입니다. 삭제 후 복구 가능성은 저장장치, TRIM, 덮어쓰기와 백업 등에 따라 달라집니다. 특히 SSD의 안전한 소거를 파일의 여러 번 덮어쓰기로 단정할 수 없습니다. 이번 수업에서는 삭제 복구나 저장장치 소거를 실행하지 않습니다.
전부 체크되면 Step 2 완료입니다.
실습 검증 기록
2026-09-10 · Windows 11, Windows PowerShell 5.1.26100.9444와 PowerShell 7.6.5에서 각각 34개 항목을 확인했습니다. 새로 만든 전용 폴더에서 덮어쓰기·추가·복사·이동·와일드카드·WhatIf·폴더 삭제와 미션 최종 파일 목록을 검증했습니다. 기존 역슬래시 누락 오류를 재현한 뒤 수정 명령으로 목적지와 파일 내용을 확인했습니다. 실제 증거 수집, 악성코드 실행, 삭제 복구는 검증 범위에 포함하지 않았습니다.
한 단계 더 가까이
수업을 마쳤나요?
본문의 완료 기준을 확인한 뒤 직접 표시하세요.