Windows server выкидывает пользователя

Обновлено: 04.07.2024

Привет. Недавно столкнулся с очень неприятной ситуацией — часть серверов начала самопроизвольно выключаться. Какой — либо закономерности в выключениях проследить не удавалось. Единственное что объединяло серверы — это то что на них была установлена ОС 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). Так же есть пункт "Отключиться", если выберите его, то пользователь будет выброшен с терминального сервера, но его сессия останется на нем, данная операция равносильна тому, если пользователь просто нажал в окне с названием терминального сервера крестик.

как выкинуть пользователя-03

Второй метод разлогинить пользователя на терминальном сервере

Второй метод, похож на первый, за исключением того, что нам необходимо залогиниться на нужный сервер, открыть оснастку "Диспетчер задач" и уже из него произвести выход пользователя. Сказано сделано, о том, как вам попадать на нужного участника RDS фермы я рассказывал. Далее щелкаем правым кликом по области пуска и из контекстного меню выбираем пункт "Диспетчер задач". Кстати, вызвать "Диспетчер задач" можно и через сочетание клавиш CTRL+SHIFT+ESC.

как выкинуть пользователя-04

Находим нужного нам пользователя и щелкаем по нему правым кликом, в контекстном меню. нас будет интересовать пункт "Выйти". Выбираем его и завершаем сессию пользователя.

Выход пользователя в диспетчере задач

Бывает так, что первые два метода не помогают в случаях, когда пользовательская сессия зависает на терминальном сервере, вы вроде бы из графического интерфейса делаете выход, но оно не отрабатывает. В таких случаях нужно использовать утилиты командной строки или PowerShell

Использование утилиты RWINSTA

Если вы попали в ситуацию, когда графические методы не позволяют вам произвести выход пользователя из системы, а это необходимо, то вам на помощь придут утилиты из командной строки. RWINSTA - это встроенная в Windows утилита, которая позволяет сбрасывать сессии, по ID и имени сеанса. Первым делом вам нужно вычислить или ID сессии или ее имя, я вам рассказывал, о всех известных мне методах. можете ознакомиться. Я выберу утилиту qwinsta. Пишем команду:

или удаленно qwinsta /server:имя сервера | findstr barboskin.g

Использование утилиты RWINSTA

И в первом и во втором случае, пользователь будет разлогинен с данного сервера. Данную команду можно запускать удаленно, со своего рабочего места, главное, чтобы были права на log off. Данный метод меня ни раз выручал в моей практике, например случай с зависшей сессией на Windows Server 2016, где вместо логина пользователя было имя (4).

Как отключить пользователя через reset session

Как отключить пользователя через reset session

Как отключить пользователя через logoff

Как отключить пользователя через logoff

Выход пользователя через командлет Stop-TSSession

Есть такой замечательный командлет Stop-TSSession. Посмотрим на сервере ID и имя сеанса, для этого в открытой оболочке PowerShell введите:

В итоге я вижу, что у пользователя barboskin.g SessionID 3. Далее пишем

Stop-TSSession 3 или принудительно Stop-TSSession 3 -Force

Выход пользователя через командлет Stop-TSSession

Соглашаемся с тем, что будет производиться log off для данного пользователя. Проверяем, что сессия завершена. Можно вот таким простеньким скриптом из планировщика задач, разлогинивать сессии:

Import-Module PSTerminalServices
Get-TSSession -ComputerName SERVER_NAME -filter | Stop-TSSession –Force

Выход пользователя через командлет Stop-TerminalSession

Данный командлет устанавливается отдельно, совместно с пакетом Pscx. Первым делом посмотрим локально или удаленно идентификаторы сессии пользователя, для которого мы хотим сделать log off. Выполняем команду:

Get-TerminalSession

Нужный мне 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

  1. А вот теперь почему делали в два этапа. Просто файл сессий имеет следующий вид

Файл сессий

И, как видно, из файла строка со статусом «Диск» не имеет Имя сеанса и соответственно в отключенном сеансе 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.

Читайте также: