PowerShell 실행 정책
PowerShell 실행 정책 (about_Execution_Policies)
PowerShell의 **실행 정책(Execution Policy)**이 뭔지, 그리고 어떻게 관리하는지 설명해 드릴게요. 실행 정책은 PowerShell이 설정 파일을 불러오고 스크립트를 실행할 때의 조건을 제어하는 안전장치예요. 덕분에 악성 스크립트가 실행되는 걸 막아 주는 역할을 해요.
Windows 컴퓨터에서는 컴퓨터 전체(local computer), 현재 사용자(current user), 또는 특정 세션 단위로 실행 정책을 정할 수 있어요. 또 그룹 정책(Group Policy) 설정을 이용해서 컴퓨터와 사용자 대상의 실행 정책을 정해 둘 수도 있고요.
컴퓨터 전체와 현재 사용자용 실행 정책은 PowerShell 설정 파일에 저장돼요. 그래서 굳이 PowerShell 프로필에 실행 정책을 따로 설정할 필요는 없어요. 반면 특정 세션용 실행 정책은 메모리에만 저장되기 때문에, 세션이 닫히면 그대로 사라져요.
한 가지 꼭 짚어 둘게요. 실행 정책은 **보안 경계(security boundary)가 아니라 방어 심층(defense in depth)**이에요. 예를 들어 사용자가 스크립트를 실행할 수 없을 때, 그냥 스크립트 내용을 명령줄에 직접 타이핑해 버리면 정책을 쉽게 우회할 수 있어요. 그래서 실행 정책의 역할은 사용자가 기본 규칙을 세우고, 그 규칙을 실수로 어기지 않도록 막아 주는 거예요.
보안 경계에 대한 더 자세한 내용은 PowerShell 보안 기능 문서의 보안 서비스 기준 섹션을 참고해 주세요.
Windows가 아닌 컴퓨터에서는 기본 실행 정책이 Unrestricted이고, 이것은 바꿀 수 없어요. Set-ExecutionPolicy cmdlet 자체는 쓸 수 있지만, PowerShell이 "지원되지 않는다"는 콘솔 메시지를 보여 줘요. Windows가 아닌 플랫폼에서 Get-ExecutionPolicy는 Unrestricted를 반환하지만, 실제 동작은 Bypass에 가까워요. 그 이유는 그런 플랫폼에서는 Windows 보안 영역(Security Zones)을 구현하지 않기 때문이에요.
본문
PowerShell 실행 정책
이 정책들은 오직 Windows 플랫폼에서만 적용돼요. PowerShell 실행 정책은 다음과 같아요.
-
AllSigned- 스크립트 실행을 허용해요.
- 로컬 컴퓨터에서 직접 작성한 스크립트까지 포함해서, 모든 스크립트와 설정 파일이 신뢰할 수 있는 게시자(publisher)의 서명을 받아야 해요.
- 아직 신뢰하거나 불신한다고 분류하지 않은 게시자의 스크립트를 실행하기 전에 확인을 요청해요.
- 서명은 됐지만 악성인 스크립트를 실행할 위험이 있어요.
-
Bypass- 아무것도 차단하지 않고, 경고나 확인 프롬프트도 없어요.
- 이 정책은 PowerShell 스크립트가 더 큰 애플리케이션 안에 내장되거나, PowerShell이 자체 보안 모델을 가진 프로그램의 기반이 되는 구성에 설계된 거예요.
-
Default- 기본 실행 정책으로 설정해요.
- Windows 클라이언트와 서버에서는 RemoteSigned가 기본이에요.
-
RemoteSigned- Windows 컴퓨터의 기본 실행 정책이에요.
- 스크립트 실행을 허용해요.
- 인터넷(이메일, 인스턴트 메시징 프로그램 포함)에서 다운로드한 스크립트와 설정 파일은 신뢰할 수 있는 게시자의 디지털 서명이 필요해요.
- 로컬 컴퓨터에서 작성해서 인터넷에서 다운로드하지 않은 스크립트에는 디지털 서명이 필요 없어요.
- 인터넷에서 다운로드했지만 서명이 없는 스크립트도,
Unblock-Filecmdlet 같은 걸로 차단을 해제(unblock)하면 실행돼요. - 인터넷이 아닌 곳에서 온 서명 없는 스크립트나, 악성일 수 있는 서명된 스크립트를 실행할 위험이 있어요.
-
Restricted- 개별 명령은 실행할 수 있지만 스크립트는 실행하지 못해요.
- 모든 스크립트 파일을 실행하지 못하게 막아요. 여기에는 서식/구성 파일(
.ps1xml), 모듈 스크립트 파일(.psm1), PowerShell 프로필(.ps1)이 다 포함돼요.
-
Undefined- 현재 범위(scope)에 실행 정책이 설정돼 있지 않아요.
- 모든 범위의 실행 정책이 Undefined면, 효력이 있는 실행 정책은 Windows 클라이언트에서는 Restricted, Windows Server에서는 RemoteSigned가 돼요.
-
Unrestricted- Windows가 아닌 컴퓨터의 기본 실행 정책이고, 바꿀 수 없어요.
- 서명 없는 스크립트를 실행할 수 있어요. 악성 스크립트를 실행할 위험이 있죠.
- 로컬 인트라넷 영역이 아닌 곳에서 온 스크립트와 설정 파일을 실행하기 전에 사용자에게 경고를 보여 줘요.
참고 UNC(범용 명명 규칙) 경로를 인터넷 경로와 구분하지 않는 시스템에서는, UNC 경로로 식별된 스크립트가 RemoteSigned 실행 정책에서 실행이 허용되지 않을 수 있어요.
실행 정책의 범위와 우선순위
특정 범위에서만 유효한 실행 정책을 설정할 수 있어요. 이 매개변수는 다음 값을 받아요.
MachinePolicy- 컴퓨터의 모든 사용자에 대해 그룹 정책으로 설정돼요.UserPolicy- 컴퓨터의 현재 사용자에 대해 그룹 정책으로 설정돼요.Process- 현재 PowerShell 세션에만 영향을 줘요.CurrentUser- 현재 사용자에게만 영향을 줘요.LocalMachine- 컴퓨터의 모든 사용자에게 영향을 주는 기본 범위예요.
참고
MachinePolicy와UserPolicy는 그룹 정책으로 설정돼요. 이 값들 중 하나를 범위로 설정하려고 하면, PowerShell이 해당 범위는 그룹 정책으로 설정돼 있어서 바꿀 수 없다는 오류 메시지를 보여 줘요.
실행 정책이 그룹 정책으로 정의돼 있지 않다면, 효력이 있는 실행 정책은 다음 우선순위 순서에 따라 정해져요.
-
Process- 우선순위가 가장 높아요.Process범위는 현재 PowerShell 세션에만 영향을 줘요. 실행 정책은 레지스트리가 아니라 환경 변수$Env:PSExecutionPolicyPreference에 저장돼요. PowerShell 세션이 닫히면 이 변수와 값도 함께 삭제돼요. -
CurrentUser- 두 번째로 높은 우선순위예요. 이 설정은 사용자별powershell.config.json파일에 저장돼요. -
LocalMachine- 우선순위가 가장 낮아요. 이 설정은$PSHOME/powershell.config.json파일에 저장돼요.
powershell.config.json 파일에 대한 더 자세한 내용은 about_PowerShell_Config 문서를 참고해 주세요.
PowerShell로 실행 정책 관리하기
현재 PowerShell 세션의 효력이 있는 실행 정책을 확인하려면 Get-ExecutionPolicy cmdlet을 사용해요.
다음 명령은 효력이 있는 실행 정책을 가져와요.
Get-ExecutionPolicy
현재 세션에 영향을 주는 모든 실행 정책을 우선순위 순서대로 가져오려면:
Get-ExecutionPolicy -List
결과는 대략 다음 샘플 출력처럼 보여요.
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser RemoteSigned
LocalMachine AllSigned
이 경우 효력이 있는 실행 정책은 RemoteSigned예요. 그 이유는 현재 사용자의 실행 정책이 로컬 컴퓨터에 설정된 실행 정책보다 우선하기 때문이에요.
특정 범위에 설정된 실행 정책을 가져오려면, Get-ExecutionPolicy의 Scope 매개변수를 사용해요.
예를 들어 다음 명령은 CurrentUser 범위의 실행 정책을 가져와요.
Get-ExecutionPolicy -Scope CurrentUser
실행 정책 변경하기
Windows 컴퓨터에서 PowerShell 실행 정책을 바꾸려면 Set-ExecutionPolicy cmdlet을 사용해요. 변경 사항은 즉시 적용되고, PowerShell을 재시작할 필요가 없어요.
LocalMachine 또는 CurrentUser 범위에 실행 정책을 설정하면, 그 변경 사항은 구성 파일에 저장돼서 다시 바꾸기 전까지 계속 유효해요.
Process 범위에 실행 정책을 설정하면, 구성 파일에 저장되지 않아요. 실행 정책은 현재 프로세스와 그 자식 프로세스가 모두 닫힐 때까지 유지돼요.
참고 Windows Vista 이상에서는 로컬 컴퓨터(LocalMachine 범위)의 실행 정책을 바꾸는 명령을 실행하려면, 관리자 권한으로 실행 옵션으로 PowerShell을 시작해야 해요.
실행 정책을 바꾸려면:
Set-ExecutionPolicy -ExecutionPolicy <PolicyName>
예를 들어:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
특정 범위에 실행 정책을 설정하려면:
Set-ExecutionPolicy -ExecutionPolicy <PolicyName> -Scope <scope>
예를 들어:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
실행 정책을 바꾸는 명령이 성공해도, 효력이 있는 실행 정책이 바뀌지 않을 수 있어요.
예를 들어, 로컬 컴퓨터의 실행 정책을 설정하는 명령이 성공해도, 현재 사용자의 실행 정책에 덮어써질 수 있어요.
실행 정책 제거하기
특정 범위의 실행 정책을 제거하려면, 실행 정책을 Undefined로 설정하면 돼요.
예를 들어, 로컬 컴퓨터의 모든 사용자에 대한 실행 정책을 제거하려면:
Set-ExecutionPolicy -ExecutionPolicy Undefined -Scope LocalMachine
Scope의 실행 정책을 제거하려면:
Set-ExecutionPolicy -ExecutionPolicy Undefined -Scope CurrentUser
어느 범위에도 실행 정책이 설정돼 있지 않다면, 효력이 있는 실행 정책은 Restricted예요. 이게 Windows 클라이언트의 기본값이에요.
세션마다 다른 정책 설정하기
pwsh.exe의 ExecutionPolicy 매개변수를 사용해서 새 PowerShell 세션의 실행 정책을 설정할 수 있어요. 그 정책은 현재 세션과 자식 세션에만 영향을 줘요.
새 세션의 실행 정책을 설정하려면, cmd.exe 같은 명령줄이나 PowerShell에서 PowerShell을 시작하면서 pwsh.exe의 ExecutionPolicy 매개변수를 사용해요.
예를 들어:
pwsh.exe -ExecutionPolicy AllSigned
이렇게 설정한 실행 정책은 구성 파일에 저장되지 않아요. 대신 $Env:PSExecutionPolicyPreference 환경 변수에 저장되죠. 이 변수는 정책을 설정한 세션이 닫힐 때 삭제돼요. 그리고 이 변수 값을 편집해서 정책을 바꿀 수는 없어요.
세션 동안, 세션에 설정된 실행 정책은 로컬 컴퓨터나 현재 사용자용 구성 파일에 설정된 실행 정책보다 우선해요. 다만 그룹 정책으로 설정된 실행 정책보다는 우선하지 않아요.
그룹 정책으로 실행 정책 관리하기
Turn on Script Execution(스크립트 실행 켜기) 그룹 정책 설정으로 기업 내 컴퓨터들의 실행 정책을 관리할 수 있어요. 이 그룹 정책 설정은 모든 범위에서 PowerShell로 설정된 실행 정책을 덮어써요.
Turn on Script Execution 정책 설정은 다음과 같아요.
-
Turn on Script Execution을 사용 안 함으로 설정하면, 스크립트가 실행되지 않아요. 이건 Restricted 실행 정책과 동일해요.
-
Turn on Script Execution을 사용함으로 설정하면, 실행 정책을 선택할 수 있어요. 그룹 정책 설정은 다음 실행 정책 설정과 동일해요.
| Group Policy | Execution Policy |
|---|---|
| Allow all scripts | Unrestricted |
| Allow local scripts and remote signed scripts | RemoteSigned |
| Allow only signed scripts | AllSigned |
- Turn on Script Execution이 구성되지 않으면 아무 효과도 없어요. 그러면 PowerShell에 설정된 실행 정책이 적용돼요.
PowerShellCoreExecutionPolicy.adm과 PowerShellCoreExecutionPolicy.admx 파일은 Group Policy Editor의 Computer Configuration와 User Configuration 노드에 다음 경로로 Turn on Script Execution 정책을 추가해요.
Administrative Templates\Windows Components\Windows PowerShell
Computer Configuration 노드에 설정된 정책은 User Configuration 노드에 설정된 정책보다 우선해요.
더 자세한 내용은 about_Group_Policy_Settings 문서를 참고해 주세요.
서명된 스크립트와 서명되지 않은 스크립트 관리하기
Windows에서 Internet Explorer나 Microsoft Edge 같은 프로그램은 다운로드한 파일에 대체 데이터 스트림(alternate data stream)을 추가해요. 이렇게 하면 그 파일이 "인터넷에서 온 것"으로 표시되죠. 실행 정책이 RemoteSigned라면, PowerShell은 인터넷(이메일, 인스턴트 메시징 프로그램 포함)에서 다운로드한 서명 없는 스크립트를 실행하지 않아요.
실행 정책을 바꾸지 않고도, 스크립트에 서명을 하거나 서명 없는 스크립트를 실행하도록 선택할 수 있어요.
PowerShell 3.0부터는 Get-Item cmdlet의 Stream 매개변수를 사용해서 인터넷에서 다운로드했기 때문에 차단된 파일을 감지할 수 있어요. 그리고 Unblock-File cmdlet을 사용해서 스크립트를 차단 해제하면 PowerShell에서 실행할 수 있게 돼요.
더 자세한 내용은 about_Signing, Get-Item, Unblock-File 문서를 참고해 주세요.
참고 파일을 다운로드하는 다른 방법들은 파일을 Internet Zone에서 온 것으로 표시하지 않을 수 있어요. 예를 들면:
curl.exe Invoke-RestMethod Invoke-WebRequest
Windows Server Core와 Windows Nano Server의 실행 정책
특정 조건에서 PowerShell 6이 Windows Server Core나 Windows Nano Server에서 실행되면, 실행 정책이 다음 오류와 함께 실패할 수 있어요.
AuthorizationManager check failed.
At line:1 char:1
+ C:\scriptpath\scriptname.ps1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
PowerShell은 스크립트 파일의 영역(Zone)을 확인하기 위해 Windows 데스크톱 셸(explorer.exe)의 API를 사용해요. 그런데 Windows Server Core와 Windows Nano Server에는 Windows 셸이 없어요.
Windows 데스크톱 셸을 쓸 수 없거나 응답하지 않는 Windows 시스템이라면 어디서든 이 오류가 발생할 수 있어요. 예를 들어, 로그온 중에 Windows 데스크톱이 준비되기 전에 PowerShell 로그온 스크립트가 실행을 시작하면 실패할 수 있어요.
ByPass나 AllSigned 실행 정책을 사용하면 Zone 확인이 필요 없어서 이 문제를 피할 수 있어요.