PowerShell 「系統上已停用指令碼執行」解決方法

某次,當我嘗試執行某個powershell的腳本時,
出現了「因為這個系統上已停用指令碼執行,所以無法載入 …」的錯誤資訊。
這篇文章記錄關於這個錯誤的說明與解決方法。

備註:
可以在CMD當中執行powershell以開啟powershell執行
或是在搜尋中直接尋找Windows PowerShell啟動它

PS C:\Users\K\Downloads\ICMP> .\Invoke-IcmpDownload.ps1
.\Invoke-IcmpDownload.ps1 : 因為這個系統上已停用指令碼執行,所以無法載入 C:\Users\K\Downloads\ICMP\Invoke-IcmpDownload.
ps1 檔案。如需詳細資訊,請參閱 about_Execution_Policies,網址為 https:/go.microsoft.com/fwlink/?LinkID=135170。
位於 線路:1 字元:1
+ .\Invoke-IcmpDownload.ps1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : SecurityError: (:) [], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

(英文可能是: cannot be loaded because the execution of scripts is disabled on this system)

這個問題的原因是因為執行原則為受到限制的原則,導致我們無法執行該腳本。

簡單的檢查與解決方法

(⚠️⚠️⚠️請注意⚠️⚠️⚠️,建議你清楚知道自己在做甚麼事情,才執行解決方法,因為這個並非是一個「錯誤」,並不是要修復它。而是一種對於系統安全的保護機制,這個解決方法等於是去關閉這種機制,讓你可以執行自己想要執行的腳本;但換個角度想,今天惡意程式與腳本也就可以更容易被執行)

簡單的檢查方法,可以利用Get-ExecutionPolicy指令,來查看目前的執行原則:
(備註:大小寫皆可,Windows中無區分大小寫)

Get-ExecutionPolicy

一般Windows 10預設原則為Restricted,也就是受到限制的意思,所以造成你無法執行Powershell的腳本。

PowerShell 執行原則共有七個:
AllSigned: 可執行已簽署的腳本
Bypass: 不會封鎖任何項目,且不會顯示警告或提示
Default: 設定預設執行原則。(用戶端會是Restricted,伺服器會是RemoteSigned。)
RemoteSigned: 本機撰寫的腳本不必簽署可執行,遠端下載的腳本需簽署才可執行
Restricted: 不允許執行腳本。
Undefined: 無定義
Unrestricted: 所有腳本都可以執行
(雖然你可能會搜尋到網路有些文章說是四個,但我自己看到官方文件是有七個。也許是新舊版本差異,或是那四個比較常見,詳細我也不清楚)
詳細正確的說明請參考官方文件:
About Execution Policies

如果想要快速解決此問題,可以利用 Set-ExecutionPolicy來去改變執行原則,因為只是想要短暫去執行腳本。所以可以將執行原則改成RemoteSigned或Unrestricted之類,實際要設定成甚麼原則可以依照需求去改。

這邊稍微注意,若要執行該設定,必須要「以系統管理員身分執行」才可以,否則會跳出權限不足的警告。

設定完成之後再檢查,就可以發現執行原則確實改變了。也可以正常去執行想要執行的Powershell腳本。因為我的案例中單純是想執行看看腳本,所以測試完之後就會把執行原則給Set回Restricted,確保系統有一定的安全保護機制。如果是有長期上的業務或是便利需求,可以選擇最適合的執行原則來設定。

Set-ExecutionPolicy Unrestricted

進階補充

上面的內容其實已經足夠解決問題了,如果想多了解,下面有些小小補充。
關於執行原則,想看到更詳細的內容,可以利用List參數,會顯示每個「執行原則範圍」以及「PowerShell執行原則」,並且會依照優先順序列出。

以下列的執行範圍來看,LocalMachine其實是排在最後一位。但是由於前面幾個的範圍都是Undefined,所以我在執行時使用的其實會是LocalMachine的執行原則Restricted

Get-ExecutionPolicy -List

執行原則範圍共有五個:
MachinePolicy: 由電腦的所有使用者的群組原則設定。
UserPolicy: 由電腦目前使用者的群組原則設定。
Process: Process 範圍只會影響目前的 PowerShell 會話。
CurrentUser: 執行原則只會影響目前的使用者。
LocalMachine: 執行原則會影響目前電腦上的所有使用者。

而我們剛剛在沒有指定範圍的情況下,預設會是LocalMachine。所以沒有指定範圍時,不管是使用Get查看或是Set設定,都是顯示與設定LocalMachine的執行原則。

如果想要指定範圍查看或是變更執行原則,可以使用scope參數來去查看與變更。例如以下我去指定scope CurrentUser,查看與變更它的執行原則。

關於更多詳細與正確的Get-ExecutionPolicy及Set-ExecutionPolicy指令,請參閱官方文件:
Get-ExecutionPolicy 官方說明
Set-ExecutionPolicy 官方說明

額外的額外補充

最後再提一個東西啦,不過這次就不特別講解說明了,如果要開啟可以Bypass執行原則的powershell,也可以直接在powershell的後面加上-ep bypass參數就可以了。用這樣的方式開啟的powershell就可以繞過執行原則。

powershell -ep bypass

發佈留言