PowerShell 기초
PowerShell 기초
PowerShell 은 Microsoft 가 만든 셸이자 스크립팅 언어입니다. 텍스트가 아닌 .NET 객체를 파이프로 흘려보낸다는 점에서 bash 계열과 결이 다릅니다.
1. PowerShell 에 대한 이야기
PowerShell 은 2006 년 Windows PowerShell 1.0 으로 처음 출시. .NET 프레임워크 위에서 동작하는 셸로, 명령 (cmdlet) 이 텍스트 대신 객체를 입출력합니다. 시스템 관리·자동화 목적이 강한 흐름에서 출발.
2. 두 갈래의 PowerShell
| 항목 | Windows PowerShell 5.1 | PowerShell 7+ |
|---|---|---|
| 런타임 | .NET Framework | .NET Core / .NET 5+ |
| 플랫폼 | Windows 전용 | Windows · macOS · Linux |
| 기본 인코딩 | UTF-16 LE (BOM) | UTF-8 (BOM 없음) |
&& · ` |
` 파이프라인 체인 | |
삼항 연산자 ? : |
미지원 | 지원 |
| 실행 파일 | powershell.exe |
pwsh |
| 지원 | Windows 와 함께 보안 패치만 | 활발한 개발 |
5.1 은 Windows 10/11 에 기본 탑재되어 사라지지 않습니다. 7+ 는 별도 설치 (winget install Microsoft.PowerShell 또는 macOS 의 brew install powershell) 필요.
3. cmdlet 의 명명 규약
cmdlet 은 Verb-Noun 형식.
| Verb | 의미 |
|---|---|
Get- |
조회 (Get-Process · Get-ChildItem). |
Set- |
변경 (Set-Location · Set-Content). |
New- |
생성 (New-Item · New-Object). |
Remove- |
삭제 (Remove-Item). |
Start- · Stop- |
시작/중지. |
Invoke- |
실행 (Invoke-WebRequest · Invoke-RestMethod). |
승인된 동사 목록은 Get-Verb 로 확인. 일관된 명명은 자동완성과 학습에 도움.
4. 별칭 (alias)
| 별칭 | 본명 |
|---|---|
ls · dir · gci |
Get-ChildItem |
cd · sl |
Set-Location |
cat · gc |
Get-Content |
cp · copy |
Copy-Item |
mv · move |
Move-Item |
rm · del |
Remove-Item |
pwd |
Get-Location |
cls |
Clear-Host |
스크립트 안에서는 가독성을 위해 본명 사용 권장 (PSScriptAnalyzer 의 AvoidUsingCmdletAliases).
5. .ps1 와 실행 정책
.ps1 는 PowerShell 스크립트 확장자. 보안상 기본 실행 정책이 Restricted 라 새로 받은 스크립트가 곧바로 실행되지 않습니다.
| 정책 | 동작 |
|---|---|
Restricted |
차단 (기본). |
AllSigned |
서명된 스크립트만. |
RemoteSigned |
인터넷에서 받은 스크립트는 서명 필요, 로컬은 자유. |
Unrestricted |
인터넷 스크립트는 경고 후 실행. |
Bypass |
모두 통과 (CI 등). |
Get-ExecutionPolicy
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
-Scope CurrentUser 는 관리자 권한 없이 자기 사용자에만 적용.
6. 객체 파이프
bash 의 파이프가 텍스트라면 PowerShell 의 파이프는 객체:
# bash
ps -ef | grep node | awk '{print $2}'
# PowerShell
Get-Process | Where-Object { $_.Name -eq "node" } | Select-Object -ExpandProperty Id
PowerShell 은 객체의 속성에 직접 접근하므로 awk 같은 텍스트 파싱이 필요 없습니다. 반면 외부 명령 (git · curl) 의 출력은 문자열로 들어오므로 그때는 텍스트 파싱이 다시 필요.
7. bash 등가 명령
| 작업 | bash | PowerShell |
|---|---|---|
| 디렉터리 목록 | ls -la |
Get-ChildItem -Force |
| 현재 위치 | pwd |
Get-Location (pwd) |
| 화면 비우기 | clear |
Clear-Host (cls) |
| 파일 보기 | cat file |
Get-Content file |
| 파일 검색 | find . -name "*.md" |
Get-ChildItem -Recurse -Filter *.md |
| 내용 검색 | grep -r "TODO" . |
Select-String -Path *.* -Pattern "TODO" |
| 환경변수 조회 | echo $PATH |
$env:PATH |
| 환경변수 설정 | export FOO=bar |
$env:FOO = "bar" |
| HTTP 요청 | curl ... |
Invoke-WebRequest ... |
| 명령 체인 (성공시) | a && b |
a; if ($?) { b } (5.1) / a && b (7+) |
| 종료 코드 | $? |
$LASTEXITCODE (외부 exe) / $? (cmdlet) |
8. 인코딩 함정 (5.1)
Windows PowerShell 5.1 은 Out-File · Set-Content · > 리다이렉션의 기본 인코딩이 UTF-16 LE (BOM 포함). 다른 도구가 UTF-8 을 기대할 때 깨진 파일이 만들어집니다.
# 5.1 안전 패턴
"hello" | Out-File -Encoding utf8 file.txt
Set-Content -Encoding utf8 -Path file.txt -Value "hello"
PowerShell 7+ 는 기본이 UTF-8 (BOM 없음) 로 바뀌었습니다.
9. 기본 문법
$name = "world"
Write-Output "hello, $name"
if (Test-Path "config.json") {
Write-Output "found"
} else {
Write-Output "missing"
}
foreach ($f in Get-ChildItem -Filter *.txt) {
Write-Output $f.Name
}
function Greet {
param([string]$Name)
"hello, $Name"
}
Greet -Name "alice"
10. 자주 걸리는 자리
5.1 의 && · || 미지원 — 명령 체인을 ; if ($?) { ... } 로 풀어 씀.
외부 exe 의 stderr 를 2>&1 로 리다이렉트하면 5.1 에서 ErrorRecord 로 감싸져 $? 가 $false 가 되는 사례. 가능하면 stderr 는 그대로.
Set-ExecutionPolicy Bypass -Scope Process 를 무심코 시스템 전역에 적용 — -Scope Process 또는 -Scope CurrentUser 로 제한.
출력 인코딩이 UTF-16 LE 이라 다른 도구 (Node · Python) 가 못 읽는 경우 — -Encoding utf8 명시.
cmdlet 이름의 대소문자 비구분이라 익숙하지만, 외부 도구로 출력을 넘길 때 별칭 의존이 의외의 호환성 문제.
하고픈 말
PowerShell 은 객체 파이프 + Verb-Noun 명명 + 강력한 cmdlet 라이브러리가 매력입니다. 다만 5.1 의 인코딩 · && 부재 · 실행 정책 셋이 처음 학습 비용. 7+ 가 크로스플랫폼이고 bash 와 같은 줄에 있을 수 있다는 점이 미래 모양.
Next
- cmd-and-bat
- cross-platform-scripts
Microsoft PowerShell 문서 · about_Execution_Policies · about_Pipelines · PowerShell on GitHub · PSScriptAnalyzer 를 참고합니다.