簡體   English   中英

C#:以編程方式檢測 Windows Server 已啟動

[英]C#: Programmatically Detect Windows Server Has Booted

我正在使用 C# 進行自動化過程,該過程將遠程重新啟動 Windows (2008/2012/2016) 服務器,我需要等到該服務器重新聯機才能繼續。

我知道“返回在線”可能不明確,因此根據我的要求,我需要服務器返回 Ctrl-Alt-Del 屏幕。 這樣做的原因是在繼續之前讓服務器處於一致狀態。 根據我的經驗,有幾個因素可能會阻止服務器到達此屏幕,例如安裝 Windows 更新卡在重啟周期或卡在“等待本地會話管理器”等。

我花了幾天時間研究這個無濟於事:

  • 服務器顯然在它可用之前就開始響應 ping 請求
  • 系統啟動時間發生在服務器達到所需狀態之前
  • 任何指示系統已啟動的事件都會在所需狀態之前記錄下來
  • 我不能簡單地輪詢基本服務 - 當 Windows 在登錄之前應用計算機更新時,這些服務可能已經啟動。 此外,有時服務器會在此階段安裝更新時自行重啟,這可能會導致誤報。
  • 輪詢 CPU 活動也可能產生誤報或引入延遲

無論如何檢測Windows服務器已完成啟動並且可用於交互式登錄?

聽起來你已經涵蓋了我所知道的大多數可能的方式。 這讓我恢復到蠻力的想法。 我很好奇你在做什么,你不能在盒子上安裝 Windows 服務(或者因為數量不是很可行)

首先只是嘗試遠程登錄或其他什么,並有一些方法來測試它是否失敗,等待 1 分鍾,再試一次。 但似乎這可能會以某種方式對您造成副作用?

我對不影響狀態的蠻力方法的想法:

  • 每 1-5 秒 ping 一次
  • 一旦它開始響應
  • 等待 5 或 10 甚至 15 分鍾,同時仍然 ping 它
  • 如果 ping 失敗,則重置該計時器(Windows 更新重啟情況)
  • 然后非常自信你處於正確的狀態。

可能有數千台服務器,我無法想象每個 15 分鍾會是什么大不了的事,尤其是如果它足夠一致以能夠大批量運行

所以我已經能夠通過使用一種看起來在我的測試環境中工作的hacky方法來實現這一點。

請注意,el.Current.Name 屬性將等同於 Ctrl-Alt-Del 文本,因此在 2008R2 上,這是“按 CTRL-ALT-DEL 登錄”和“按 CTRL-ALT-DEL 登錄”。 在 2012R2

我構建了一個使用 UI 自動化的 C# 控制台應用程序:

using System;
using System.Windows.Automation;

namespace WorkstationLocked
{
    class Program
    {
        static void Main()
        {
            AutomationElement el = AutomationUI.FindElementFromAutomationID("LockedMessage");

            if (el !=null)
            {
                Console.WriteLine(el.Current.Name);
            }
        }
    }
    class AutomationUI
    {
        public static AutomationElement FindElementFromAutomationID(string automationID)
        {
            string className = "AUTHUI.DLL: LogonUI Logon Window";

            PropertyCondition condition = new PropertyCondition(AutomationElement.ClassNameProperty, className);
            AutomationElement logonui = AutomationElement.RootElement.FindFirst(TreeScope.Children, condition);

            if (logonui != null)
            {
                condition = new PropertyCondition(AutomationElement.AutomationIdProperty, automationID);
                return logonui.FindFirst(TreeScope.Descendants, condition);
            }
            else
            {
                return null;
            }

        }
    }
}

然后我可以通過 PsExec 執行這個控制台應用程序,但是,因為這需要在 winlogon 桌面中啟動,這只能通過在本地系統下運行來完成,所以 PsExec 被調用了兩次。 例如:

psexec.exe \\ServerA -s -d C:\PsTools\PsExec.exe -accepteula -d -x C:\Utils\WorkstationLocked.exe

這是一項目前正在進行的工作,因為我無法將命令的輸出傳遞給調用進程,因此我可能只想填充一個注冊表值或寫入一個可以隨后進行查詢的文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM