文章目錄

PowerShell 的腳本是副檔名為 .ps1 的文字檔,很多工具的安裝與設定都靠它執行。在 Windows PowerShell 執行腳本時出現「因為這個系統上已停用指令碼執行」,是因為 Windows 預設的執行原則(Execution Policy)是 Restricted,只允許輸入單行指令,不執行任何腳本檔。
我們只要把目前使用者的執行原則改成 RemoteSigned,自己寫的腳本就能執行,而且不需要系統管理員權限。從網路下載又沒有簽章的腳本仍會先被擋下,確認內容後再解除封鎖即可。
測試環境是 Windows 11(26H2)內建的 Windows PowerShell 5.1,另外用 PowerShell 7.6 對照。
錯誤訊息與原因
在 Windows PowerShell 執行 .\hello.ps1,會看到這樣的錯誤,英文介面則顯示 running scripts is disabled on this system:

執行原則可以分別設定在幾個範圍,Get-ExecutionPolicy -List 會列出每個範圍目前的設定。全部都是 Undefined 時,依 Microsoft 的說明,Windows 10、11 這類非 Server 版的 Windows 實際套用的就是 Restricted:

Windows 內建的 Windows PowerShell 5.1 與另外安裝的 PowerShell 7 各自保存執行原則。PowerShell 7 在 Windows 上的預設是 RemoteSigned,我的電腦也是如此,所以同一個腳本在 PowerShell 7 能執行,在 Windows PowerShell 卻被擋下,要在出現錯誤的那一個 PowerShell 裡修改。
把目前使用者改成 RemoteSigned
在 Windows PowerShell 執行下面的指令,把目前使用者(CurrentUser)的執行原則改成 RemoteSigned。這個範圍只影響自己的帳號,所以不用以系統管理員身分開啟 PowerShell,改完也不需要重開視窗:
1Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
RemoteSigned 只擋從網路下載又沒有簽章的腳本。瀏覽器、電子郵件與通訊軟體下載的檔案會帶有「來自網際網路」的標記,PowerShell 就是依這個標記判斷,自己在電腦上建立的腳本沒有這個標記。
改好後再執行一次 .\hello.ps1,就會正常印出結果。帶有網路下載標記的 setup.ps1 則仍然被擋下,錯誤訊息從「已停用指令碼執行」變成「未經數位簽署」:

執行下載的腳本
從網路下載的腳本,先用記事本或 VS Code 打開看過內容,確定來源可以信任,再用 Unblock-File 拿掉下載標記:
1Unblock-File .\setup.ps1
拿掉標記後再執行 .\setup.ps1,就會正常印出結果:

只執行一次的寫法
不想改設定、只想執行一次時,可以在啟動 PowerShell 時用 -ExecutionPolicy Bypass 指定這一次的執行原則。這個設定只對這一次啟動的 PowerShell 有效,關掉後就恢復原本的設定。Bypass 不會檢查下載標記,執行前一樣要先看過腳本內容:
1powershell -ExecutionPolicy Bypass -File .\setup.ps1
uv 的安裝指令與 Whetstone 的 Windows 安裝指令都是這種寫法,所以即使執行原則還是 Restricted 也能安裝。
其他執行原則
Set-ExecutionPolicy 常用的三種執行原則,差別在於哪些腳本可以執行:
| 執行原則 | 自己寫的腳本 | 從網路下載、沒有簽章的腳本 |
|---|---|---|
| Restricted | 不執行 | 不執行 |
| RemoteSigned | 執行 | 解除封鎖後才執行 |
| Bypass | 執行 | 執行,也不提示 |
還原設定
要改回原本的設定,把 CurrentUser 範圍設回 Undefined。其他範圍也都是 Undefined 時,執行原則就會回到 Restricted:
1Set-ExecutionPolicy -ExecutionPolicy Undefined -Scope CurrentUser
總結
Windows PowerShell 不能執行腳本時,把目前使用者的執行原則改成 RemoteSigned,從網路下載的腳本確認內容後再用 Unblock-File 解除封鎖。實測改成 RemoteSigned 後,自己建立的腳本可以直接執行,帶有下載標記的腳本則要解除封鎖後才能執行。
