[廚餘回收] 原本應該睡眠的 Windows 10 卻在清晨被喚醒

身為一名程式設計師,打開瀏覽器 Google 一些資料,或是開啟 IDE 寫點程式是常有的事,而當事情做到一半必須被打斷時,「睡眠」這個功能就可以讓電腦在下一次開機的時候,快速地回復到前一次的工作狀態,但是 Windows 10 自從更新了 1903 之後,電腦卻經常在清晨被喚醒,等到我發現的時候,早就不知道運轉了多久、浪費了多少電,甚至直到最近我也更新了 1909,問題依舊還在。

神出鬼沒的 Universal Orchestrator Start 排程

我先從事件檢視器中,尋找被喚醒前後有沒有什麼事件發生? 很幸運地,找到一個 Power-Troubleshooter 事件,其中記錄著我的電腦被一個 Universal Orchestrator Start 的排程喚醒。

既然知道是哪個排程搞的鬼,那我們就去修改排程的觸發時間或是停用就好了,殊不知與 Universal Orchestrator Start 排程的鬥法才剛開始,當我打開工作排程器,翻到了 \Microsoft\Windows\UpdateOrchestrator,卻找不到名稱為 Universal Orchestrator Start 的排程,這下子見鬼了,那是誰來把我的電腦給喚醒的?

Google 到微軟論壇的一篇貼文 - Turn off Task Scheduler "Universal Orchestrator Idle Start" on Task Scheduler,裡面有提到 Universal Orchestrator Start 排程每天會被重新建立,所以我決定守株待兔等它出現,就在隔天下班回家打開電腦之後沒多久,它就出現在工作排程器裡面了。

由於 Universal Orchestrator Start 排程每天都會被重新建立,所以我們調整它的觸發時間或是停用是沒有用的,因此我參考上面提到的那一篇貼文建議的,建立一個排程,在電腦進入睡眠之前,把 Universal Orchestrator Start 排程給停用掉。

建立停用 Universal Orchestrator Start 排程的排程

我原以為這是件很容易的事情,其實沒有,Universal Orchestrator Start 排程的建立及執行身分是 System 帳戶,所以就算我們用系統管理員也無法動它分毫,因此我們必須切換到 System 身分來建立停用的排程,但問題是 System 帳戶不是一般可登入的使用者,還好,在那篇貼文也有提到我們可以借助 PsExec 的力量,用它來切換成 System 身分。

PsTools 下載下來解壓縮後,PsExec 就在裡頭,找到 PsExec 之後我們就用系統管理員的身份執行下面的指令:

PsExec.exe -s -i cmd.exe

第一次執行會跳出一個 License Agreement 的視窗,按 Agree 就行了。

然後,它會開啟一個用 System 身分執行的命令提示字元,我們就利用它來啟動工作排程器。

接著,我們就可以在工作排程器中建立我們要的排程,名稱為 Disable Universal Orchestrator Start,觸發時機為發生 Kernel-Power(187) 事件的時候,執行下面指令:

schtasks.exe /Change /TN "\Microsoft\Windows\UpdateOrchestrator\Universal Orchestrator Start" /DISABLE

最後,測試讓我的電腦進入睡眠狀態,排程有確實執行,Universal Orchestrator Start 排程也被停用了。

或者,建立 Universal Orchestrator Start 檔案卡位

工作排程器中的工作任務都會在 C:\Windows\System32\Tasks\Microsoft\Windows\UpdateOrchestrator 底下建立設定檔,既然 Universal Orchestrator Start 排程會被建立又刪除了,那我們就趁著它被刪除的空檔,建立相同名稱的檔案,卡位讓排程無法被建立,借以阻止 Universal Orchestrator Start 排程執行。

我們先用 PowerShell 在 C:\Windows\System32\Tasks\Microsoft\Windows\UpdateOrchestrator 底下建立名稱為 Universal Orchestrator Start 的檔案。

接著在 Universal Orchestrator Start 檔案的進階安全性設定中,將除了 Administrators 群組以外的角色全部刪除。

最後再把 Universal Orchestrator Start 檔案設成唯讀

如果還是想讓 Universal Orchestrator Start 排程持續執行

如果我們擔心這個排程沒有執行,反而會造成一些非預期錯誤的話,那我們就要趁著 Universal Orchestrator Start 排程還沒被刪除的時候,把排程的觸發時間點改一下,那我這邊是改成「當任何使用者登入時執行」或「當工作站由任何使用者解除鎖定時」。

然後,取消勾選「喚醒電腦以執行此工作」。

修改 Universal Orchestrator Start 排程記得切換到 System 身分

最後把 Universal Orchestrator Start 檔案的安全性,設定成 System 只能讀取及執行,Administrators 群組可完全控制。

要再保險一點的話,可以將檔案設成唯讀。

以上,利用這三種方式,我的電腦終於可以一夜好眠了

參考資料

C# 指南 ASP.NET 教學 ASP.NET MVC 指引
Azure SQL Database 教學 SQL Server 教學 Xamarin.Forms 教學