PowerShell이란?
PowerShell은 Microsoft가 개발한 객체 지향 셸 및 스크립팅 언어입니다. CMD의 텍스트 기반 출력과 달리, PowerShell은 .NET 객체를 파이프라인으로 전달합니다. 스크립트 파일 확장자는 .ps1이며, Windows 관리, CI/CD 자동화, 시스템 모니터링 등에 사용됩니다.
이 글에서는 PowerShell의 기본 문법, 변수, 함수, 파이프라인, 그리고 실전 자동화 스크립트까지 다룹니다.
BAT vs PowerShell 비교
| 항목 | BAT (CMD) | PowerShell |
|---|---|---|
| 출력 방식 | 텍스트 문자열 | .NET 객체 |
| 변수 | %VAR% | $VAR |
| 파이프라인 | 텍스트 전달 | 객체 전달 (속성 접근 가능) |
| 에러 처리 | %ERRORLEVEL% | try/catch/finally |
| 함수 | 라벨 + goto | function 키워드 |
| 모듈 시스템 | 없음 | PowerShell Gallery |
| 크로스 플랫폼 | Windows 전용 | Windows, macOS, Linux |
기본 문법
PowerShell은 동사-명사 형태의 Cmdlet(커맨드렛)을 사용합니다. 변수는 $로 시작하며, 타입이 자동 추론됩니다.
# 출력
Write-Host "안녕하세요, PowerShell입니다!" -ForegroundColor Green
# 변수 선언 (타입 자동 추론)
$name = "PowerShell"
$version = 7.4
$today = Get-Date
Write-Host "이름: $name, 버전: $version"
Write-Host "오늘 날짜: $($today.ToString('yyyy-MM-dd HH:mm'))"
# 배열과 해시테이블
$fruits = @("사과", "바나나", "포도")
$config = @{
Host = "localhost"
Port = 8080
Debug = $true
}
Write-Host "첫 번째 과일: $($fruits[0])" # 사과
Write-Host "포트: $($config.Port)" # 8080
문자열 안에서 변수를 참조할 때 큰따옴표(")를 사용합니다. 작은따옴표(')는 변수를 해석하지 않고 그대로 출력합니다. 복잡한 표현식은 $()로 감쌉니다.
파이프라인과 객체
PowerShell의 가장 강력한 기능은 객체 파이프라인입니다. | 연산자로 Cmdlet을 연결하면, 텍스트가 아닌 객체가 전달되어 속성에 직접 접근할 수 있습니다.
# 프로세스 목록에서 메모리 사용량 상위 5개 조회
Get-Process |
Sort-Object WorkingSet64 -Descending |
Select-Object -First 5 Name, @{N='메모리(MB)'; E={[math]::Round($_.WorkingSet64/1MB, 1)}} |
Format-Table -AutoSize
# 출력 예시:
# Name 메모리(MB)
# ---- ----------
# chrome 1024.3
# code 512.7
# explorer 256.1
# 특정 확장자 파일 검색 + 크기 합계
$totalSize = Get-ChildItem -Path "C:\Projects" -Recurse -Filter "*.log" |
Measure-Object -Property Length -Sum
Write-Host "로그 파일 총 크기: $([math]::Round($totalSize.Sum/1MB, 2)) MB"
Get-Process는 프로세스 객체를 반환하고, Sort-Object는 WorkingSet64 속성으로 정렬합니다. BAT에서는 텍스트 파싱이 필요한 작업이 PowerShell에서는 속성 접근만으로 해결됩니다.
조건문, 반복문, 함수
PowerShell은 C# 계열 문법과 유사한 제어 구조를 제공합니다.
# === 조건문 ===
$score = 85
if ($score -ge 90) {
Write-Host "A등급"
} elseif ($score -ge 80) {
Write-Host "B등급" # B등급
} else {
Write-Host "C등급 이하"
}
# switch 문
$os = "Windows"
switch ($os) {
"Windows" { Write-Host "Windows 감지" }
"Linux" { Write-Host "Linux 감지" }
default { Write-Host "알 수 없는 OS" }
}
# === 반복문 ===
# foreach: 배열 순회
$servers = @("web01", "web02", "db01")
foreach ($server in $servers) {
Write-Host "서버 점검: $server"
}
# for: 숫자 범위
for ($i = 1; $i -le 5; $i++) {
Write-Host "카운트: $i"
}
# === 함수 ===
function Get-DiskUsage {
param(
[string]$DriveLetter = "C" # 기본값
)
$disk = Get-PSDrive -Name $DriveLetter
$usedGB = [math]::Round($disk.Used / 1GB, 1)
$freeGB = [math]::Round($disk.Free / 1GB, 1)
return @{ Used = $usedGB; Free = $freeGB }
}
$usage = Get-DiskUsage -DriveLetter "C"
Write-Host "C: 사용 $($usage.Used)GB / 여유 $($usage.Free)GB"
비교 연산자는 -eq(같다), -ne(다르다), -gt(크다), -ge(크거나 같다), -lt(작다), -le(작거나 같다)를 사용합니다. BAT의 EQU/NEQ와 유사하지만 하이픈 접두사가 특징입니다.
| PowerShell | 의미 | BAT 등가 |
|---|---|---|
-eq | 같다 | EQU |
-ne | 다르다 | NEQ |
-gt | 크다 | GTR |
-ge | 크거나 같다 | GEQ |
-lt | 작다 | LSS |
-le | 작거나 같다 | LEQ |
-like | 와일드카드 매칭 | 없음 |
-match | 정규표현식 매칭 | 없음 |
실전 스크립트: 서비스 모니터링
지정된 서비스의 상태를 점검하고, 중지된 서비스를 자동 재시작하는 스크립트입니다.
# service-monitor.ps1 — 서비스 상태 점검 및 자동 재시작
param(
[string[]]$ServiceNames = @("W32Time", "Spooler"),
[string]$LogPath = ".\service-monitor.log"
)
function Write-Log {
param([string]$Message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$entry = "[$timestamp] $Message"
Add-Content -Path $LogPath -Value $entry
Write-Host $entry
}
Write-Log "=== 서비스 모니터링 시작 ==="
foreach ($svcName in $ServiceNames) {
try {
$service = Get-Service -Name $svcName -ErrorAction Stop
if ($service.Status -eq "Running") {
Write-Log "[OK] $svcName — 정상 실행 중"
} else {
Write-Log "[경고] $svcName — 상태: $($service.Status). 재시작 시도..."
Start-Service -Name $svcName -ErrorAction Stop
Write-Log "[복구] $svcName — 재시작 완료"
}
} catch {
Write-Log "[오류] $svcName — $($_.Exception.Message)"
}
}
Write-Log "=== 모니터링 완료 ==="
try/catch로 에러를 처리하고, -ErrorAction Stop으로 비종료 에러도 catch 블록에서 잡을 수 있게 합니다. param() 블록으로 스크립트 매개변수를 정의하면 .\service-monitor.ps1 -ServiceNames "W32Time","Spooler"처럼 호출할 수 있습니다.
실행 정책 설정
PowerShell은 보안을 위해 기본적으로 스크립트 실행이 차단되어 있습니다. PS1 파일을 실행하려면 실행 정책을 변경해야 합니다.
# 현재 실행 정책 확인
Get-ExecutionPolicy
# Restricted (기본값 — 스크립트 실행 차단)
# 현재 사용자에 대해 스크립트 실행 허용
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# RemoteSigned: 로컬 스크립트 허용, 원격 스크립트는 서명 필요
| 정책 | 설명 |
|---|---|
Restricted | 스크립트 실행 차단 (기본값) |
RemoteSigned | 로컬 스크립트 허용, 원격은 서명 필요 (권장) |
Unrestricted | 모든 스크립트 허용 (비권장) |
Bypass | 제한 없음, 경고 없음 (CI/CD용) |
정리
PowerShell은 BAT의 한계를 넘어서는 강력한 자동화 도구입니다. 핵심 포인트를 정리하면 다음과 같습니다.
- 객체 파이프라인이 핵심 — 텍스트 파싱 대신
.속성으로 데이터 접근 - 변수는
$로 시작, 비교는-eq/-ne/-gt등 하이픈 접두사 try/catch/finally로 체계적 에러 처리param()블록으로 스크립트 매개변수 정의- 실행 전
Set-ExecutionPolicy RemoteSigned설정 필수 - PowerShell 7+는 Windows, macOS, Linux 크로스 플랫폼 지원