解決 PowerShell 系統上已停用指令碼執行

前言

在 Node.Js 執行 cli 指令時(以ng update為例),遇到

ng : 因為這個系統上已停用指令碼執行,所以無法載入 D:\node\nodejs\ng.ps1 檔案。如需詳細資訊,請參閱 about_Execution_Policies,網址為 http://go.microsoft.com/fwlink/?LinkID=135170。
位於 線路:1 字元:1

  • ng update @angular/core @angular/cli @angular/material @angular/cdk …
  • ~~
    • CategoryInfo : SecurityError: (:) [], PSSecurityException
    • FullyQualifiedErrorId : UnauthorizedAccess

略爬文,很明確是 Windows GPO 造成的
有可能是系統管理員派送 GPO 權限全域鎖住
但通常不會鎖到這麼細,在急著找管理員開權限之前,可以先試試本機權限能否順利解決
以我的情境,並非系統管理員派送的「標準化 GPO」鎖住,自行輸入指令後就打開限制了

解決方法

  1. 打開 PowerShell
  2. 輸入Get-ExecutionPolicy,可以看到目前權限清單
  3. 輸入Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
  4. 再試試看指令可否運作!

由於 AD 權限鎖住,重點在參數-Scope CurrentUser限定範圍
也就是當切換 AD 帳號,可能會需要再次執行此指令

腳本過程

故意拆成三段方便閱讀處理過程

PS C:\Users\ryan> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       Undefined
PS C:\Users\ryan> Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

執行原則變更
執行原則有助於防範您不信任的指令碼。如果變更執行原則,可能會使您接觸到 about_Execution_Policies 說明主題 (網址為
http://go.microsoft.com/fwlink/?LinkID=135170) 中所述的安全性風險。您要變更執行原則嗎?
[Y](Y)  [A] 全部皆是(A)  [N](N)  [L] 全部皆否(L)  [S] 暫停(S)  [?] 說明 (預設值為 "N"): y
PS C:\Users\ryan> Get-ExecutionPolicy -List

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

補充說明

一般 Windows 10 預設原則為 Restricted,造成無法執行 Powershell 的腳本

PowerShell 執行原則共七個:

  1. AllSigned: 可執行已簽署的腳本
  2. Bypass: 不會封鎖任何項目,且不會顯示警告或提示
  3. Default: 設定預設執行原則。(用戶端會是 Restricted,伺服器會是RemoteSigned)
  4. RemoteSigned: 本機撰寫的腳本不必簽署可執行,遠端下載的腳本需簽署才可執行
  5. Restricted: 不允許執行腳本
  6. Undefined: 無定義。若是未定義,則當作 Restricted
  7. Unrestricted: 所有腳本都可以執行

後記

我遇到的狀況比較特別,列出權限清單皆是Undefined,最後則當作 Restricted
但也不確定之前是什麼。畢竟我之前是可正常執行指令

網路上常見解法都會說要透管理員權限啟動 PowerShell
對於 AD 限制嚴謹的企業來說,看到這步可能就直接放棄了…
所幸有-Scope參數避開了管理員權限的麻煩!

參考資料

微軟官方文件 / Set-ExecutionPolicy
PowerShell 「系統上已停用指令碼執行」解決方法
it邦幫忙 serve : 因為這個系統上已停用指令碼執行,所以無法載入 C:\Users\jbudu\AppData\Roaming\npm\serve.ps1 檔案

上述it邦幫忙連結可看到不僅是 Angular 的 CLI 指令,React.Js 也有可能遇到這狀況!
就我自身經驗,ncu(npm-check-update) 也需要執行 ps1 腳本,其實影響範圍滿大的!