[英]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:我花了几天时间研究这个无济于事:
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:我对不影响状态的蛮力方法的想法:
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.