Скрипт автоматически выкидывающий пользователей из терминальной сессии.
Так как пользователи по большей степени не хотят вникать во все компьютерные тонкости, то нам, админам, приходится постоянно бороться не только с серверами, но и с обычными юзерами! К чему это я? Да всё очень просто - имеется у нас в одном филиале терминальный сервер 1C, но так как денег было мало выделено, то удалось в сервак поставить всего 16 гектар оперативки. Но сам терминальный сервак сделал я виртуальным, в итоге я выделил ему всего 10 гектар оперативы, 2 на виртуальный контроллер контроллер домена, 2 под FreeBSD для бэкапов, остальное отдал под платформу VMWare ESXI 5.1. Я начал потихоньку переносить пользователей в домен, а их контроллер перенёс в отдельный сайт. После успешного переноса всех пользователей на новый терминальный сервер выяснилось, что не хватает памяти в серваке.
После проведённого анализа выяснилось, что всю память съедает SQL, на котором крутится 1С. Было решено провести ряд мер по изменению ситуации:
Удалось приобрести простенький NAS от D-Link. Туда я перенёс бэкапы и соответственно избавился от FreeBS. Терминальному серверу выделил ещё 2 гектара оперативы.
Удалось приобрести ещё 4 планки памяти по 2 гектара. Заменил в серваке 4 планки с 1 на 2 гектара. В итоге прирост ещё в 4 гектара.
Был написан скрипт, который автоматически выбрасывает пользователей из терминальной сессии, что приводит к выгрузке из памяти профиля пользователя со всеми службами и процессами пользователя, что существенно повлияло на работоспособность сервера.
Сам скрипт написал на VBS, на серваке создал задание, которое запускает скрипт каждый час. При написании скрипта были поставлены следующие задачи:
Не трогать сессии админов!
Тех пользователей, что просто нажали на крестик (т.е. неправильно закрыли сессию) выкидываем сразу.
Остальных пользователей выкидываем при простое большем чем в 9 часов (почему выбрано именно так, а не всех поголовно в определённое время? филиал работает круглосуточно!).
Не забываем про отчётность! админ должен знать что и когда происходило!
Сам скрипт RDP_Reset.vbs:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Скрипт следит за терминальными пользователями и выкидывает их сессии по условиям: '
' 1.По какой-либо причине не произошёл выход из сессии '
' 2.Пользователь не закрывает сессию более 8 часов! Просто какой-то кашмар - '
' пора домой, а они кричат: "Хлебом не корми - работу давай!" '
' Скрипт написал Анчуров Олег Владимирович в 2013 году. '
' Скрипт взят с сайта: http://ithelp.moy.su '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
On Error Resume Next
Dim WshShell, WshShell2
Dim objScriptExec, objScriptExec2
Set WshShell = CreateObject("Wscript.Shell")
Set WshShell2 = CreateObject("Wscript.Shell")
Set objScriptExec = WshShell.Exec("qUser.exe")
Dim User, Rdp, Id, Status, OffLine, TDate, TTime
Dim Line, Line2
Dim a, c, t, p, i, Reset
Dim Msg, k
Msg = "ПРОТОКОЛ РАБОТЫ СКРИПТА, АВТОМАТИЧЕСКИ ВЫКИДЫВАЮЩЕГО ПОЛЬЗОВАТЕЛЕЙ ИЗ ТЕРМИНАЛЬНЫХ СЕССИЙ НА ТЕРМИНАЛЬНОМ СЕРВАКЕ:" + chr(13) + chr(10) + chr(13) + chr(10)
k = 0
Do Until objScriptExec.StdOut.AtEndOfStream
Line = objScriptExec.StdOut.ReadLine
Line2 = ""
'Производим перекодировку текста из Dos в ANSI:
For i = 1 to Len(Line)
a = Asc(Mid(Line,i,1))
If a < 128 then Line2 = Line2 + chr(a)
If a > 127 and a < 176 then Line2 = Line2 + chr(a + 64)
If a > 175 and a < 224 then Line2 = Line2 + chr(a)
If a > 223 and a < 240 then Line2 = Line2 + chr(a + 16)
If a = 240 then Line2 = Line2 + chr(168)
If a = 241 then Line2 = Line2 + chr(184)
If a > 241 then Line2 = Line2 + chr(a)
Next
Line = Line2
'Разщипляем строку на составляющие
User = LCase(Trim(Mid(Line, 2, 22)))
Rdp = LCase(Trim(Mid(Line, 24, 16)))
Id = LCase(Trim(Mid(Line, 40, 6)))
Status = LCase(Trim(Mid(Line, 47, 8))) 'Если нужно, то раскоментировать!
OffLine = LCase(Trim(Mid(Line, 55, 12)))
TDate = LCase(Trim(Mid(Line, 67, 11))) 'Если нужно, то раскоментировать!
TTime = LCase(Trim(Mid(Line, 78, 6))) 'Если нужно, то раскоментировать!
'Первая строка нас не интересует!
'Переменная Rdp может принимать следующие значения:
'rdp-tcp#xxx - стандартный клиент RDP
'console - консоль, например из DameWare
'пустая строка - пользователь отключился некорректно
If Rdp <> "сеанс" Then
a = 0
a = a + InStr(User,"admin1") 'Эту учётку трогать низя!
a = a + InStr(User,"admin2") 'Эту учётку трогать низя!
a = a + InStr(User,"admin3") 'Эту учётку трогать низя!
a = a + InStr(User,"admin4") 'Эту учётку трогать низя!
'Остальные учётки проверяем дальше...
If a = 0 then
c = 0
t = 0
p = 0
If OffLine = "отсутствует" then c = c + 1 'Если была закрыта сессия просто крестиком или по какой-либо причине не произошёл выход из системы, то сразу необходимо выкинуть пользователя из сессии!
p = InStr(OffLine,":")
If p > 0 then
t = CDbl(Left(OffLine,p - 1))
If t > 8 then c = c + 1 'Если пользователь не выключает комп на ночь и его сессия простаивает больше 8 часов, то тоже выкидываем из сессии!
End If
If c > 0 then
Reset = "logoff " & Id 'Команду LogOff можно заменить на Reset Session. Кому что больше подходит.
Set objScriptExec2 = WshShell2.Exec(Reset)
Msg = Msg + "Отключен пользователь: " + User + chr(13) + chr(10)
Msg = Msg + "Значения параметров команды QUser для данного пользователя: " + chr(13) + chr(10)
Msg = Msg + " Пользователь: " + User + chr(13) + chr(10)
Msg = Msg + " Сеанс: " + Rdp + chr(13) + chr(10)
Msg = Msg + " ID: " + Id + chr(13) + chr(10)
Msg = Msg + " Статус: " + Status + chr(13) + chr(10)
Msg = Msg + " Бездействие: " + Offline + chr(13) + chr(10)
Msg = Msg + " Время входа: " + TDate + "/" + TTime + chr(13) + chr(10) + chr(13) + chr(10)
k = k + 1
WScript.Sleep 3000 'Это время (в млсек) ждёт скрипт, пока будет исполнена команда Logoff. если паузы не делать, то будет отключен только первый пользователь, а остальных проигнорирует!
End If
End If
End If
Loop
Set objScriptExec = Nothing
Set WshShell = Nothing
Внимание, есть интересная заметка. Данный скрипт идеально работает под Windows Server 2003 и идеально перехватывает оба события (простой по времени и некорректное завершение сессии), но есть большое но! На 2012 сервере данный скрипт работает только по одному событию - простой по времени. Связано это с отличием результата отработки команды quser в разных версиях ОС. На 2008 платформе не удалось проверить пока. Если кто это уже сделал, просьба отпишитесь в коментах. Просьба не судить строго. Для меня это тоже печальная новость, но пока я не нашёл способа решения данной проблемы в виду отсутствия времени. Если у кого есть мысли, которые помогут мне ускорить адаптацию скрипта, то пишем сюда в коменты. Заранее спасибо...
Добавлять комментарии могут только зарегистрированные пользователи. [ Регистрация | Вход ]