โดยค่าเริ่มต้น การตั้งค่าของ Windows ป้องกันไม่ให้สคริปต์ PowerShell รันได้ จากมุมมองด้านความปลอดภัย จำเป็นต้องจำกัดโค้ดที่ไม่น่าเชื่อถือและเป็นอันตรายจากการรันผ่านสคริปต์ PowerShell Execution Policy กำหนดการตั้งค่าสำหรับการรันสคริปต์ PowerShell ในบทความนี้เราจะดูการตั้งค่าที่มีอยู่สำหรับการรันสคริปต์ PS บน Windows วิธีเปลี่ยน Execution Policy และการกำหนดค่านโยบายการรันสคริปต์ PowerShell สำหรับคอมพิวเตอร์ในโดเมนโดยใช้ GPO
การรันสคริปต์ PowerShell ถูกปิดใช้งานบนระบบนี้
เมื่อพยายามรันสคริปต์ PowerShell ใดๆ (ไฟล์ PS1) บน Windows 10 ที่เพิ่งติดตั้ง จะเกิดข้อผิดพลาดดังนี้:
File C:\ps\script.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170. + CategoryInfo : SecurityError: (:) [], PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess
สามารถดูการตั้งค่าปัจจุบันของ PowerShell Script Execution Policy ใน Windows ได้ด้วยคำสั่ง:
Get-ExecutionPolicy
ค่าของ PowerShell Execution Policy ที่มีอยู่
- Restricted – ปิดใช้งานการรันสคริปต์ PowerShell สามารถรันคำสั่งแบบโต้ตอบในคอนโซล PS ได้อย่างเดียว
- AllSigned – อนุญาตเฉพาะสคริปต์ PS ที่ลงนามด้วยลายเซ็นดิจิทัลโดยผู้เผยแพร่ที่เชื่อถือได้ (สามารถลงนามสคริปต์ด้วยใบรับรองเซลฟ์ไซด์และเพิ่มลงใน Trusted Root Certificates) เมื่อรันสคริปต์ที่ไม่น่าเชื่อถือ จะปรากฏคำเตือน:
Do you want to run software from this untrusted publisher? File .ps1 is published by CN=test1 and is not trusted on your system. Only run scripts from trusted publishers.
- RemoteSigned – สามารถรันสคริปต์ PowerShell ท้องถิ่นได้โดยไม่มีข้อจำกัด สามารถรันไฟล์ PS แบบระยะไกลที่มีลายเซ็นดิจิทัล (ไม่สามารถรันไฟล์ PS1 ที่ดาวน์โหลดจากอินเทอร์เน็ตหรือเปิดจากโฟลเดอร์แชร์ผ่าน UNC path)
- Unrestricted – อนุญาตให้รันสคริปต์ PowerShell ทั้งหมด เมื่อพยายามรันสคริปต์ของบุคคลที่สาม อาจได้รับแจ้งให้ยืนยันการเปิด (ดูด้านล่าง)
- Bypass – อนุญาตให้รันไฟล์ PS ใดๆ ได้ (ไม่แสดงคำเตือน) นโยบายนี้มักใช้เพื่อรันสคริปต์ PS แบบอัตโนมัติโดยไม่แสดงการแจ้งเตือน (เช่น เมื่อรันสคริปต์ผ่าน GPO, SCCM, Task Scheduler ฯลฯ) และไม่แนะนำให้ใช้ถาวร
- Default – รีเซ็ตการตั้งค่าการรันสคริปต์ PowerShell กลับเป็นค่าเริ่มต้น บน Windows 10 ค่าเริ่มต้นคือ Restricted และบน Windows Server 2016 คือ RemoteSigned
- Undefined – ไม่ได้ตั้งค่านโยบาย นโยบาย Restricted จะถูกนำไปใช้กับ OS เดสก์ท็อป และ RemoteSigned สำหรับ OS เซิร์ฟเวอร์
วิธีอนุญาตให้ PowerShell รันสคริปต์ด้วย Execution Policy
เพื่อเปลี่ยนค่าปัจจุบันของ PowerShell Script Execution Policy ใช้ cmdlet Set-ExecutionPolicy
ตัวอย่าง ให้อนุญาตรันไฟล์สคริปต์ PS ท้องถิ่น:
Set-ExecutionPolicy RemoteSigned
ยืนยันการเปลี่ยน Execution Policy สำหรับสคริปต์ PS1 โดยกด Y หรือ A
เพื่อไม่ให้แสดงพรอมต์ยืนยัน สามารถใช้พารามิเตอร์ Force:
Set-ExecutionPolicy RemoteSigned –Force
หากตั้งค่า PowerShell Execution Policy เป็น Unrestricted ยังคงเห็นพรอมต์เมื่อพยายามรันสคริปต์ระยะไกลจากโฟลเดอร์แชร์ผ่าน UNC paths หรือไฟล์ที่ดาวน์โหลดจากอินเทอร์เน็ต:
Security warning Run only scripts that you trust. While scripts from the internet can be useful, this script can potentially harm your computer. If you trust this script, use the Unblock-File cmdlet to allow the script to run without this warning message. Do you want to run? [D] Do not run [R] Run once [S] Suspend [?] Help (default is "D")
PowerShell แยกแยะระหว่างสคริปต์ท้องถิ่นและระยะไกลอย่างไร? เพราะตัวระบุ ZoneId ที่เบราว์เซอร์ตั้งค่าใน alternative stream เมื่อดาวน์โหลดไฟล์ (ดูรายละเอียดในบทความ How does Windows know if a file was downloaded from the Internet?) สามารถปลดบล็อกไฟล์ได้โดยติ๊ก Unblock ในคุณสมบัติไฟล์ หรือล้างป้ายกำกับโซนด้วย cmdlet Unblock-File
ขอบเขต (Scope) ของ PowerShell Execution Policy
ต้องแยกแยะขอบเขตที่แตกต่างกันของ PowerShell Execution Policy:
- MachinePolicy – ตั้งค่าผ่าน GPO ใช้กับผู้ใช้ทุกคนของคอมพิวเตอร์
- UserPolicy – ตั้งค่าผ่าน GPO เช่นกัน ใช้กับผู้ใช้คอมพิวเตอร์
- Process – การตั้งค่า Execution Policy ใช้กับเซสชัน PowerShell ปัจจุบันอย่างเดียว (และรีเซ็ตหลังจบกระบวนการ powershell.exe)
- CurrentUser – Execution Policy ใช้กับผู้ใช้ปัจจุบันอย่างเดียว (พารามิเตอร์ของ registry key HKEY_CURRENT_USER)
- LocalMachine – นโยบายสำหรับผู้ใช้ทุกคนของคอมพิวเตอร์ (พารามิเตอร์จาก registry key HKEY_LOCAL_MACHINE)
สามารถตั้งค่าขอบเขตนโยบายได้โดยใช้พารามิเตอร์ Scope ของ cmdlet Set-ExecutionPolicy ตัวอย่าง:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass –Force
ลองตรวจสอบการตั้งค่า ExecutionPolicy ปัจจุบันสำหรับทุกขอบเขต:
Get-ExecutionPolicy -List
Scope ExecutionPolicy ----- --------------- MachinePolicy Undefined UserPolicy Undefined Process Bypass CurrentUser Undefined LocalMachine RemoteSigned
ค่า Execution Policy ที่ตั้งด้วย cmdlet Set-ExecutionPolicy สำหรับขอบเขต CurrentUser และ LocalMachine จะถูกเก็บใน Registry ตัวอย่างรันคำสั่ง:
Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy Restricted –Force
เปิด registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell และตรวจสอบค่า REG_SZ ของพารามิเตอร์ ExecutionPolicy ควรเปลี่ยนเป็น Restricted (ค่าที่อนุญาตคือ Restricted, AllSigned, RemoteSigned, Bypass, Unrestricted และ Undefined)
การตั้งค่าเดียวกันสำหรับขอบเขต CurrentUser อยู่ที่ HKEY_CURRENT_USER\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell
หมายความว่าสามารถปรับใช้การตั้งค่านโยบายการรันสคริปต์ PowerShell ผ่าน Registry โดยใช้ Group Policy Preferences ได้
ตั้งค่า PowerShell Execution Policy ใน Active Directory ด้วย GPO
สามารถกำหนดค่า Execution Policy สำหรับสคริปต์ PowerShell บนเซิร์ฟเวอร์หรือคอมพิวเตอร์ในโดเมน Active Directory ได้โดยใช้ Group Policies
- ในตัวแก้ไข GPO ของโดเมน (
gpmc.msc) สร้าง GPO ใหม่หรือแก้ไข GPO ที่มีอยู่และลิงก์ไปยัง OU ที่มีคอมพิวเตอร์ที่ต้องการนำ PowerShell script Execution Policy ไปใช้ - เปิด Computer Configuration → Policies → Administrative Templates → Windows Components → Windows PowerShell ในตัวแก้ไข GPO และค้นหาพารามิเตอร์ Turn on Script Execution มีนโยบายเดียวกันในส่วน User Configuration แต่ Computer Policy มีความสำคัญสูงกว่า
- นโยบายอาจมี 3 ค่า:
- Allow only signed scripts – เทียบเท่ากับนโยบาย AllSigned
- Allow local scripts and remote signed scripts – เทียบเท่ากับนโยบาย PS RemoteSigned
- Allow all scripts – เทียบเท่ากับนโยบาย Unrestricted
- ตั้งค่านโยบายที่ต้องการ บันทึก GPO และอัปเดตการตั้งค่า Group Policy บนคอมพิวเตอร์
- ตรวจสอบว่าการตั้งค่าการรันใหม่ถูกนำไปใช้กับขอบเขต MachinePolicy แล้ว
หลังจากกำหนดค่า Execution Policy ด้วย GPO แล้ว จะไม่สามารถเปลี่ยนการตั้งค่านโยบายการรันสคริปต์ด้วยตนเองได้ หากพยายามเปลี่ยน Execution Policy บนคอมพิวเตอร์ที่ GPO ถูกนำไปใช้ จะเกิดข้อผิดพลาด:
Set-ExecutionPolicy: Windows PowerShell updated your execution policy successfully, but the setting is overridden by a policy defined at a more specific scope. Due to the override, your shell will retain its current effective execution policy of RemoteSigned. Type "Get-ExecutionPolicy -List" to view your execution policy settings.
สามารถกำหนดค่า Execution Policy บนคอมพิวเตอร์ Standalone ได้เช่นกันโดยใช้ Local GPO editor — gpedit.msc
วิธี Bypass PowerShell Execution Policy บน Windows
มีเทคนิคบางอย่างที่ช่วยได้หากต้องการรันสคริปต์ PowerShell บนคอมพิวเตอร์โดยไม่เปลี่ยนการตั้งค่า Execution Policy ตัวอย่างเช่น ต้องการรันสคริปต์ PS1 เรียบง่ายที่ตรวจสอบว่ารันด้วยสิทธิ์แอดมินหรือไม่
สามารถดึงเนื้อหาสคริปต์ด้วย Get-Content และส่งต่อไปยัง standard input stream ของคอนโซล PS:
Get-Content c:\ps\check_process_elevation.ps1 | PowerShell.exe -noprofile –
หรือรันกระบวนการ powershell.exe ใหม่ด้วยนโยบาย Bypass:
powershell.exe -noprofile -executionpolicy bypass -file c:\ps\check_process_elevation.ps1