有些批次檔需要管理員權限才能正常執行,例如修改系統設定、操作受保護的資料夾、或是安裝服務。
相較於要求使用者以滑鼠右鍵「以系統管理員身份執行」,比較合理的做法是讓批次檔自己偵測權限,不足就直接觸發 UAC 提示重新啟動,因為最常發生的狀況就是直接啟動了腳本就被提示權限不足,使用體驗大打折扣。
做法
把以下程式碼貼在批次檔的最前面,Your codes 之後再接原本的邏輯:
| |
運作原理
偵測權限:用
cacls.exe嘗試讀取%SYSTEMROOT%\system32\config\system,這個檔案只有管理員才能存取。如果errorlevel不是0,代表目前沒有管理員權限。觸發 UAC:在
%temp%建立一個暫時的 VBScript,內容是呼叫Shell.Application的ShellExecute並指定runas動詞——這就是彈出 UAC 視窗的標準方式。VBScript 執行後,原本的 batch 程序直接exit /B結束,由新的提升後的 process 接手。清理並繼續:取得權限後,刪除剛才建立的暫時 VBScript,然後
pushd確保工作目錄正確,讓後續指令可以用相對路徑正常執行。
用在 PowerShell 腳本的啟動器
現在寫自動化腳本大多傾向用 PowerShell,.bat 檔案很常見的用途是當 .ps1 的啟動器——由 batch 負責提權、設定執行政策,再呼叫 PowerShell 腳本本體:
| |
為什麼不直接在 .ps1 裡觸發 UAC?其實 PowerShell 可以自我提權,寫法大概長這樣:
| |
但問題不在提權本身,主要有兩個獨立的阻礙:
第一:Execution Policy(主因)
Windows 客戶端預設的執行政策是 Restricted,直接禁止所有 .ps1 執行,不管是雙擊還是在命令列輸入路徑都一樣擋。企業環境還常透過 Group Policy 強制鎖定這個設定。.bat 啟動器可以在呼叫時帶入 -ExecutionPolicy Bypass 直接繞過,這是最主要的實際原因。
第二:雙擊不執行(獨立的安全設計)
即使 Execution Policy 已放寬,.ps1 雙擊預設也不會執行——Windows 把副檔名關聯設成用 PowerShell ISE(或其他關聯的 editor)開啟,而不是直接跑。Microsoft 文件明確指出這是刻意設計,與 Execution Policy 是兩件獨立的事。.bat 就沒有這個問題,雙擊直接執行。
兩個問題疊在一起,讓 .bat 作啟動器成為最省事的做法。
注意事項
- UAC 提示會跳出一個獨立視窗,所以原本的 console 視窗會關掉、再開一個新的。如果有 console 輸出需要保留,注意這個行為。
%~s0是批次檔自身的短路徑(8.3 格式),避免路徑含空白時 VBScript 解析出錯。- Windows 11 / 10 都適用,不需要額外安裝任何工具。
References