Получить id сессии 1с
Описание проблемы
Методы завершения сессии пользователя не терминале
Существует несколько методов позволяющие выкинуть пользователя с сервера.
- Завершить сессию пользователя (Сделать log off) вы можете из оснастки управления RDS фермой
- Разлогинить пользователя можно и на самом терминальном сервере из диспетчера задач
- Выход пользователя можно выполнить из утилиты командной строки rwinsta
- Утилита командной строки log off
- Утилита reset session
- * Командлет Stop-TSSession
Как выкинуть пользователя из оснастки управления RDS
И так, у меня есть мой любимый, тестовый пользователь в Active Directory, по имени Барбоскин Геннадий Викторович. Предположим, что он зашел на терминальный стол и нам по причине зависания его сессии, нужно сделать ему выход. Первый метод, это использование оснастки по управлению RDS фермой, я вам рассказывал, как ее собирать. Открываем раздел с вашей коллекцией RDS фермы. В поисковом фильтре указываем логин или фамилию нужного сотрудника. В результате получаем хост, где он работает.
Щелкаем по нему правым кликом. В контекстном меню будет пункт "Выйти", это и соответствует завершению сессии (Log off). Так же есть пункт "Отключиться", если выберите его, то пользователь будет выброшен с терминального сервера, но его сессия останется на нем, данная операция равносильна тому, если пользователь просто нажал в окне с названием терминального сервера крестик.
Второй метод разлогинить пользователя на терминальном сервере
Второй метод, похож на первый, за исключением того, что нам необходимо залогиниться на нужный сервер, открыть оснастку "Диспетчер задач" и уже из него произвести выход пользователя. Сказано сделано, о том, как вам попадать на нужного участника RDS фермы я рассказывал. Далее щелкаем правым кликом по области пуска и из контекстного меню выбираем пункт "Диспетчер задач". Кстати, вызвать "Диспетчер задач" можно и через сочетание клавиш CTRL+SHIFT+ESC.
Находим нужного нам пользователя и щелкаем по нему правым кликом, в контекстном меню. нас будет интересовать пункт "Выйти". Выбираем его и завершаем сессию пользователя.
Бывает так, что первые два метода не помогают в случаях, когда пользовательская сессия зависает на терминальном сервере, вы вроде бы из графического интерфейса делаете выход, но оно не отрабатывает. В таких случаях нужно использовать утилиты командной строки или PowerShell
Использование утилиты 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. Далее пишем
Соглашаемся с тем, что будет производиться log off для данного пользователя. Проверяем, что сессия завершена. Можно вот таким простеньким скриптом из планировщика задач, разлогинивать сессии:
Import-Module PSTerminalServices
Get-TSSession -ComputerName SERVER_NAME -filter | Stop-TSSession –Force
Выход пользователя через командлет Stop-TerminalSession
Данный командлет устанавливается отдельно, совместно с пакетом Pscx. Первым делом посмотрим локально или удаленно идентификаторы сессии пользователя, для которого мы хотим сделать log off. Выполняем команду:
Нужный мне ID сеанса 427. Далее воспользуемся командлетом Stop-TerminalSession, чтобы выкинуть пользователя и завершить его сессию.
У которого запущен процесс 1С?
Или давая пользователям 1С такие же имена как в ОС.
Или прикручивая собственные костыли в 1С. Типа определять имя текущего пользователя в ОС, потом в 1С, и записывать все это дело в какой нибудь регистр сведений.
Нормальных средств для файловой базы в терминале нет
Все базы файловые.
Есть несколько вариантов того, как работают пользователи -
1 Пользователи под уникальными именами заходят в терминальной сессии(UserTS) и работают под одним пользователем(User1С) в одной базе в 1С
2 Пользователи под уникальными именами заходят в терминальной сессии и открывают каждый свою уникальную базу в 1С.
Проблема 1
Как при варианте 1 узнать какой UserTS сидит в известной базе как User1С. Т.к. User1С у все одинаковый получается что в базе сидят 10 например пользователей User с уникальными ID.
Проблема 2
Как при варианте 2 узнать какой UserTS сидит в какой базе 1С.
Пока знаю только 1 вариант решения по проблеме 2 - Искать все строки открытых хендлов где присутствует .1CD искать в именах открытых файлов всех хендлов где присутствует .1CD, это путь к базе, а этот открытый файл в процессе 1Сv8.exe(или другой в зависимости от толстый\тонкий клиент) . Смотреть на того, кто запустил этот процесс.
Пока знаю только 1 вариант решения по проблеме 2 - Искать все строки открытых хендлов где присутствует .1CD искать в именах открытых файлов всех хендлов где присутствует .1CD, это путь к базе, а этот открытый файл в процессе 1Сv8.exe(или другой в зависимости от толстый\тонкий клиент) . Смотреть на того, кто запустил этот процесс.
Хотел сразу тебе это посоветовать, но не думал что тебе это НАСТОЛЬКО необходимо.
Есть путь попроще, с доработкой 1С, как я писал выше - с определением пользователей и записью куда нить в 1С. Потом используя внешнее соединение собирать данные о пользователях со всех баз. Хотя, кому как проще.
В твоем варианте с хендлами не нужно вносить изменения в 1С, т.е. не будет зависимости от конфигурации - универсальная консоль получится. Кстати, если напишешь - поделишься? Время от времени тоже есть необходимость определять кто завис в базе.
Думаю сделаю без проблем.
Вот возник технический вопрос.
Я правильно понимаю:
При открытии Базы, данные пользователя базы(если был выбран) + имя ПК + дата и т.д. записываются в таблицу в базу данных. В системе данные нигде не фигурируют?
Навскидку данные о пользователях хранятся в таблице Params и v8users. Подробнее надо гуглить, давно там не ковырялся.
Я узнал как найти имя пользователя 1С, который вошел в конкретную базу. Опять-же уже имея путь к базе и имя пользователя системы.
1 Прочитать файл
C:\Documents and Settings\User\Application Data\1C\1CEStart\ibases.v8i
2 найти ID базы по Connect=File="H:\База 8.2 test";
ID=5247b911-765f-4e91-8455-41018103f9c7
3 зайти в папку
C:\Documents and Settings\User\Application Data\1C\1Cv82\5247b911-765f-4e91-8455-41018103f9c7
Осталось лишь реализовать программно, и будет мега тулза для терминального сервера.
Собственно вот:
Я решил пока не заморачиваться с процессами, сделал все проще - Мы знаем имя пользователя из пути к профилю,мы знаем о открытии базы по .lсk.
Минусы:
- Открытые базы завершенные "резетом" и не открытые снова считаются как открытые, т.к. файл .lсk остается.
- Если пользователя переименовали, а профиль остался старый - будет неверное имя пользователя
- Если 1 пользователь зашел под разными именами в 1 базу, будет показано последнее имя под которым он заходил
- не стал заморачиваться сохранением конфигов.
- не стал автоматом настраивать пути
Прикреплённый файл 1___user_finder_RAD_2010.rar (362,01 Кбайт, скачиваний: 227)
Прежде чем начать
Как тестовый пример будем рассматривать описание API банка «Приватбанк». Детально описание можно найти по ссылке. Данный пример хорош тем, что затрагивает взаимодействие с пользователем, мобильными номерами (OTP-авторизация, правда не во всех случаях), а так же имеется разграничения прав как на уровне приложения так и на уровне доступной роли клиента. Даже беглое описание, наверное, вызывает определенные сложности в оценке времени на разработку, а так же вопросы по поводу организации кода.
Анализируем шаги авторизации
Весь процесс состоит из четырех последовательных шагов:
Определим объекты которые будут необходимы:
- Id — идентификатор сессии;
- ExpiresIn — дата в формате Unix Timestamp, когда истечет сессия;
- ApplicationId — идентификатор приложения;
- ApplicationSecret — секрет приложения;
- Login — логин пользователя;
- Password — пароль пользователя;
- OtpDev — устройство для получения OTP-пароля;
- Otp — OTP-пароль полученный на устройство;
- Роли — таблица ролей доступных сессии.
Срок истечения сессии достаточно мал, получается, что нет смысла выполнять предварительную авторизацию и хранить данные сессии. Логично сохранять только текущую сессию и при каждом запросе к W eb-сервису банка проверять валидность сессии и необходимые права доступа к команде сервиса. При надобности обновлять сессию и повышать права к определенному уровню. Теперь можно переходить к псевдокоду.
ШАГ 0. Выбор команды Web-сервиса банка
После предварительного анализа уже понятно, что необходимо для каждого запроса выполнять проверку сессии и если есть потребность проходить авторизацию. Сделаем это с помощью псевдокода для выписок банка:
Происходит очистка объекта в который будет выполнятся загрузка выписок банка, далее создается описание оповещения, которое будет выполнено при актуальной сессии и доступной роли для данной операции (Роль передается как структура в дополнительных параметрах).
ШАГ 1. Получаем ID сессии
После авторизации или валидации приложения, необходимо проверить результат выполнения. Если валидация сессии прошла успешно и роль для вызова операции Web-сервера банка доступна, тогда выполняем запрос на получения полезных данных, иначе переходим на следующий этап авторизации.
ШАГ 2. Авторизация с помощью пары логин/пароль
После авторизации пользователя, необходимо проверить результат выполнения. Если валидация сессии прошла успешно и роль для вызова операции Web-сервера банка доступна, тогда выполняем запрос на получения полезных данных, иначе переходим на следующий этап авторизации.
ШАГ 3. Прохождение OTP-авторизации
ШАГ 4. Проверка OTP-авторизации
На последнем этапе уже нет необходимости создавать описание оповещения для следующего этапе авторизации, этот уже последний.
Если все прошло успешно, будут получены выписки из банка. В случае проблем, ЗначениеВРеквизитФормы использовалось для того что бы формировать вполне симпатичные логи:
10.09.2017 23:36:59:
REQUEST URL
Production Base URL: link.privatbank.ua
Operation: POST /api/auth/createSessionREQUEST BODY
"clientId": "*******",
"clientSecret": "*******"
>10.09.2017 23:36:59:
RESPONSE
10.09.2017 23:36:59: Выполнен запрос авторизации приложения (279 мс).
10.09.2017 23:36:59: OK: Приложение успешно авторизировано.
10.09.2017 23:36:59:REQUEST URL
Production Base URL: link.privatbank.ua
Operation: POST /api/p24BusinessAuth/createSessionREQUEST BODY
"login": "*******",
"password": "*******",
"sessionId": "*******"
>10.09.2017 23:37:00:
RESPONSE
10.09.2017 23:37:00: Выполнен запрос авторизации клиента (1 129 мс).
10.09.2017 23:37:00: Authentication successfull
10.09.2017 23:37:00:REQUEST URL
Production Base URL: link.privatbank.ua
Operation: GET /api/p24b/statements?acc=26006054710862&stdate=10.09.2017&endate=10.09.201710.09.2017 23:37:01:
RESPONSE
<>10.09.2017 23:37:01: Выполнен запрос для получения выписок из банка (552 мс).
10.09.2017 23:37:01: OK: Выписки из банка за указанный период отсутствуют.
Вместо послесловия
Надеюсь, вы заметили шаблон, каждый этап авторизации имеет всего две процедуры или функции: первая процедура предназначена для создания описания оповещения следующего шага авторизации и вызова процедуры/функции/формы текущего шага обработчика, а в самом конце выполняется проверка успешности и переход к получению полезных данных или на следующий шаг авторизации.
Конфигуратор в режиме отладки позволяет выбрать предмет отладки (Тонкий/Толстый клиенты/HTTP-Сервис/Фоновое задание и т.д.), консоль кластера также отображает тип подключения сеанса (колонка "приложение"), ну и наконец стандартная обработка "Активные пользователи" также умеет это делать.
Контекст сеанса 1С хранит в параметре ИмяПриложения соединениий с информационной базой, для того чтобы получить список сеансов текущей информационной базы можно воспользоваться фунцией ПолучитьСеансыИнформационнойБазы(), а номер текущего соединения - НомерСоединенияИнформационнойБазы().
Для простоты и удобства пример функции, которая получает контекст сеанса:
Вызвать функцию можно так:
Реализация, найденная в интернете и не решающая задачу:
Специальные предложения
Кажется, что предложенное решение тоже не до конца справляется.
Например для толстого клиента оно так и не ответит на вопрос - где же я нахожусь. На сервере толстого клиента, или на клиенте.
Но с оговорками да.. вполне себе вариант.
(3)Почему не скажет? Скажет. Проблема только с файловой базой и толстым клиентом. Но. в этом случае "Серверного контекста" НЕ СУЩЕСТВУЕТ - все вызовы идут только под контекстом "Толстого клиента" (под обычным или управляемым приложением), даже, если в указан переход в контекст сервера (например через общи модуль с вызовом сервера) - контекст останется "Толстый клиент". А зачем Вам иное - ведь - реально контекст именно и будет "Толстый клиент" - никакого серверного контекста ВООБЩЕ не будет - будет доступно всё то, что доступно толстому клиенту - т.е. ВСЁ! В отладчике контекст будет "Толстый клиент". Более того, в толстом клиенте игнорируется не только директива "Вызов сервера", но и директива "Сервер" - т.е. будут доступны и функции чисто серверных модулей - прямо с клиента. Так устроена платформа. Вот, для тонкого клиента в файловой базе - контексты уже будут разделены.
А для толстого клиента остаётся только проверить, что он толстый клиент и это файловая база. Это можно проверить ещё и так
Аналогично толстому клиенту, в файловой базе, ведёт себя и внешнее соединение (только вместо директивы "Клиент" отрабатывает директива "ВнешнееСоединение ", а директива "Сервер" по-прежнему отрабатывает, вернее игнорируется - серверный контекст полностью доступен в контексте внешнего соединения без "вызова сервера"). Разве что интерфейсные вызовы не доступны (доступно всё то, что доступно для внешнего соединения).
Что такое ID сеанса
Когда пользователь входит на компьютер с включенными службами удаленных рабочих столов, для него запускается сеанс. Каждый сеанс идентифицируется уникальным идентификатором сеанса. Каждый такой сеанс ассоциируется с интерактивной оконной станцией (interactive window station) "WinSta0"; поэтому каждый сеанс связан со своей собственной оконной станцией "WinSta0". Для каждой оконной станции имеется три стандартных рабочих стола: рабочий стол Winlogon, рабочий стол с заставкой и интерактивный рабочий стол.
Когда пользователь выходит с сервера удаленных рабочих столов (RDC), то сеанс, который клиент имеет на сервере узла сеансов удаленных рабочих столов (ранее назывался сервер терминалов), удаляется. Однако если сеанс консоли служб удаленных рабочих столов не смог завершится, то оконные станции, связанные с сеансом консоли, не удаляются, все процессы продолжают висеть. Это влияет на поведение приложений в среде служб удаленных рабочих столов, когда они настроены для работы в контексте безопасности интерактивного пользователя, также известного как режим активации объекта «RunAs Interactive User». Вот тогда, то и выявляется ID сеанса, чтобы его грохнуть.
Методы определения ID сеанса пользователя RDP
Существует несколько методов, которые могут вам помочь определить номер сеанса и его ID на терминальных серверах и RDS фермах.
- Утилита quser
- Утилита qwinsta
- Утилита Query session
- Оснастка диспетчер задач
- PowerShell командлет Get-TerminalSession
- PowerShell командлет Get-TSSession
Определение ID сеанса через quser
И так у меня есть RDS ферма состоящая из хостов с Windows Server 2012 R2, в базе Active Directory есть пользователь Барбоскин Геннадий Викторович. Данный пользователь вошел на терминал, работал, но по какой-то причине он завис и чтобы корректно разлогинить его сессию нам необходимо вычислить ее номер сеанса и уникальный идентификатор. Попробуем это выполнить через утилиту quser.
QUSER - это утилита командной строки Windows, которая отображает информацию, о пользовательских сессиях на серверах и обычных компьютерах, удобна в случае удаленных рабочих столов. Может получать информацию локально и удаленно.
Вы можете использовать эту команду, чтобы выяснить, вошел ли конкретный пользователь на конкретный сервер Session Host. Команда возвращает:
- Имя пользователя
- Имя сеанса на сервере Session Host
- ID сеанса
- Состояние сеанса (активно или отключено)
- Время простоя (количество минут с момента последнего нажатия клавиш или движения мыши во время сеанса)
- Дата и время входа пользователя
Откройте командную строку cmd, лучше в режиме администратора и введите команду:
У вас будет выведен список всех текущих сессий на вашем терминальном сервере.Если пользователей много, то сложно сразу найти нужного, так как все идет не по алфавиту. Ранее я вам показывал, как фильтровать вывод результатов в командной строке Windows, там была команда findstr. Вводим команду:
Вы наверное спросите, почему сразу так не ввели, все просто, я лишь еще раз напомнил вам, о фильтрации в cmd, которая работает почти с любой командой, так сказать универсальный ключ.
Так же есть возможность запустить для конкретного сервера, для этого есть ключ /server
Определение ID сеанса через qwinsta
QWINSTA - Это утилита командной строки Windows, в задачи которой входит извлечение информации, о пользовательских сессиях на удаленных рабочих столах и выводя много полезной информации.
Для того, чтобы получить номер сеанса с ID, введите в командной строке:
Утилита выведет список всех авторизованных в системе пользователей, из полезной информации вы получите:
Чтобы вывести определенного пользователя, введите команду:
qwinsta barboskin.g или qwinsta " findstr barboskin.g или с ключом /server. qwinsta barboskin.g /server localhost
Как узнать id пользователя через диспетчер задач
Покажу и графический метод. который позволяет вам получать ID и номер сеанса на терминальных столах. Откройте диспетчер задач и перейдите на вкладку "Пользователи". У вас будет отображен список сотрудников. Тут для удобства их можно выстроить по алфавиту. Все хорошо, но нет ID и номера сеанса.
Чтобы включить отображение нужных нам столбцов, вам необходимо щелкнуть правым кликом на область с именем столбцов. В контекстном меню поставьте галки на "Код" и "Сеанс".
Как узнать id пользователя через query session
QUERY SESSION - это утилита командной строки так же выводящая информацию, о вошедших в систему пользователей. Вводите в командной строке query session, вывод утилиты копия qwinsta. Вы так же будите видеть номер сеанса, логин учетной записи, ID, статус подключения.
Получение информации о сеансе через Get-TerminalSession
PowerShell не зря называют могучим, он поистине может все. К сожалению родных командлетов, которые бы заменяли утилиты командной строки нет, но есть возможность установить дополнительные, из репозитория. Речь пойдет, о сборнике "PowerShell Community Extensions" (Pscx 3.2.2). Данный сборник включаем в себя огромный комплекс командлетов, нас будет интересовать Get-TerminalSession.
Установка "PowerShell Community Extensions" очень проста и выполняется одной командой. Перед установкой Pscx 3.2.2, вам необходимо обновить ваш PowerShell хотя бы до версии 5.1. Далее запускаете оболочку PowerShell от имени администратора и вводите команду:
Пишите на терминальном сервере Get-TerminalSession, или же можете запросить удаленно Get-TerminalSession -ComputerName 192 . 168 . 1 . 51
Если у вас не отработает команда для удаленного вывода, то вам необходимо на удаленном компьютере разрешить выполнение скриптов PowerShell
Получение информации о сеансе через Get-TSSession
Модуль PSTerminalServices, так же позволяет взаимодействовать с терминальными профилями В состав PSTerminalServices входят вот такие командлеты:
Установка PSTerminalServices проста до безобразия. На первом экране нажимаем "Next".
При необходимости изменяем путь установки данного модуля.
Для продолжения нажимаем "Install"
Установка модуля завершена.
Теперь, чтобы модуль запускался вам нужно разрешить запуск скриптов, напоминаю, что для текущего пользователя, это можно сделать вот так:
Далее проверьте командой, что модуль PSTerminalServices доступен в системе, выполните:
Далее импортируем модуль и запускаем его:
На выходе вы получаете информацию, о всех ваших сеансах пользователей на терминальном столе
Читайте также: