개요
PowerShell 변수는 이름 앞에 $를 붙여 만들며, 별도 선언 없이 대입하는 순간 생성된다. 지금까지 다뤄온 $PROFILE(06장), $Matches(20장 예고), $_(15장) 같은 자동 변수도 결국 이 변수 시스템 위에서 동작한다. 이 장은 Part 4까지 다양한 cmdlet의 결과를 담아 온 변수 자체의 규칙 — 이름, 타입, 스코프 — 을 정리하며 Part 5(데이터 구조와 텍스트 처리)의 출발점이 된다.
PowerShell 변수의 핵심 정신 모델은 “변수는 타입이 아니라 값에 묶인 이름표"라는 것이다. $x = 1이라고 쓴 뒤 $x = "hello"로 다시 대입해도 오류가 나지 않는다 — 변수 자체가 [int]나 [string]으로 고정되지 않고, 담긴 값의 타입만 그때그때 바뀌기 때문이다. 타입을 강제하고 싶다면 이름 앞에 타입 리터럴을 붙이는 별도 문법(type-constraining)을 써야 한다.
사용법
| |
종류
| 변수 유형 | 설명 | 예 |
|---|---|---|
| 사용자 변수 | 스크립트·세션에서 직접 만드는 변수 | $count, $serverList |
| 자동 변수 | PowerShell이 자동으로 채우는 변수(24장에서 전체 목록) | $_, $?, $LASTEXITCODE |
| 환경 변수 | OS 환경 변수를 감싼 접근자, Env: 프로바이더 사용 | $env:PATH, $env:USERNAME |
| 기본 설정 변수 | cmdlet 동작을 제어하는 변수(25장에서 다룬 공통 매개변수와 연동) | $ErrorActionPreference, $PSDefaultParameterValues |
타입 제약 문법에 쓸 수 있는 대표 타입은 다음과 같다.
| 타입 리터럴 | 의미 |
|---|---|
[int] | 32비트 정수 |
[string] | 문자열 |
[double] | 배정밀도 부동소수점 |
[bool] | $true/$false |
[datetime] | 날짜·시간(52장에서 자세히) |
[array] | 배열(42장) |
[hashtable] | 해시테이블(44장) |
예시
| |
주의사항·함정
타입 제약은 변수 하나에만 적용되고, 재대입 시 강제로 변환을 시도한다: [int]$x = 10 이후 $x = "20"을 대입하면 문자열 “20"이 int 10으로 변환되어 저장되지만, $x = "abc"처럼 변환 불가능한 값을 넣으면 예외가 발생한다. 반대로 타입 제약이 없는 변수는 어떤 값이든 조용히 받아들이므로, 예상치 못한 타입의 값이 뒤늦게 다른 cmdlet에서 오류를 일으키는 원인이 되기 쉽다. 함수 매개변수나 반복적으로 재사용하는 변수에는 타입 제약을 붙여 실수를 조기에 드러내는 편이 안전하다.
변수 이름의 대소문자는 구분되지 않는다: $Name과 $name은 같은 변수를 가리킨다. 여러 사람이 협업하는 스크립트에서는 이 점이 혼란을 줄 수 있으므로, 프로젝트 전체에서 하나의 표기 관례(PascalCase 등)를 정해 일관되게 쓰는 편이 좋다.
스코프를 명시하지 않으면 항상 “현재” 스코프에 생성·수정된다: 함수 안에서 $x = 1을 쓰면 그 함수의 지역 변수가 새로 생기는 것이지, 같은 이름의 전역 변수를 바꾸는 것이 아니다. 스코프의 전체 규칙(전역·지역·스크립트·비공개)은 64장에서 함수와 함께 자세히 다룬다 — 지금은 “변수는 기본적으로 자신이 만들어진 블록 안에서만 보인다"는 원칙만 기억하면 된다.
이식성: Bash는 x=10처럼 $ 없이 대입하고 참조할 때만 $x를 붙이며 기본적으로 모든 값을 문자열로 다룬다. CMD의 set x=10과 %x%도 문자열 전용이다. PowerShell은 대입·참조 모두 $ 접두사를 쓰고, 문자열이 아닌 실제 .NET 타입(정수·불리언·날짜 등)을 그대로 저장한다는 점이 근본적으로 다르다 — 이 차이가 10장에서 강조한 객체 파이프라인의 토대이기도 하다.
![Featured image of post [PowerShell] 41. 변수와 데이터 타입](/post/powershell/variables-data-types-powershell/wordcloud_hu_443a57c6ccec381c.webp)
![[PowerShell] 39. Test-Path — 경로 존재 확인](/post/powershell/test-path-command-check-path-powershell/wordcloud_hu_8b7ea3ad5761442.webp)
![[PowerShell] 40. 레지스트리 프로바이더(Registry:) 다루기](/post/powershell/registry-provider-hklm-hkcu-powershell/wordcloud_hu_cf90c98823ba3b1c.webp)
![[PowerShell] 41. 변수와 데이터 타입](/post/powershell/variables-data-types-powershell/wordcloud_hu_6051f7a36d4700ee.webp)
![[PowerShell] 42. 배열과 컬렉션 기초](/post/powershell/arrays-collections-powershell/wordcloud_hu_c295cc73d4592ae5.webp)
![[PowerShell] 43. ArrayList와 Generic List(List<T>)](/post/powershell/arraylist-generic-list-powershell/wordcloud_hu_a34550a6370cee87.webp)
![[PowerShell] 62. 스코프(Scope) — 전역/지역/스크립트](/post/powershell/scope-global-local-script-powershell/wordcloud_hu_59e4df2abadaaec.webp)
![[PowerShell] 23. 타입 캐스팅과 [type] 접근자](/post/powershell/type-casting-type-accelerator-powershell/wordcloud_hu_e3ac5e77eecdb3c5.webp)
![[PowerShell] 44. 해시테이블(Hashtable) 다루기](/post/powershell/hash-tables-powershell/wordcloud_hu_d1fd29269ce3c32d.webp)