Windows server выкидывает пользователя
Привет. Недавно столкнулся с очень неприятной ситуацией — часть серверов начала самопроизвольно выключаться. Какой — либо закономерности в выключениях проследить не удавалось. Единственное что объединяло серверы — это то что на них была установлена ОС Windows Server 2012 или выше, и большая их часть имеет роль терминальных. Ах да, еще все эти серверы — виртуальные и работают под управлением Hyper V. Хочу сегодня рассказать, в чем была проблема.
Конечно, любая диагностика должна начинаться с анализа логов. И вот какое событие удалось обнаружить непосредственно перед выключениями серверов – событие 1074, user32:
The process C:\Windows\system32\winlogon.exe (DC) has initiated the power off of computer DC on behalf of user NT AUTHORITY\SYSTEM for the following reason: No title for this reason could be found
Reason Code: 0x500ff
Shutdown Type: power off
Comment:
По ним становится понятно, что работа завершается штатно. Что в общем то позволяет исключить влияние железа, хотя оно и так было исключено, т. к. все серверы виртуальные. Под подозрение попал гипервизор, но рысканье вдоль и поперек по логам ни какого результата не дало. События относящиеся к завершениям работы не имели отношения к инициализации завершения работы. Говорят, что виртуальные машины могут в редких случаях произвольно выключаться, если есть проблемы со свободной памятью, но в моем случае памяти было более чем достаточно.
В общем думаю хватит томить, и пора рассказать вам, в чем же в итоге было дело. Подключившись по RDP, я сидел и размышлял, что же может быть причиной подобного завершения работы. И вот из-за бездействия меня выбило на экран ввода пароля, где я обнаружил вот такой экран:
Обратите внимание на нижний угол:
Да, это мать его, завершение работы системы. Оказывается с 2012 винды MS сделали эту кнопку доступной при подключении по RDP.
Отвечает за эту кнопку параметр в групповой политике -
Computer Configuration – Policies – Windows Settings – Local Policies – Security Options – Shutdown: Allow system to be shut down without having to log on.
Отключаем его и всё, возможности выключить сервер у пользователей не будет.
Почему в моем случае этот параметр оказался включенным - остается загадкой. Скорее всего кто-то когда-то давным-давно его включил. Хотя, не исключаю, что он оказывается включенным при переходе с 2008 домена, проверять, честно говоря, лень. Кто в курсе, напишите в комментариях, в каком состоянии находится этот параметр при добавлении контроллера домена Windows 2012 в домен с уровнем 2008r2 или ниже.
В общем и целом, после изменения этого параметра мистические выключения прекратились.
Описание проблемы
Методы завершения сессии пользователя не терминале
Существует несколько методов позволяющие выкинуть пользователя с сервера.
- Завершить сессию пользователя (Сделать log off) вы можете из оснастки управления RDS фермой
- Разлогинить пользователя можно и на самом терминальном сервере из диспетчера задач
- Выход пользователя можно выполнить из утилиты командной строки rwinsta
- Утилита командной строки log off
- Утилита reset session
- * Командлет Stop-TSSession
Как выкинуть пользователя из оснастки управления RDS
И так, у меня есть мой любимый, тестовый пользователь в Active Directory, по имени Барбоскин Геннадий Викторович. Предположим, что он зашел на терминальный стол и нам по причине зависания его сессии, нужно сделать ему выход. Первый метод, это использование оснастки по управлению RDS фермой, я вам рассказывал, как ее собирать. Открываем раздел с вашей коллекцией RDS фермы. В поисковом фильтре указываем логин или фамилию нужного сотрудника. В результате получаем хост, где он работает.
Щелкаем по нему правым кликом. В контекстном меню будет пункт "Выйти", это и соответствует завершению сессии (Log off). Так же есть пункт "Отключиться", если выберите его, то пользователь будет выброшен с терминального сервера, но его сессия останется на нем, данная операция равносильна тому, если пользователь просто нажал в окне с названием терминального сервера крестик.
Второй метод разлогинить пользователя на терминальном сервере
Второй метод, похож на первый, за исключением того, что нам необходимо залогиниться на нужный сервер, открыть оснастку "Диспетчер задач" и уже из него произвести выход пользователя. Сказано сделано, о том, как вам попадать на нужного участника RDS фермы я рассказывал. Далее щелкаем правым кликом по области пуска и из контекстного меню выбираем пункт "Диспетчер задач". Кстати, вызвать "Диспетчер задач" можно и через сочетание клавиш CTRL+SHIFT+ESC.
Находим нужного нам пользователя и щелкаем по нему правым кликом, в контекстном меню. нас будет интересовать пункт "Выйти". Выбираем его и завершаем сессию пользователя.
Использование утилиты RWINSTA
Если вы попали в ситуацию, когда графические методы не позволяют вам произвести выход пользователя из системы, а это необходимо, то вам на помощь придут утилиты из командной строки. RWINSTA - это встроенная в Windows утилита, которая позволяет сбрасывать сессии, по ID и имени сеанса. Первым делом вам нужно вычислить или ID сессии или ее имя, я вам рассказывал, о всех известных мне методах. можете ознакомиться. Я выберу утилиту qwinsta. Пишем команду:
или удаленно qwinsta /server:имя сервера | findstr barboskin.g
И в первом и во втором случае, пользователь будет разлогинен с данного сервера. Данную команду можно запускать удаленно, со своего рабочего места, главное, чтобы были права на log off. Данный метод меня ни раз выручал в моей практике, например случай с зависшей сессией на Windows Server 2016, где вместо логина пользователя было имя (4).
Как отключить пользователя через reset session
Как отключить пользователя через logoff
Выход пользователя через командлет Stop-TSSession
Есть такой замечательный командлет Stop-TSSession. Посмотрим на сервере ID и имя сеанса, для этого в открытой оболочке PowerShell введите:
В итоге я вижу, что у пользователя barboskin.g SessionID 3. Далее пишем
Stop-TSSession 3 или принудительно Stop-TSSession 3 -ForceСоглашаемся с тем, что будет производиться log off для данного пользователя. Проверяем, что сессия завершена. Можно вот таким простеньким скриптом из планировщика задач, разлогинивать сессии:
Import-Module PSTerminalServicesGet-TSSession -ComputerName SERVER_NAME -filter | Stop-TSSession –Force
Выход пользователя через командлет Stop-TerminalSession
Данный командлет устанавливается отдельно, совместно с пакетом Pscx. Первым делом посмотрим локально или удаленно идентификаторы сессии пользователя, для которого мы хотим сделать log off. Выполняем команду:
Нужный мне ID сеанса 427. Далее воспользуемся командлетом Stop-TerminalSession, чтобы выкинуть пользователя и завершить его сессию.
Как то, в одной конторе нужно было бэкапить файловую базу а она в свою очередь хранилась на серваке, к серваку юзвери цеплялись терминальным клиентом и работали с 1С, понадобилось перед бекапом гасить юзеров, точнее выходить из их сеансов.
И вот был написан скриптик, который по времени перед бекапом выкидывает пользователей.
Скрипт, кстати, во вложении (точнее, 3 скрипта: выкинуть всех, выкинуть активных и выкинуть отключенных).
Как это работает на примере скрипта, который выкидывает всех пользователей:
query user >user_temp_all.txt
2. Убираем из файла строку со словом “console”, так как консольного юзера не нужно выкидывать;
find "console" user_temp_all.txt > user_temp.txt /V
find "Активно" user_temp.txt > user.txt
4. Убиваем файл start.bat;
del start.bat
5. Вдруг никто не подключен, соответственно файл user.txt будет пустой, а файл скрипта нам нужен в любом случае, надо создать и написать что-то в файл, чтобы он смог запуститься;
@echo rem begin files start.bat>start.bat
6. Обработаем файл user.txt. Синтаксис команды for можно посмотреть по команде for /?, но расскажу по-быстрому: команда фор перебирает файл и разлаживает содержимое строки по переменным, ну и запускает для каждой строки команду, разберем начало for /f "skip=2 tokens=3," %%i
for в принципе сама команда, ключ /F означает перебрать и выполнить команду для каждой строки
параметр skip=2 означает, что пропустим 2-е первые строчки
параметр tokens=3 означает, что берем в строке 3-е значение, разделенное пробелами или «,» или «таб.» и помещаем его в переменную %%i
Разберем следующий кусок in (user.txt) DO echo logoff %%i >>start.bat
In (user.txt) означает, что перебираем файл user.txt
DO echo logoff %%i>>start.bat выполнить команду echo logoff %%i (сюда подставляется ид сеанса или значение переменной %%i) и результат добавить к файлу start.bat, команда эхо просто выводит в поток то, что написано после этого слова
7. Первый этап закончили, теперь нужно обработать неактивные сессии, допишем в файл start.bat строчку «echo rem NoAction session» просто чтобы видеть где закончился 1-й этап скрипта, так как файл start.bat не удаляется, то можно посмотреть что в нем было после запуска;
@echo rem NoAction session >>start.bat
8. Принцип второго этапа аналогичный первому, теперь в файле с сессиями ищем строки со словом «Диск», это те сеансы, которые отключены;
find "Диск" user_temp.txt>user.txt
- А вот теперь почему делали в два этапа. Просто файл сессий имеет следующий вид
И, как видно, из файла строка со статусом «Диск» не имеет Имя сеанса и соответственно в отключенном сеансе ID сеанса является 2-й переменной, если пробел считать разделителем, а при активном сеансе она является 3-й переменной, поэтому в первом этапе параметр tokens=3, а во втором этапе tokens=2, вот поэтому скрипт разбил на 2 части
for /f "skip=2 tokens=2," %%i in (user.txt) DO echo logoff ID %%i >>start.bat
9. Теперь убиваем лишние файлы
del user_temp.txt
del user.txt
10. Запускаем наш батник, который у нас получился, и результат работы выводим в файл log_logoff.txt
start.bat > log_logoff.txt
З.Ы.: почему не убили все файлы? чтобы видеть, какие вообще были сеансы после запуска скрипта.
Почему задача так сформулирована, потому как доводилось мне администрировать одну организацию ( kari), но вот только чтобы подключиться к серверам, нужно было зайти сперва на одну станцию выделенную для прямого доступа, а уже потом с нее на контролируемые сервера. Но как всегда не всё так красиво и удобно, на контролируемых серверах (к примеру dc,ts и так далее) уже был залогинен сотрудник из отдела имеющий привычку не завершать корректно свою сессию . Попытки объяснить или как то донести до человека, что он не один, результатов не приносило. Поэтому родилась данная заметка.
Для справки: любое совпадение с реальными данными чистое совпадение все данные включая сервера, логины, аутентификационные сведения лишь плод моего воображения.
Please wait for KARI\d.shatilov to respond
Вообщем я разобрал как выкидывать залогининных пользователей через консоль :
Подключаемся на сервер с которого уже производиться дальнейшее управление серверами клиента «Кари».
Win + R → mstsc /v:<ip_ выделенная_станция > /admin /w:1024 /h:768
Далее открываю консоль командной строки на выделенной станции с правами Администратора и делаю так:
Нижеследующий пример взят для примера, потому как в конечно итоге действия аналогичны, это просто для наглядности.
На заметку: нужно обладать правами Администратора на удаленном сервере прежде чем исполнять ниже следующий запрос.
C:\Users\aollo>qwinsta /server:ts03f.kari.local
Этим мы получаем информация по активным rdp сессиям на удаленном терминальном сервере ( ts 03 f ), то т.к. для администрирования нужно подключаться с ключом / admin , то нужно одну из двух сессий выбить, предварительно проверить каков период неактивности у нее.
Вывести все терминальные подключения которые находятся в статусе Disconnect :
services 0 Disc
e.lysenko 28 Disc
n.tashtenov 39 Disc
y.fomenko 62 Disc
R.Shishkin 66 Disc
s.likova 91 Disc
a.lukashenko 109 Disc
Чтобы кикнуть кого-либо ( в данном случае пользователя a.lukashenko ) нужно, указать идентификатор сессии полученной из предыдущего исполнения команды:
C:\Users\aollo>logoff /server:ts07f.kari.local 109 /v
Logging off session ID 109
services 0 Disc
Не правильно отсоединенной сессии нет, я ее логофнул.
И уже после этих действий подключиться к удаленному серверу находящемуся на обслуживании не представляет ни каких трудностей. Хоть и неправильно это делать, но другого выхода порой не было. На этом заметка завершена, цель поставленной задачи расписана с показом примера, как и что делать. Вот собственно и все, с уважением ekzorchik.
Используйте прокси ((заблокировано роскомнадзором, используйте vpn или proxy)) при использовании Telegram клиента:
Поблагодари автора и новые статьи
будут появляться чаще :)
Карта МКБ: 4432-7300-2472-8059
Большое спасибо тем кто благодарит автора за практические заметки небольшими пожертвованиями. С уважением, Олло Александр aka ekzorchik.
Читайте также: