스크립트는 .ps1 파일이다
콘솔에 치던 명령을 .ps1 파일에 적으면 스크립트다. 편집기는 무엇이든 되지만 Visual Studio Code에 PowerShell 확장을 깔면 자동 완성, 디버깅, 문법 검사(PSScriptAnalyzer)를 함께 쓸 수 있다. 예전의 PowerShell ISE는 5.1 전용이고 더는 개발되지 않는다.
# hello.ps1
param([string]$Name = 'World')
"Hello, $Name!"
실행할 때는 경로를 적는다. 현재 폴더의 파일도 ./를 붙여야 한다. 현재 폴더를 뒤지지 않는 것은 실수로 엉뚱한 파일을 실행하지 않게 하려는 의도된 동작이다.
./hello.ps1
./hello.ps1 -Name talsu
경로에 공백이 있으면 따옴표로 감싸고 호출 연산자 &를 앞에 붙인다. 따옴표만 있으면 그냥 문자열이라 실행되지 않는다.
& './my scripts/hello.ps1' -Name talsu
점으로 불러오기
스크립트 안에서 만든 변수와 함수는 스크립트가 끝나면 사라진다. 현재 세션에 남기려면 앞에 점과 공백을 붙여 불러온다(dot sourcing).
. ./functions.ps1
함수 몇 개를 파일 하나에 모아 두고 쓰는 가장 간단한 방법이다. 여러 곳에서 쓸 것이면 모듈로 만드는 편이 낫다(3편).
실행 정책 (Windows)
Windows에서 스크립트를 실행하다 보면 이런 오류를 만난다.
./hello.ps1: File C:\work\hello.ps1 cannot be loaded because running scripts
is disabled on this system.
한국어 Windows에서는 같은 오류가 이렇게 나온다.
./hello.ps1: 이 시스템에서 스크립트 실행이 사용하지 않도록 설정되어 있으므로
File C:\work\hello.ps1을(를) 로드할 수 없습니다.
실행 정책(execution policy) 때문이다. 정책은 네 가지를 알면 된다.
| 정책 | 뜻 |
|---|---|
Restricted | 스크립트 실행 안 함 |
RemoteSigned | 내 컴퓨터에서 만든 것은 실행. 인터넷에서 받은 것은 서명이 있어야 실행 |
AllSigned | 서명된 것만 실행 |
Bypass | 아무것도 막지 않고 묻지도 않음 |
기본값은 어느 PowerShell이냐에 따라 다르다. 둘은 정책을 따로 저장한다.
| 기본값 | 저장하는 곳 | |
|---|---|---|
| Windows PowerShell 5.1 | 클라이언트는 Restricted, 서버는 RemoteSigned | 레지스트리 |
| PowerShell 7 | RemoteSigned | 설치 폴더의 powershell.config.json |
그래서 Windows 11에 PowerShell 7을 막 설치한 상태라면 내가 만든 스크립트는 그냥 실행된다. 위의 오류를 만나는 것은 5.1에서 실행했거나, 인터넷에서 받은 파일이거나, 조직이 정책을 걸어 둔 경우다. 지금 걸린 값은 범위별로 볼 수 있다.
Get-ExecutionPolicy -List
범위는 MachinePolicy, UserPolicy, Process, CurrentUser, LocalMachine 다섯이다. PowerShell 7을 막 설치한 Windows 11에서는 LocalMachine만 RemoteSigned이고 나머지는 Undefined다.
위에서부터 먼저 적용된다. MachinePolicy와 UserPolicy는 그룹 정책이 건 것이라 내가 바꿀 수 없다.
5.1에서 스크립트를 써야 하거나 정책이 Restricted로 걸려 있으면, RemoteSigned를 현재 사용자에게만 건다. 관리자 권한이 필요 없다.
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
Get-ExecutionPolicy -List
인터넷에서 받은 스크립트는 RemoteSigned에서도 막힌다. 내용을 읽어 보고 믿을 만하면 그 파일의 차단 표시를 푼다.
Unblock-File ./downloaded.ps1
정책을 바꾸지 않고 한 번만 실행하려면 이렇게 한다. CI나 예약 작업에서 흔히 쓴다.
pwsh -ExecutionPolicy Bypass -File ./build.ps1
실행 정책은 보안 경계가 아니다. 실수로 스크립트를 실행하는 일을 막는 안전장치일 뿐이고, 마음먹은 사람은 위처럼 한 줄로 지나간다. 조직에서 스크립트 실행을 정말로 통제하려면 그룹 정책과 애플리케이션 제어(App Control)를 쓴다.
리눅스와 macOS에는 실행 정책이 없다. Get-ExecutionPolicy는 늘 Unrestricted를 돌려주고 바꿀 수도 없다. 그쪽에서는 운영체제의 파일 권한이 그 일을 한다.
리눅스와 macOS에서 바로 실행하기
첫 줄에 셔뱅을 적고 실행 권한을 주면 셸 스크립트처럼 실행된다.
#!/usr/bin/env pwsh
"Running on $($PSVersionTable.OS)"
chmod +x ./info.ps1
./info.ps1
프로필: 시작할 때마다 실행되는 스크립트
PowerShell은 시작할 때 프로필 스크립트를 실행한다. 자주 쓰는 함수, 별칭, 프롬프트 설정을 여기에 둔다. 경로는 $PROFILE에 들어 있다.
$PROFILE
# Windows: C:\Users\talsu\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
# 리눅스: /home/talsu/.config/powershell/Microsoft.PowerShell_profile.ps1
Windows PowerShell 5.1의 프로필은 Documents\WindowsPowerShell 아래에 따로 있다. 한쪽에 넣은 설정은 다른 쪽에 적용되지 않는다.
파일이 없으면 만들고 편집한다.
if (-not (Test-Path $PROFILE)) { New-Item $PROFILE -Force }
code $PROFILE
프로필이 길어지면 시작이 느려진다. 무거운 모듈을 프로필에서 미리 불러오지 않는다. 모듈은 그 명령을 처음 쓸 때 자동으로 불려 온다. 프로필 없이 깨끗한 상태로 띄워 보려면 pwsh -NoProfile을 쓴다. 스크립트가 내 컴퓨터에서만 되는 이유가 프로필인 경우가 많다.
다음 글: 명령의 종류와 모듈