C#: Программное определение загрузки Windows Server

Я работаю над процессом автоматизации на С#, который собирается удаленно перезагрузить сервер Windows (2008/2012/2016), и мне нужно дождаться, пока этот сервер вернется в сеть, прежде чем продолжить.

Я знаю, что «возврат в онлайн» может быть неоднозначным, поэтому для моих требований мне нужно, чтобы сервер вернулся на экран Ctrl-Alt-Del. Это делается для того, чтобы сервер находился в согласованном состоянии перед продолжением. По моему опыту, есть несколько факторов, которые могут помешать серверу выйти на этот экран, например, установка обновлений Windows, которые застревают в цикле перезагрузки или застревают в «Ожидание локального диспетчера сеансов» и т. д.

Я провел несколько дней, изучая это безрезультатно:

  • Очевидно, что сервер начинает отвечать на пинг-запросы до того, как он станет доступен.
  • Время загрузки системы происходит до того, как сервер достигнет желаемого состояния.
  • Любые события, указывающие на загрузку системы, регистрируются до желаемого состояния.
  • Я не могу просто опросить важную службу — когда Windows применяет обновления компьютера перед входом в систему, эти службы могут быть уже запущены. Кроме того, иногда сервер перезагружается во время установки обновлений на этом этапе, что может привести к ложным срабатываниям.
  • Опрос активности ЦП также может привести к ложным срабатываниям или вызвать задержки.

Можно ли каким-либо образом обнаружить, что сервер Windows завершил загрузку и доступен для интерактивного входа в систему?


person sunts    schedule 18.07.2018    source источник
comment
Может быть, запустить код обнаружения в качестве службы отложенного запуска? stackoverflow.com/questions/11015189/< /а>   -  person Tim Medora    schedule 19.07.2018
comment
Я забыл упомянуть, что не могу установить службу Windows на этот сервер. Я мог бы создать исполняемый файл и вызывать его через PsExec или PowerShell. Проблема в том, каким будет код обнаружения, я не знаю, как определить желаемое состояние.   -  person sunts    schedule 19.07.2018
comment
Возможно, создайте службу и разверните ее для автоматического запуска... и пропингуйте эту службу.   -  person Dan Hunex    schedule 19.07.2018
comment
Проблема со службой заключается в том, что она, скорее всего, будет запущена до появления экрана Ctrl-Alt-Del, поэтому ее опрос до тех пор, пока она не будет запущена, может привести к ложному срабатыванию. Кроме того, как указано выше, я не могу установить службу Windows на эти серверы :(   -  person sunts    schedule 19.07.2018
comment
Вы знаете, что можете настроить Windows для автоматического входа в систему с заданным пользователем и паролем, хранящимся в реестре. Почему вы ждете экрана входа в систему?   -  person Alois Kraus    schedule 19.07.2018
comment
Для меня на нашем предприятии невозможен автоматический вход в систему, и для интерактивного входа в систему требуется MFA. Кроме того, мне нужно делать это удаленно, а не в интерактивном режиме, поскольку это необходимо масштабировать до тысяч серверов.   -  person sunts    schedule 19.07.2018
comment
Вы можете проверить, ожидается ли перезагрузка (stackoverflow.com/questions/47867949/), и если нет, и экран входа в систему присутствует, вы можете продолжить. Это также может помочь проверить журналы установки, прежде чем продолжить.   -  person Alois Kraus    schedule 19.07.2018
comment
Я могу проверить файл logonui.exe в сеансе 1, что будет означать, что сервер загрузил экран входа в систему, но это окно также отображается при установке обновлений Windows или при возникновении проблемы с загрузкой, например, при зависании в ожидании локального диспетчера сеансов и т. д. .   -  person sunts    schedule 19.07.2018


Ответы (2)


Похоже, вы рассмотрели большинство возможных способов, о которых я знаю. Что заставляет меня вернуться к идеям грубой силы. Мне любопытно, что вы делаете, когда не можете установить службу Windows на поле (или это просто не очень жизнеспособно из-за числа)

Во-первых, просто попытаться удаленно войти в систему или что-то еще, и иметь какой-то способ проверить, не сработает это или нет, подождите 1 минуту, попробуйте еще раз. Но похоже, что это может вызвать у вас побочные проблемы?

Моя идея метода грубой силы, который не повлияет на состояние:

  • Пинг каждые 1-5 секунд
  • Как только он начнет отвечать
  • подождите 5 или 10 или даже 15 минут, продолжая пинговать его
  • Если проверка связи не удалась, сбросьте этот таймер (случай перезапуска обновлений Windows)
  • Затем будьте красивы уверены, что находитесь в правильном состоянии.

С потенциально тысячами серверов я не могу себе представить, что 15 минут на каждом будут иметь большое значение, особенно если они достаточно последовательны, чтобы можно было запускать большие партии.

person Thymine    schedule 18.07.2018
comment
Я думаю, что какой-то подход «грубой силы» может быть единственным вариантом. Я могу проверить, запущен ли процесс logonui.exe в сеансе 1, что указывает на то, что сервер несколько загрузился, просто я не могу найти способ вытащить текст из окна, ищущего Ctrl-Alt-Del. Очевидно, это сделано специально, поскольку winlogon должен быть безопасным рабочим столом. Мне не очень нравится идея пинговать в течение определенного времени, так как это приведет к ненужным задержкам. Установка обновлений Windows иногда также занимает намного больше 15 минут, что означает, что опрос необходимо продлить. - person sunts; 19.07.2018
comment
Может быть, мне повезло с оборудованием и по крайней мере с обновлением ОС на пакетах обновлений. Наблюдение за logonui кажется достаточно надежным, возможно, также проверьте процессы с Windows*KB*.exe (и любыми другими известными вам шаблонами) в них, чтобы также иметь возможность обнаруживать обновления Windows (в основном разработать белый список и черный список процессы, за которыми следует наблюдать и принять решение подождать или продолжить) - person Thymine; 19.07.2018

Итак, я смог добиться этого, используя хакерский метод, который, похоже, работает в моей тестовой среде.

Обратите внимание, что свойство el.Current.Name будет соответствовать тексту Ctrl-Alt-Del, поэтому в 2008R2 это «Нажмите CTRL-ALT-DEL, чтобы войти в систему» ​​и «Нажмите CTRL-ALT-DEL, чтобы войти в систему». на 2012R2

Я создал консольное приложение С#, использующее автоматизацию пользовательского интерфейса:

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

Сейчас это очень большая работа, так как я не могу передать вывод команды вызывающему процессу, поэтому я могу просто посмотреть, чтобы заполнить значение реестра или записать в файл, который впоследствии может быть опрошен.

person sunts    schedule 20.07.2018