Что нового

Завершение сеансов пользователей с помощью Autoit

jokemas

Новичок
Сообщения
5
Репутация
0
Добрый день,

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

До этого использовал батник:
Код:
@cd c:\BAT-files
@echo off
echo ----STEP 0----
echo Connect into the server for search users
echo ----------------------------------------------
setlocal enabledelayedexpansion
:: Имя сервера
set server=server-1c
:: Имя пользователя, сеанс которого нужно завершить
set user1=oficeman-co
set user2=eksandinova
set user3=operman
set user4=imalinskaya
set user5=ishkirya
set user6=ngornykh
set user7=sbabenkova
set user8=trainee
set user9=flowers-world
set user10=financier-pl-co
set user11=catman1-pl-co
set user12=catman2-pl-co
set user13=logistic-pl-co
set user14=catman3-pl-co
set user15=FirstManPL
set user16=SecondManPL
set user17=ThirdManPL
set user18=skladPL
set user19=BuhPL
set user20=svk-pl
set user21=users
set user22=work_out
set user23=work-out
set user24=receptionPL
set user25=managerPL
set user26=pricer-pl-co
set user27=kassa
set user28=Users
set user29=buhPL
set user30=guru-merchandiser
set user31=st.cashier
set user32=guru-marketing
echo ----------------------------------------------
echo ----Successfully connection----
echo ----------------------------------------------
echo----STEP 1----
echo sending message for all users
echo ----------------------------------------------
echo ----------------------------------------------
echo ----STEP 2----
echo Disconnecting users from the server
echo ----------------------------------------------
:: Поиск ID сеанса и его отключение от сервера
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user1%"') do (
  logoff %%i /server:%server% && echo The session "%user1%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user2%"') do (
  logoff %%i /server:%server% && echo The session "%user2%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user3%"') do (
  logoff %%i /server:%server% && echo The session "%user3%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user4%"') do (
  logoff %%i /server:%server% && echo The session "%user4%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user5%"') do (
  logoff %%i /server:%server% && echo The session "%user5%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user6%"') do (
  logoff %%i /server:%server% && echo The session "%user6%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user7%"') do (
  logoff %%i /server:%server% && echo The session "%user7%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user8%"') do (
  logoff %%i /server:%server% && echo The session "%user8%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user9%"') do (
  logoff %%i /server:%server% && echo The session "%user9%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user10%"') do (
  logoff %%i /server:%server% && echo The session "%user10%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user11%"') do (
  logoff %%i /server:%server% && echo The session "%user11%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user12%"') do (
  logoff %%i /server:%server% && echo The session "%user12%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user13%"') do (
  logoff %%i /server:%server% && echo The session "%user13%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user14%"') do (
  logoff %%i /server:%server% && echo The session "%user14%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user15%"') do (
  logoff %%i /server:%server% && echo The session "%user15%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user16%"') do (
  logoff %%i /server:%server% && echo The session "%user16%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user17%"') do (
  logoff %%i /server:%server% && echo The session "%user17%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user18%"') do (
  logoff %%i /server:%server% && echo The session "%user18%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user19%"') do (
  logoff %%i /server:%server% && echo The session "%user19%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user20%"') do (
  logoff %%i /server:%server% && echo The session "%user20%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user21%"') do (
  logoff %%i /server:%server% && echo The session "%user21%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user22%"') do (
  logoff %%i /server:%server% && echo The session "%user22%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user23%"') do (
  logoff %%i /server:%server% && echo The session "%user23%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user24%"') do (
  logoff %%i /server:%server% && echo The session "%user24%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user25%"') do (
  logoff %%i /server:%server% && echo The session "%user25%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user26%"') do (
  logoff %%i /server:%server% && echo The session "%user26%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user27%"') do (
  logoff %%i /server:%server% && echo The session "%user27%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user28%"') do (
  logoff %%i /server:%server% && echo The session "%user28%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user29%"') do (
  logoff %%i /server:%server% && echo The session "%user29%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user30%"') do (
  logoff %%i /server:%server% && echo The session "%user30%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user31%"') do (
  logoff %%i /server:%server% && echo The session "%user31%" was successfully completed
)
for /f "tokens=3,* delims= " %%i in ('qwinsta /server:%server% ^| find "%user32%"') do (
  logoff %%i /server:%server% && echo The session "%user32%" was successfully completed
)
echo ----------------------------------------------
echo ----Users successfully disconnected----
echo ----------------------------------------------
echo ----STEP 3----
echo Turning off User Account
echo ----------------------------------------------
net user "%user1%" /active:no &&  echo The accaunt "%user1%" was successfully disable
net user "%user2%" /active:no &&  echo The accaunt "%user2%" was successfully disable
net user "%user3%" /active:no &&  echo The accaunt "%user3%" was successfully disable
net user "%user4%" /active:no &&  echo The accaunt "%user4%" was successfully disable
net user "%user5%" /active:no &&  echo The accaunt "%user5%" was successfully disable
net user "%user6%" /active:no &&  echo The accaunt "%user6%" was successfully disable
net user "%user7%" /active:no &&  echo The accaunt "%user7%" was successfully disable
net user "%user8%" /active:no &&  echo The accaunt "%user8%" was successfully disable
net user "%user9%" /active:no &&  echo The accaunt "%user9%" was successfully disable
net user "%user10%" /active:no &&  echo The accaunt "%user10%" was successfully disable
net user "%user11%" /active:no &&  echo The accaunt "%user11%" was successfully disable
net user "%user12%" /active:no &&  echo The accaunt "%user12%" was successfully disable
net user "%user13%" /active:no &&  echo The accaunt "%user13%" was successfully disable
net user "%user14%" /active:no &&  echo The accaunt "%user14%" was successfully disable
net user "%user15%" /active:no &&  echo The accaunt "%user15%" was successfully disable
net user "%user16%" /active:no &&  echo The accaunt "%user16%" was successfully disable
net user "%user17%" /active:no &&  echo The accaunt "%user17%" was successfully disable
net user "%user18%" /active:no &&  echo The accaunt "%user18%" was successfully disable
net user "%user19%" /active:no &&  echo The accaunt "%user19%" was successfully disable
net user "%user20%" /active:no &&  echo The accaunt "%user20%" was successfully disable
net user "%user21%" /active:no &&  echo The accaunt "%user21%" was successfully disable
net user "%user22%" /active:no &&  echo The accaunt "%user22%" was successfully disable
net user "%user23%" /active:no &&  echo The accaunt "%user23%" was successfully disable
net user "%user24%" /active:no &&  echo The accaunt "%user24%" was successfully disable
net user "%user25%" /active:no &&  echo The accaunt "%user25%" was successfully disable
net user "%user26%" /active:no &&  echo The accaunt "%user26%" was successfully disable
net user "%user27%" /active:no &&  echo The accaunt "%user27%" was successfully disable
net user "%user28%" /active:no &&  echo The accaunt "%user28%" was successfully disable
net user "%user29%" /active:no &&  echo The accaunt "%user29%" was successfully disable
net user "%user30%" /active:no &&  echo The accaunt "%user30%" was successfully disable
net user "%user31%" /active:no &&  echo The accaunt "%user31%" was successfully disable
net user "%user32%" /active:no &&  echo The accaunt "%user32%" was successfully disable
echo ----------------------------------------------
echo ----Successfully disable all users----
echo ----------------------------------------------
exit

