简体   繁体   English

C#:以编程方式检测 Windows Server 已启动

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

I'm working on an automation process in C# that is going to remotely reboot a Windows (2008/2012/2016) server and I need to wait until that server is back online before proceeding.我正在使用 C# 进行自动化过程,该过程将远程重新启动 Windows (2008/2012/2016) 服务器,我需要等到该服务器重新联机才能继续。

I know 'back online' can be ambiguous, so for my requirements, I need the server to be back at the Ctrl-Alt-Del screen.我知道“返回在线”可能不明确,因此根据我的要求,我需要服务器返回 Ctrl-Alt-Del 屏幕。 The reason for this is to have the server in a consistent state before proceeding.这样做的原因是在继续之前让服务器处于一致状态。 In my experience, there are several factors that could prevent the server from reaching this screen, such as installing windows updates that gets stuck in a reboot cycle or getting stuck at 'Waiting for Local Session Manager' etc.根据我的经验,有几个因素可能会阻止服务器到达此屏幕,例如安装 Windows 更新卡在重启周期或卡在“等待本地会话管理器”等。

I've spent a few days looking in to this to no avail:我花了几天时间研究这个无济于事:

  • The server obviously starts responding to ping requests before it is available服务器显然在它可用之前就开始响应 ping 请求
  • System Boot Time occurs before the Server reaches the desired state系统启动时间发生在服务器达到所需状态之前
  • Any events indicating the system has booted are logged before the desired state任何指示系统已启动的事件都会在所需状态之前记录下来
  • I can't simply poll for an essential service - when Windows is applying computer updates prior to logon these services can be already started.我不能简单地轮询基本服务 - 当 Windows 在登录之前应用计算机更新时,这些服务可能已经启动。 Additionally, sometimes a server will reboot itself whilst installing updates at this stage which could result in false positives.此外,有时服务器会在此阶段安装更新时自行重启,这可能会导致误报。
  • Polling CPU activity could also produce false positives or introduce delays轮询 CPU 活动也可能产生误报或引入延迟

Is there anyway to detect a Windows server has finished booting and is available for an interactive logon?无论如何检测Windows服务器已完成启动并且可用于交互式登录?

It sounds like you've covered most of the possible ways I know of.听起来你已经涵盖了我所知道的大多数可能的方式。 Which makes me revert to brute force ideas.这让我恢复到蛮力的想法。 I am curious what you're doing where you can't install a windows service on the box (or is that just not very viable because of the number)我很好奇你在做什么,你不能在盒子上安装 Windows 服务(或者因为数量不是很可行)

First would just be trying to remote login or whatever, and having some way to test if it fails or not, wait 1 minute, try again.首先只是尝试远程登录或其他什么,并有一些方法来测试它是否失败,等待 1 分钟,再试一次。 But seems like that might cause side-issues for you somehow?但似乎这可能会以某种方式对您造成副作用?

My idea of a brute force method that wouldn't affect state:我对不影响状态的蛮力方法的想法:

  • Ping every 1-5seconds每 1-5 秒 ping 一次
  • Once it starts responding一旦它开始响应
  • wait 5 or 10 or even 15 minutes, whilst still pinging it等待 5 或 10 甚至 15 分钟,同时仍然 ping 它
  • If pings fail reset that timer (windows updates restart case)如果 ping 失败,则重置该计时器(Windows 更新重启情况)
  • Then be pretty confident you're at the right state.然后非常自信你处于正确的状态。

With potentially thousands of servers, I can't imagine 15 minutes each would be a big deal, especially if it is consistent enough to be able to run in larger batches可能有数千台服务器,我无法想象每个 15 分钟会是什么大不了的事,尤其是如果它足够一致以能够大批量运行

So I've been able to accomplish this by using a hacky method put seems to work in my test environment.所以我已经能够通过使用一种看起来在我的测试环境中工作的hacky方法来实现这一点。

Note that the el.Current.Name property will equate to the Ctrl-Alt-Del text, so on 2008R2 this is 'Press CTRL-ALT-DEL to log on' and 'Press CTRL-ALT-DEL to sign in.'请注意,el.Current.Name 属性将等同于 Ctrl-Alt-Del 文本,因此在 2008R2 上,这是“按 CTRL-ALT-DEL 登录”和“按 CTRL-ALT-DEL 登录”。 on 2012R2在 2012R2

I've built a C# console application that uses UI Automation:我构建了一个使用 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;
            }

        }
    }
}

I can then execute this console application via PsExec, however, because this needs to be launched in the winlogon desktop, which can only be done by running under the local system, PsExec is invoked twice.然后我可以通过 PsExec 执行这个控制台应用程序,但是,因为这需要在 winlogon 桌面中启动,这只能通过在本地系统下运行来完成,所以 PsExec 被调用了两次。 For example:例如:

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

This is very much a work in progress right now as I can't get the output of the command to pass through to the calling process so I may just look to populate a registry value or write to a file that can be subsequently interrogated.这是一项目前正在进行的工作,因为我无法将命令的输出传递给调用进程,因此我可能只想填充一个注册表值或写入一个可以随后进行查询的文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Windows完全启动后如何确保C#应用程序启动 - How to ensure C# application starts after windows is booted compltely 如何从Windows 7中的C#检测应用程序中是否包含UI元素? - How to detect if an application has UI elements in it from C# in Windows 7? 如何检测Windows Mobile设备是否具有摄像头? C# - how to detect if windows mobile device has camera ? c# 使用C#或WixToolset以编程方式安装IIS Windows Server 2016 - Programmatically Installing IIS Windows Server 2016 using C# or WixToolset 如何在C#中检测Windows Server 2008上的防病毒软件? - How to detect antivirus on Windows Server 2008 in C#? 如何检测 WinPE(4) 是否已从 UEFI 或 BIOS 启动? - How do I detect if WinPE(4) has booted from a UEFI or BIOS? 使用C#检测Windows关闭 - Detect Windows shutdown with C# 确定Windows计算机何时已完全启动并开始响应 - Determine When Windows Computer has fully booted and becomes responsive 使用C#,如何以编程方式确定Windows证书存储中的证书是否已被禁用 - Using C#, how to programmatically determine if a certificate in a Windows certificate store has been disabled 如何在C#中检测音频设备何时被拔出(windows vista) - How to detect when an audio device has been unplugged (windows vista) in C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM