PowerShell 실행 정책 관리를 위한 Set-ExecutionPolicy

이전에 PowerShell 스크립트를 다운로드하여 실행한 후 아래의 악명 높은 오류 메시지를 마주한 적이 있나요? 그렇다면, Set-ExecutionPolicy cmdlet과 이 튜토리얼이 필요합니다!

PowerShell Script Execution Disabled Error

이 포스트에서는 PowerShell 실행 정책과 Set-ExecutionPolicy cmdlet을 사용하여 정책을 관리하는 방법에 대해 배우게 될 것입니다. 이 포스트를 마칠 때쯤에는 스크립트를 실행하는 방법뿐만 아니라 실행 정책을 사용하는 방법도 알게 될 것입니다!

이 튜토리얼은 Windows PowerShell을 기준으로 작성되었으며, 모든 데모는 Windows PowerShell에서 수행되었습니다. 실행 정책은 Windows PowerShell에만 해당하는 것이 아니며, PowerShell 6+에서도 매우 유사하게 동작합니다. 그러나 PowerShell 6+를 사용하는 경우 동작에 약간의 차이가 있을 수 있습니다.

실행 정책이란 무엇인가요?

앞서 설명한 오류에 부딪혀 본 적이 있다면, 실행 정책에 직면한 것입니다. PowerShell 실행 정책은 시스템이 악성 스크립트를 실행하는 것으로부터 보호하기 위한 보안 메커니즘입니다. 실행 정책은 콘솔로서의 PowerShell 코드 실행을 방지하지 않지만, 스크립트 실행을 방지합니다.

Microsoft는 실행 정책이 기술적으로 “보안” 조치는 아니라고 말하지만, 개념적으로는 열고 닫을 수 있는 게이트라고 설명합니다. 결국, 정의된 실행 정책을 우회할 수 있으며, 이후에 배우게 될 것입니다.

실행 정책은 신뢰에 기반을 둡니다. 스크립트를 신뢰한다면 악의적이지 않을 확률이 높습니다. 실행 정책은 일반적으로 모든 스크립트의 실행을 방지하지 않습니다. 그들의 주요 목적(특히 더 엄격하게 구성된 경우)은 실행 중인 스크립트가 인증서로 암호화되어 서명되었음을 확신하는 것입니다.

실행 정책 범위

알게 된 대로, 실행 정책은 스크립트 실행을 제한하지만 PowerShell은 많은 다양한 문맥에서 스크립트를 실행할 수 있습니다. PowerShell은 사용자의 로그인한 문맥이나 전역 컴퓨터 문맥, SYSTEM으로 실행되는 예약된 작업 또는 하나의 열린 PowerShell 콘솔의 범위 내에서 스크립트를 실행합니다.

모든 이러한 문맥을 수용하기 위해 PowerShell에는 실행 정책을 정의할 수 있는 다섯 가지 다른 문맥 또는 범위가 있습니다.

  • MachinePolicy – 이 범위는 단일 컴퓨터로 제한됩니다. 해당 컴퓨터에 로그인하는 모든 사용자에 영향을 미치며, Active Directory 그룹 정책 개체가 설정합니다. 정의된 경우 다른 모든 범위보다 우선합니다.
  • LocalMachine. 모든 컴퓨터 사용자에게 영향을 미치는 기본 범위로, HKEY_LOCAL_MACHINE 레지스트리 하위 키에 저장됩니다. Set-ExecutionPolicy를 사용하여 실행 정책을 설정할 때 이 범위가 기본값입니다.

LocalMachine의 실행 정책은 레지스트리 키 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell에 저장됩니다.

  • UserPolicyUserPolicy 범위는 컴퓨터의 단일 사용자에만 영향을 미치며, Active Directory 그룹 정책 개체가 설정합니다. Set-ExecutionPolicy로 이 정책을 변경할 수 없습니다.
  • CurrentUser. CurrentUser 정책 범위는 현재 사용자에게만 실행 정책을 설정하며 HKEY_CURRENT_USER 레지스트리 하이브에 저장됩니다. Set-ExecutionPolicy로 이 정책을 변경할 수 없습니다.

CurrentUser의 실행 정책은 레지스트리 키 HKEY_CURRENT_USER\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell에 저장됩니다.

  • Process – 이 범위는 단일 사용자의 단일 PowerShell 세션에 대한 실행 정책을 정의합니다. Process 실행 정책 범위는 정의할 수 있는 가장 세부적인 실행 정책입니다. 다른 실행 정책과 달리 이 정책은 레지스트리가 아닌 PSExecutionPolicyPreference이라는 환경 변수에 저장됩니다.

실행 정책 유형

실행 정책은 다양한 “보안 수준”을 가지고 있습니다. 이러한 수준은 실행 정책의 엄격성을 규정합니다. 예를 들어, 실행 정책은 아무런 영향을 미치지 않는 비활성화된 상태일 수도 있고, 반면에 스크립트 실행을 완전히 비활성화할 수도 있습니다.

가장 제한적인 보안 수준부터 가장 제한적인 수준까지 실행 정책의 보안 수준을 설명해 보겠습니다.

Unrestricted

가장 제한적이지 않은 정책은 아무런 영향을 미치지 않는 Unrestricted입니다. Unrestricted 실행 정책은 사실상 비활성화됩니다. 실행 정책이 Unrestricted인 경우 사용자는 신뢰 여부에 관계없이 모든 스크립트를 실행할 수 있습니다.

Bypass

Unrestricted 유형과 유사하게, 실행 정책을 Bypass로 설정하면 아무런 차단도 발생하지 않습니다.

BypassUnrestricted는 유사한 효과를 가지지만, Bypass 실행 정책 유형은 기술적으로는 유형이 아닙니다. 이는 정의된 실행 정책을 완전히 건너뛰게 됩니다.

Undefined

일반적으로 사용되지는 않지만, 실행 정책을 Undefined로 설정하여 실행 정책을 제거할 수 있습니다. 실행 정책을 Undefined로 설정하면 PowerShell은 할당된 범위에서 모든 실행 정책을 완전히 제거합니다.

Windows 이외의 컴퓨터에서는 실행 정책이 항상 Unrestricted로 설정되어 있으며 변경할 수 없습니다.

모든 범위가 Undefined로 설정되면 PowerShell은 사실상 모든 범위를 Restricted로 처리합니다.

RemoteSigned

앞서 읽었듯이, 실행 정책은 스크립트의 디지털 서명을 통해 얻은 신뢰에 관한 것입니다. PowerShell은 그 스크립트가 어디에서 만들어졌는지도 고려합니다. 그것은 당신의 로컬 컴퓨터에서 만들어진 것인가, 아니면 인터넷의 무작위한 사람에게서 온 것인가요?

당신의 로컬 컴퓨터 이외의 어딘가에서 만들어진 스크립트는 본질적으로 신뢰되어서는 안 됩니다. 이것이 PowerShell이 RemoteSigned 실행 정책을 제공하는 이유입니다. RemoteSigned 실행 정책은 당신의 로컬 컴퓨터 이외의 어딘가에서 작성된 모든 스크립트가 암호화 서명되도록 강제합니다.

인터넷에서 다운로드한 파일에 대해 이 실행 정책을 일정 정도로 무시할 수 있습니다 Unblock-File cmdlet을 사용하면 됩니다. 이 동작에 대한 자세한 정보는 ‘RemoteSigned Policy가 어떻게 작동하는가’ 섹션에서 나중에 얻을 수 있습니다.

Windows 서버의 경우, RemoteSigned가 기본 정책으로 지정됩니다.

AllSigned

모든 PowerShell 스크립트가 암호화 서명되도록 하려면 실행 정책을 AllSigned로 설정하십시오. RemoteSigned와 마찬가지로, 이 실행 정책은 서명 요구사항을 한 단계 더 나아가 모든 스크립트가 실행 전에 서명되도록 강제합니다.

AllSigned 실행 정책을 설정해도 나중에 배우게 될 것처럼 실행 정책을 우회하여 정책을 무시할 수 있습니다.

제한된

가장 제한적인 실행 정책은 Restricted입니다. 실행 정책이 Restricted으로 설정되면 신뢰할 수 있는지 여부에 상관없이 스크립트가 실행되지 않습니다. 이 정책은 실질적으로 스크립트 실행을 완전히 비활성화합니다.

또한, 다른 덜 제한적인 유형과 달리 Restricted 유형은 PowerShell 서식 및 구성 파일 (PS1XML), 모듈 스크립트 파일 (PSM1) 및 PowerShell 프로파일이 실행되지 않도록 보장합니다.

기본적으로 모든 Windows 클라이언트는 Restricted 실행 정책으로 설정되어 있습니다.

기술적으로 Microsoft는 Default라는 일곱 번째 실행 정책을 정의하지만, 이 유형은 사실상 RemoteSigned (Windows Server)와 Restricted (Windows Clients)을 위한 또 다른 라벨입니다.

RemoteSigned 정책의 작동 방식

RemoteSigned 실행 정책이 작동하는 특정 시나리오 중 하나는 다른 위치에서 생성된 스크립트가 실행되지 않도록 하는 것입니다.

그러나 PowerShell은 어떻게 스크립트가 다른 곳에서 생성되었는지를 알 수 있을까요? 데이터 스트림입니다.

NTFS 데이터 스트림 이해 및 조회

NTFS 파일 시스템에서 파일을 생성하면 NTFS는 파일에 대해 대체 데이터 스트림 (ADS) 속성을 적용합니다. ADS에는 $Datazone.Identifier라는 두 가지 파일 속성이 있습니다. PowerShell은 zone.Identifier 속성을 사용하여 PowerShell 스크립트 파일이 다른 위치에서 생성되었는지 여부를 식별합니다.

다른 속성들과는 달리 압축됨이나 읽기 전용 같은 속성들은 파일 탐색기에서 ADS 속성은 숨겨져 있습니다. 그러나 PowerShell을 사용하면 이러한 데이터 스트림을 검사할 수 있습니다.

아래와 같이 스크립트 경로와 Stream 매개변수를 사용하여 Get-Item cmdlet를 실행합니다. 이 예에서는 Hello World.ps1이 로컬 컴퓨터에 작성되었습니다. Stream 속성에 할당된 유일한 속성은 $DATA입니다. ADS 속성이 없습니다.

Get-Item '.\Hello World.ps1' -Stream *
ADS Stream output for local file

이제 인터넷에서 다운로드한 스크립트에서 동일한 명령을 실행합니다. 이제 Get-ItemZone.IdentifierStream을 반환하는 완전히 다른 객체를 반환합니다.

ADS Stream output for PowerShell file downloaded from internet

파일에 ADS가 있는지를 알게 되면 Get-Content 명령을 사용하여 zone을 발견할 수 있습니다. 영역은 파일의 출처를 정의합니다.

Get-Content .\Get-CertDetails.ps1 -Stream zone.identifier

Get-Content는 파일의 출처를 나타내는 ZoneId 값을 반환합니다.

Zone ID Value

가능한 영역 값은 다음과 같습니다:

Zone ID Zone
------- ---------------------
0       My Computer
1       Local Intranet Zone
2       Trusted sites Zone
3       Internet Zone
4       Restricted Sites Zone

실행 정책 우선순위

위에서 다룬 것처럼 동시에 많은 다른 실행 정책이 존재합니다. 이러한 모든 실행 정책은 결합되어 현재 세션의 설정을 지정합니다. 여러 실행 정책이 적용되어 있는 경우 우선순위를 가집니다.

정책 우선순위는 PowerShell이 다른 범위에서 설정된 다른 정책을 적용하는 순서입니다. 일부 실행 정책은 다른 실행 정책보다 높은 우선순위를 갖습니다.

실행할 때 Get-ExecutionPolicy -List를 실행하면 현재 적용 중인 모든 실행 정책이 우선순위가 낮은 것부터 높은 것까지 순서대로 표시됩니다. 예를 들어, MachinePolicy가 우선순위가 낮기 때문에 LocalMachineCurrentUser 정책이 이를 덮어씁니다.

Get-ExecutionPolicy cmdlet output

실행 정책 작업

실행 정책의 백그라운드를 충분히 이해했다면, 이제는 그것들을 어떻게 사용할지 살펴봅시다! PowerShell의 실행 정책을 사용하려면 Get-ExecutionPolicy로 현재 정의된 정책을 찾고 Set-ExecutionPolicy로 새로운 정책을 설정할 수 있습니다.

현재 할당된 정책 가져오기

실행 정책을 변경하기 전에 작업할 내용을 파악해야 합니다. 이를 위해 Get-ExecutionPolicy 명령을 사용합니다. 이 명령은 컴퓨터에 현재 할당된 모든 정책을 나열합니다.

Get-ExecutionPolicy 명령을 매개변수 없이 PowerShell 콘솔에서 직접 실행하면 현재 PowerShell 세션에 대해 설정된 실행 정책이 표시됩니다.

Get-ExecutionPolicy cmdlet output

범위에 설정된 실행 정책을 보려면 결과를 볼 범위 이름을 지정하여 Scope 매개변수를 지정하십시오.

Get-ExecutionPolicy -Scope Process
Get-ExecutionPolicy -Scope LocalMachine
Get-ExecutionPolicy cmdlet with scope parameter output

모든 범위와 실행 정책을 보려면 아래와 같이 List 매개변수를 사용하십시오.

Get-ExecutionPolicy -list
Get-ExecutionPolicy cmdlet displaying all scopes

실행 정책 변경

현재 할당된 실행 정책을 알게 되면, 그것들을 변경할 수도 있습니다. 단일 컴퓨터의 정책을 변경하려면, Set-ExecutionPolicy 명령어를 사용할 수 있습니다. 그러나, 조직 내에서 정책을 대량으로 변경하려면, Active Directory 도메인에 속해 있다면 항상 그룹 정책을 사용할 수 있습니다.

Set-ExecutionPolicy를 사용하는 방법

먼저 관리자 권한으로 PowerShell을 엽니다.

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

그런 다음, 실행 정책의 이름을 제공하는 하나의 매개 변수 (ExecutionPolicy)와 함께 Set-ExecutionPolicy 명령을 실행합니다.PowerShell은 실행 정책을 변경할 것인지 물어볼 것입니다. 변경하려면 Y 또는 A를 입력하고 Enter를 누르세요.

Change Execution Policy

일부 PowerShell 명령은 작동하기 위해 여러 작업을 실행해야 할 수도 있습니다. 위의 예제에서 Y를 입력하면 PowerShell은 각 단계에 대해 계속 진행 여부를 묻게 될 수도 있습니다. A를 누르면 모든 후속 단계를 계속합니다.

프롬프트 없이 Set-ExecutionPolicy 실행하기

기본적으로 Set-ExecutionPolicy를 실행할 때, 실행 정책을 변경하고 싶은지 묻습니다. Force 매개변수를 명령에 추가하여 이 프롬프트를 건너뛸 수 있습니다. Force 매개변수를 사용하면 모든 확인 프롬프트가 억제됩니다.

Set-ExecutionPolicy RemoteSigned -Force
Output of Set-ExecutionPolicy command when Force Parameter is used

레지스트리를 통한 PowerShell 실행 정책 설정

대부분의 실행 정책은 레지스트리에 저장되어 있으므로 (Process 제외), 레지스트리를 통해 직접 정책을 변경할 수도 있습니다.

레지스트리를 통해 실행 정책을 변경하려면:

  1. Windows 레지스트리 편집기 (regedit) 또는 원하는 레지스트리 편집 도구를 엽니다.

2. 변경하려는 실행 정책 범위의 레지스트리 키로 이동합니다.

LocalMachineHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

CurrentUserHKEY_CURRENT_USER\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

3. 레지스트리 키를 마우스 오른쪽 버튼으로 클릭하고 ExecutionPolicy이라는 새 문자열 값을 만듭니다.

4. 새로 만든 ExecutionPolicy 문자열 값을 더블 클릭하고 원하는 실행 정책 이름 (Restricted, RemoteSigned, AllSigned, Unrestricted, 또는 Undefined)을 입력합니다.

5. 동일한 키에 Path라는 또 다른 문자열 값을 생성하십시오. Path 문자열 값은 PowerShell 엔진의 경로를 나타냅니다. Path 값은 Windows PowerShell 엔진을 가리키는 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe로 설정되어야 합니다.

Registry path for ExecutionPolicy in registry for current user

CurrentUser 실행 정책은 LocalMachine 정책을 재정의합니다. 레지스트리에 CurrentUser 정책이 설정되어 있고 Set-ExecutionPolicy를 사용하여 실행 정책을 변경하려고 하면 기본적으로 정책이 LocalMachine 범위에 설정되므로 PowerShell에서 아래와 같은 오류가 반환됩니다.

Execution Policy Permission Denied

그룹 정책을 통해 PowerShell 실행 정책 설정

Active Directory 기반의 조직에서는 모든 Windows 기기에 돌아다니며 Set-ExecutionPolicy cmdlet을 실행할 필요가 없습니다. 대신 그룹 정책을 사용하여 일괄적으로 정책을 관리할 수 있습니다.

그룹 정책을 통해 실행 정책을 관리하려면:

그룹 정책 개체를 생성하십시오.

  1. 도메인 컨트롤러나 도메인에 가입된 워크스테이션에서 그룹 정책 관리 응용 프로그램을 엽니다.
Group Policy Management Console

2. 도메인 —> <활성 디렉터리 포레스트> —> 그룹 정책 개체를 확장합니다.

Select Group Policy Objects node

3. 그룹 정책 개체를 마우스 오른쪽 단추로 클릭하고 새로 만들기를 클릭합니다.

4. GPO에 이름을 지정하십시오. 이 튜토리얼에서 GPO는 PowerShell Execution Policy로 지정됩니다.

Create new Group Policy Object

5. 새로 만든 GPO를 마우스 오른쪽 버튼으로 클릭하고 편집을 클릭하십시오.

6. 컴퓨터 구성\Policies\관리 템플릿\Windows 구성 요소\Windows PowerShell로 이동하십시오.

Navigate to the setting in Group Policy Object

7. 오른쪽 창에 설정을 열고 스크립트 실행 켜기 설정을 엽니다.

Turn on Script Execution Policy

8. 스크립트 실행 켜기 상자에서 활성화 옵션을 선택하십시오. 이제 아래에 표시된 옵션 중 하나를 선택할 수 있습니다:

9. 이제 실행 정책을 원하는 정책으로 변경하십시오.

  • 서명된 스크립트만 허용 – 신뢰할 수 있는 발행자가 서명한 스크립트만 실행을 허용합니다.
  • 로컬 스크립트 및 원격 서명된 스크립트 허용 – 로컬 스크립트는 실행되지만 인터넷에서 다운로드한 스크립트는 신뢰할 수 있는 발행자에 의해 서명되어야 합니다.
  • 모든 스크립트 허용 – 모든 스크립트를 실행할 수 있습니다.
List Execution Policy

그룹 정책 개체 할당

만든 GPO가 있으면 대상 컴퓨터에 할당할 시간입니다. 이를 위해 GPO를 Active Directory 조직 단위 (OU)에 할당해야 합니다.

새로운 GPO를 생성하는 대신 기존 GPO를 편집했다면 해당 GPO는 이미 OU에 할당되어 있을 것입니다.

  1. 그룹 정책 관리로 이동하여 도메인 -> <귀하의 Active Directory 포레스트> -> <귀하의 OU>로 이동하세요.

2. OU를 마우스 오른쪽 단추로 클릭하고 기존 GPO 연결…을 선택합니다.

Link an Existing GPO…

3. 방금 생성한 GPO(PowerShell 실행 정책)을 선택하고 확인을 클릭합니다.

Select the GPO

이제 아래에 표시된 대로 OU에 할당된 GPO를 확인할 수 있어야 합니다.

Link the Group Policy Object

이 시점에서 정의된 그룹 정책 새로 고침 간격을 기다리거나 대상 컴퓨터에서 gpupdate 명령을 실행하여 새로 고침을 강제로 할 수 있습니다.

지역 정책 변경 잠금

실행 정책을 변경하는 GPO가 유효한 경우 로컬 사용자는 더 이상 로컬 PowerShell 콘솔을 통해 정책을 변경할 수 없습니다. 시도하면 아래에 표시된대로 오류가 발생합니다.

Error on trying to changing execution policy manually

실행 정책 완전히 우회

이전에 언급했듯이 실행 정책은 반드시 보안 조치로 고려되지 않습니다. 왜냐하면 몇 가지 다른 방법으로 완전히 우회할 수 있기 때문입니다.

-ExecutionPolicy Bypass 매개변수 사용

차단되지 않는 Bypass 정책은 일반적으로 PowerShell 콘솔이 아닌 관리자 권한으로 실행되는 powershell.exe 엔진에 전달됩니다.

예를 들어, 실행 정책을 완전히 무시하고 Hello World.ps1이라는 스크립트를 실행하려면 아래와 같이 powershell.exe를 호출하고 Bypass 매개변수를 사용하여 파일 경로를 제공하면 됩니다.

powershell.exe -executionpolicy bypass -file '.\Hello World.ps1'
ByPass Execution Policy using bypass execution policy

스크립트 읽기 및 코드 직접 실행

스크립트 내용을 먼저 읽고 해당 내용을 직접 PowerShell 엔진에 전달하여 실행 정책을 우회할 수도 있습니다. 이렇게 하면 각 명령이 개별적으로 실행되며 전체 스크립트가 한 번에 실행되지 않습니다.

아래에서 보듯이 실행 정책이 Restricted로 설정되어 있지만 스크립트를 읽고 powershell.exe에 전달하면 여전히 작동합니다.

이 방법은 PowerShell ISE 또는 Visual Studio Code와 같은 PowerShell 편집기에서 스크립트를 열고 특정 행을 선택한 다음 F8을 누르는 것과 유사합니다.

Get-Content '.\Hello World.ps1' | powershell.exe -noprofile
Alternative way to Bypass Execution Policy

결론

이제 PowerShell 실행 정책에 관한 모든 정보를 알게 되었을 것입니다. 기술적으로 보안 조치는 아니지만 조직 정책에 따라 조직에서 관리해야 합니다.

Source:
https://adamtheautomator.com/set-executionpolicy/