Начал "играться" с autoit, стараясь получить аналогичный эффект, как в батнике вверху, но уперся в то, что не могу с помощью Run(@ComSpec, "") реализовать эти команды.
В файле указываются имена пользователей построчно. Их я выдергиваю в переменную и хочу в цикл запихнуть команду, которая будет отрубать всех пользователей до тех пор, пока не вырубит всех из файла.
Там в коде есть строчка закоментированная, которая должна рубить всех сетевых, но это не подходит, так как франшиза 1С работает так же через RDP и их рубить нельзя.

Код:
;Подключаем необходимые модули
#include <file.au3>
;Открываем файы и присваиваем их переменным
$hClient = FileOpen(@ScriptDir & '\сlients.txt', 0)
$hServer = FileOpen(@ScriptDir & '\Server.txt', 0)
;получаем количество строк в файлах
$hClientCount = _FileCountLines(@ScriptDir & '\сlients.txt')
$hServerCount = _FileCountLines(@ScriptDir & '\server.txt')
;Проверяет, является ли файлы открытым, перед тем как использовать функции чтения/записи в файл
If $hClient = -1 Then
    MsgBox(4096, "Ошибка", "Не могу открыть Файл clients.txt.")
    Exit
EndIf
If $hServer = -1 Then
    MsgBox(4096, "Ошибка", "Не могу открыть Файл server.txt.")
    Exit
EndIf
;Запускаем цикл отключающий пользователей, используя переменные полученые выше.
For $i = 1 to $hClientCount Step 1
	$ServerName = FileReadLine(@ScriptDir & '\Server.txt', 1)

	MsgBox(0, "Сеанс пользователя завершен", FileReadLine(@ScriptDir & '\сlients.txt', $i), 0.5)
 ;Run(@ComSpec & " /c " & 'net session \\' & $ServerName & ' /delete', "", @SW_HIDE)
Next
;Закрываем ранее открытые файлы
FileClose($hClient)
FileClose($hServer)

MsgBox(0, "Обработано пользователей", $hClientCount,10)

;Проверочные сообщения
;MsgBox(0, "Содержимое 1-ой строки 1 файл", FileReadLine(@ScriptDir & '\сlients.txt', 1), 1)
;MsgBox(0, "Содержимое 1-ой строки 2 файл", FileReadLine(@ScriptDir & '\server.txt', 1), 1)
;MsgBox(0, "во 2 файле количество строк", $hServerCount,1)


У меня глаза от количества кавычек уже в не различают иных символов.
Может есть какая функция самого AutoIt способная облегчить эту задачу?
 

ildar

Осваивающий
Сообщения
252
Репутация
29
насколько я понимаю
Код:
Run(@ComSpec & " /c " & 'net session  /delete', "", @SW_HIDE)
закроет только все открытые сессии, RDP нетрогает
 
Автор
jokemas

jokemas

Новичок
Сообщения
5
Репутация
0
Поэтому и закоментировано, что не подходит. Пробую сейчас, все же, прикрутить команду из батника, ковыряя кавычки. Не вырубает пользователей...

Код:
For $i = 1 to $hClientCount Step 1
	$ServerName = FileReadLine(@ScriptDir & '\Server.txt', 1)
	$ClientName = FileReadLine(@ScriptDir & '\сlients.txt', $i)
    Run(@ComSpec & "for /f " & " tokens=3,* delims= " & " %%i in ('qwinsta /server:" & "%" & $ServerName & "%" & " ^| find "&"%"&$ClientName&"%"&"') do (" & @CRLF & "logoff %%i /server:"&"%"&$ServerName&"%"& @CRLF & ")", @SW_HIDE)
    MsgBox(0, "Сеанс пользователя завершен", "Завершен сеанс: " & FileReadLine(@ScriptDir & '\сlients.txt', $i), 0.5)
Next


Вот так вот сейчас выглядит мой цикл, но отключения пользователей не происходит. Такое ощущение, что команда просто не выполняется.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Зачем через аутоит запускать батник? А если так уж надо то не проще ли
Код:
Run('blabla.bat')
 
Автор
jokemas

jokemas

Новичок
Сообщения
5
Репутация
0
Бантик у меня и так есть.
Каждый раз редактировать батник, добавляя в него пользователей - муторно и долго, да еще и чревато ошибками, так как пользователей в филиалах много и каждого прописывать - долго.
Цель - автоматизировать процесс, убрать ручную "работу" с батником.
Я хочу редаткировать только один текстовый файл - добавляя или удаляя из него имена пользователей, а скрипт в цикле сам будет уже читать эти "переменные" из файла и завершать их, после чего отключать учетные записи на определенное время, а потом включать их.

Эта проблема актуальная для 1С серверов, работающих в терминальном режиме.
Решение проблемы уберет кучу ненужной работы и высвободит время для кучи нужной.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Ясно, но вы почему то пытаетесь на в AutoIt вписать команду, которая должна выполнять в батнике, вот я и спросил.
А по теме, Run(@ComSpec) не нужен. Как я понял, все работу делает команда logoff, секрет в том, что это не команда командной строки, а простой ехе, который лежит в system32 под именем logoff.exe. Запустите его с параметром /? вы увидите следующее:
Код:
>logoff /?
Завершение сеанса.

LOGOFF [<имя сеанса> | <ИД сеанса>] [/SERVER:<сервер>] [/V] [/VM]

  <имя сеанса>      Имя сеанса.
  <ID сеанса>       Идентификатор сеанса.
  /SERVER:<сервер>  Сервер удаленных рабочих столов, содержащий пользователя
                    пользователя (по умолчанию - текущий).
  /V                  Отображение информации о выполненных действиях.
  /VM                 Завершение сеанса на сервере или в виртуальной машине. Необходимо указать уникальный идентификатор сеанса.
Значит, вам нужно первым параметром передать имя сеанса или ИД сеанса, вторым /SERVER:имя сервера.
Вот и запускайте его:
Код:
Local $client = 'sbabenkova', $server = 'bigboss'
Local $cmd = StringFormat('logoff.exe %s /SERVER:%s', $client, $server)
MsgBox(0,'Будет запущен следующий exe ', $cmd)
Run($cmd, @SystemDir)
 
Автор
jokemas

jokemas

Новичок
Сообщения
5
Репутация
0
Спасибо за наводку,
поковырял logoff со всех сторон, сеансы завершать не хочет, хотя все и делается из под админа.
Синтаксис такой:
Код:
logoff.exe user /server:server
или
Код:
logoff user /server:server

пишет, что сеанс с именем не найден.
Пробовал учитывать регистр, не взлетает

Если же использовать ID, то рубит все отлично
Код:
logoff 1
Код:
logoff.exe 1

:stars:
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
А имя сеанса совпадает с именем пользователя?
Видимо нет, тогда все сеансы можно получить командой qwinsta, разобрать вывод, получить ID, но это какой то уже костыль.
 
Автор
jokemas

jokemas

Новичок
Сообщения
5
Репутация
0
Ну, собственно говоря, в батнике qwinsta и используется.
Всего то, нужно данные из нее взять, найти по имени ID и завершить сеанс используя ID...
Т.е. тоже самое, что делает батник.


Добавлено:
Сообщение автоматически объединено:

Смог получить от qwinsta данные:
Код:
Global $ServerName = FileReadLine(@ScriptDir & '\Server.txt', 1)
Local $Proc = Run(@ComSpec & " /c qwinsta /server:"&$ServerName, @ScriptDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
 While 1
                   Sleep(1000)

                    Local $WinStaResult = StdoutRead($Proc)
                    If $WinStaResult <> "" Then
                        MsgBox(0, "В файл будет записано:", $WinStaResult)
                        FileWriteLine(@ScriptDir & "\" & "test.log", $WinStaResult)
                    EndIf
                    ExitLoop
                WEnd

Записал их файл и память...
Теперь нужно сопоставить имена из файла с именами из test.log и взять ID для убивания сеанса... Начать да кончить :stars:


Добавлено:
Сообщение автоматически объединено:

Все, домучил.
Ларчик не сложно открывался, код не очень красивый, куча преобразований =). Краткость здесь вообще ни разу не сестра таланта =)

И так. Кому нужно - забирайте, полностью рабочий скрипт, проверял на Windows 7, 8.1, 10, server 2008 r2.
В файлах из которых читает данные, нужно записывать значения - каждое значение со новой строки (Имя пользователя,сервера)

Для удобства все с комментариями.
Код:
;Подключаем необходимые модули
#include <Constants.au3>
#include <file.au3>
#include <Encoding.au3>
#include <Array.au3>
#include <FileConstants.au3>

;Открываем файлы и присваиваем их переменным
$hClient = FileOpen(@ScriptDir & '\сlients.txt', 0)
$hServer = FileOpen(@ScriptDir & '\Server.txt', 0)
;получаем количество строк в файлах
$hClientCount = _FileCountLines(@ScriptDir & '\сlients.txt')
$hServerCount = _FileCountLines(@ScriptDir & '\server.txt')
;Проверяет, является ли файлы открытым, перед тем как использовать функции чтения/записи в файл
If $hClient = -1 Then
    MsgBox(4096, "Ошибка", "Не могу открыть Файл clients.txt.")
    Exit
EndIf
If $hServer = -1 Then
    MsgBox(4096, "Ошибка", "Не могу открыть Файл server.txt.")
    Exit
EndIf
;Читаем в память данные о сеансах
Global $ServerName = FileReadLine(@ScriptDir & '\Server.txt', 1)
Local $Proc = Run(@ComSpec & " /c qwinsta /server:"&$ServerName, @ScriptDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
While 1
                   Sleep(1000)
                    Local $WinSta = StdoutRead($Proc) ;забираем значение из консоли в память
					;Преобразуем данные в читабельный формат
					Local $text1 = StringStripWS($WinSta,4); убираем лишние пробелы между словами.
					Local $text2 = StringStripWS($text1,1);убираем пробелы начала строки
					Local $text3 = StringStripWS($text2,2);убираем пробелы конца строки
					local $sPattern = ' '; ищем оставшиеся пробелы между словами
					local $text4 = StringRegExpReplace($text3, $sPattern, ';'); меняем пробелы между словами на разделитель
					Local $text6 = StringSplit($text4, ';'); превращаем строку в массив подстрок, используя разделитель
					;_ArrayDisplay($text6); выводим массив на экран
					;Запускаем цикл отключающий пользователей
					Global $result ;вводим результирующую переменная
						For $word = 1 to $hClientCount ;цикл использущий имена сеансов из файла
							$ClientName = FileReadLine(@ScriptDir & '\сlients.txt', $word); получаем имена из файла в переменную
							For $j = 1 to $text6[0] ;цикл проверяющий строки одномерного массива
								if $text6[$j] = $ClientName Then $result = $text6[$j+1] ;условие проверяющиее совпадение имени из файла с именем из массива,
								;Если совпало, прибавляем к счетчику один (получаем ID), результат присваиваем результирующей переменной
								Local $cmd = StringFormat('logoff.exe '& $result& ' /SERVER:'& $ServerName);прописываем команду для отключения пользователя
							Next
						;	MsgBox(0, "Отключение сеансов", "Завершен сеанс: " & $cmd, 10)
							Run($cmd,@SystemDir);запускаем команду в работу
							Next
                    ExitLoop
                WEnd
;Создаем двумерный массив из логина и ИД пользователя, где первый столбец логин, а второй ИД.
FileClose($hClient)
FileClose($hServer)


Там еще 2 строчки добавиться - отключение учетных записей, чтобы подключится не могли, и такой же скрипт, но гораздо проще - на включение учетных записей, там ничего искать не надо. Записи включаются просто по имени.

Если кто хочет его оптимизировать и сделать проще =) Не забудьте поделиться =)

РЕШЕНО.
 
Верх