Sửa lỗi PowerShell: Running Scripts Is Disabled on This System

beginner🪟 Windows2026-03-17| Windows 10/11, Windows Server 2016/2019/2022, PowerShell 5.1 / PowerShell 7+

Error Message

cannot be loaded because running scripts is disabled on this system
#windows#powershell#execution-policy#bảo mật

Tình huống xảy ra

Đã muộn. Bạn đang cố chạy script triển khai, kích hoạt môi trường ảo Python, hoặc chạy script setup mà đồng nghiệp vừa gửi. Bạn gõ lệnh, nhấn Enter, và thay vì tiến trình chạy — bạn nhận được thông báo này:

File C:\scripts\deploy.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.

Script không chạy. Không có gì được triển khai. Máy của đồng nghiệp chạy tốt, nhưng máy bạn thì không.

Execution policy của PowerShell đang chặn bạn — đây là tính năng bảo mật kiểm soát script nào được phép chạy. Windows khóa chế độ này theo mặc định. Chỉ năm phút nữa, bạn sẽ xử lý xong vấn đề này.

Hiểu điều gì đang xảy ra (30 giây)

PowerShell có bốn cấp độ execution policy quan trọng cần biết:

  • Restricted — Không có script nào được chạy. Mặc định trên các phiên bản Windows dành cho người dùng thông thường (Windows 10/11).
  • AllSigned — Chỉ chạy các script đã được ký bởi nhà xuất bản đáng tin cậy.
  • RemoteSigned — Script cục bộ chạy tự do; script tải về cần có chữ ký.
  • Unrestricted — Tất cả script đều chạy, nhắc xác nhận với script tải về.

Chín trong mười trường hợp, lỗi này có nghĩa là policy của bạn đang ở trạng thái Restricted.

Kiểm tra policy hiện tại trước

Mở PowerShell (không phải CMD) và chạy:

Get-ExecutionPolicy -List

Bạn sẽ thấy kết quả như sau:

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine    Restricted

Scope cụ thể nhất sẽ được ưu tiên áp dụng. LocalMachine hiển thị Restricted mà không có gì khác được đặt? Đó chính là nguyên nhân.

Lưu ý: nếu MachinePolicy hoặc UserPolicy hiển thị một giá trị nào đó, đó là Group Policy đang can thiệp — và bạn không thể ghi đè nếu không có quyền admin hoặc thay đổi GPO. Chuyển sang Giải pháp 3 nếu đó là trường hợp của bạn.

Giải pháp 1: Đặt Execution Policy cho người dùng hiện tại (Khuyến nghị)

Bắt đầu từ đây. Cách này chỉ ảnh hưởng đến tài khoản của bạn, không cần UAC, và hoạt động trên hầu hết máy tính mà không cần quyền admin.

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

RemoteSigned là lựa chọn cân bằng hợp lý: script của bạn chạy tự do, script tải về cần chữ ký. Yêu cầu chữ ký đó chính là thứ ngăn chặn malware thực sự — vì vậy bạn không tạo ra lỗ hổng bảo mật khi dùng cách này.

Giải pháp 2: Đặt cho toàn máy (Yêu cầu quyền Admin)

Đang cấu hình máy trạm lập trình hoặc CI/CD runner mà tất cả người dùng đều cần chạy script? Mở PowerShell với quyền Administrator, rồi chạy:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine

PowerShell sẽ yêu cầu xác nhận. Gõ Y và nhấn Enter. Tất cả người dùng trên máy giờ đây có thể chạy script.

Giải pháp 3: Bypass cho một phiên làm việc (Không cần Admin, không thay đổi vĩnh viễn)

Cần chạy một script ngay lập tức mà không muốn thay đổi bất kỳ thứ gì lâu dài? Dùng scope Process:

Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process

Cách này chỉ áp dụng cho cửa sổ PowerShell hiện tại. Đóng cửa sổ lại, giới hạn sẽ trở lại như cũ. Hoạt động ngay cả trên máy bị Group Policy khóa — GPO không kiểm soát policy theo từng process.

Giải pháp 4: Bypass trực tiếp cho một script duy nhất

Một lựa chọn khác: truyền execution policy trực tiếp khi khởi chạy PowerShell:

powershell.exe -ExecutionPolicy Bypass -File .\your-script.ps1

Từ PowerShell 7:

pwsh -ExecutionPolicy Bypass -File .\your-script.ps1

Lý tưởng cho batch file, pipeline CI/CD, hoặc Windows Task Scheduler khi bạn không thể kiểm soát policy của hệ thống. Các pipeline Jenkins và GitHub Actions thường dùng đúng cách này.

Giải pháp 5: Unblock một file tải về cụ thể

Đây là điều nhiều người bỏ qua: đôi khi execution policy không phải vấn đề thực sự. Windows âm thầm đánh dấu các file tải từ internet là có thể không an toàn — và chỉ cái dấu đó thôi cũng đủ để chặn chúng, bất kể cài đặt policy của bạn là gì.

Kiểm tra xem script có mang dấu này không:

Get-Item .\your-script.ps1 | Select-Object -ExpandProperty Attributes

Nếu file có alternate data stream Zone.Identifier, hãy xóa nó đi:

Unblock-File -Path .\your-script.ps1

Vậy là xong. Không cần thay đổi policy. Windows ngừng coi file là không đáng tin, và PowerShell sẽ chạy nó mà không phàn nàn gì.

Xác nhận lại sau khi sửa

Sau bất kỳ bước nào ở trên, hãy xác nhận policy trông đúng chưa:

Get-ExecutionPolicy -List

Sau đó chạy lại script. Lúc này sẽ hoạt động bình thường.

Với cách dùng Unblock-File, kiểm tra lại xem stream đã biến mất chưa:

Get-Item .\your-script.ps1 -Stream *

Zone.Identifier sẽ không còn xuất hiện trong kết quả nữa.

Khi mọi cách đều không hiệu quả: Group Policy đang ghi đè

Nếu MachinePolicy hoặc UserPolicy hiển thị giá trị bị hạn chế, Group Policy của tổ chức đang cưỡng chế áp dụng. Set-ExecutionPolicy có vẻ thành công — nhưng sẽ bị hoàn nguyên ngay khi bạn kiểm tra lại.

Các lựa chọn của bạn:

  • Dùng -Scope Process hoặc cờ -ExecutionPolicy Bypass trực tiếp. Group Policy không chặn được cả hai cách này.
  • Liên hệ sysadmin để xin ngoại lệ GPO cho máy lập trình viên.
  • Dùng Invoke-Expression hoặc iex để pipe nội dung script — nhưng chỉ với code bạn đã đọc và thực sự tin tưởng.

Bài học rút ra

  • Tránh dùng Unrestricted trên bất kỳ máy nào chạy code không đáng tin. RemoteSigned là mặc định hợp lý cho lập trình viên.
  • Trên CI/CD runner dùng chung, đặt -ExecutionPolicy Bypass trực tiếp trong lệnh pipeline. Đừng thay đổi policy hệ thống vĩnh viễn.
  • Gửi script cho đồng nghiệp? Hãy ký bằng chứng chỉ tự ký và đưa vào repo. Giải quyết vấn đề này triệt để trên các máy dùng AllSigned.
  • Unblock-File là công cụ bị bỏ qua một cách đáng tiếc. Không ít lỗi "execution policy" từ script tải về thực ra là vấn đề zone identifier đang ẩn náu bên trong.

Related Error Notes