В процессе администрирования серверов 1С:Предприятия часто возникает необходимость принудительного отключения активных сеансов пользователей. Это может потребоваться для проведения регламентных работ, обновления конфигурации или устранения зависших процессов. Разработчики и системные администраторы стремятся автоматизировать этот процесс, чтобы минимизировать ручное вмешательство и сократить время простоя системы. Давайте рассмотрим, как это можно сделать с помощью VBScript, а также узнаем о других, более современных и мощных инструментах.
Один из распространённых подходов — использование COM-соединения с кластером серверов 1С:Предприятия. Пользователи часто сталкиваются с трудностями при написании таких скриптов, особенно если нет глубоких знаний в VBScript или специфике работы с COM-объектами 1С.
Наш пользователь столкнулся с затруднением при адаптации VBScript-скрипта для отключения сеансов 1С:Предприятия. Скрипт предназначен для работы с COM-соединителем и выполнения административных операций на кластере серверов 1С. Однако при выполнении скрипта возникла ошибка, указывающая на проблему с вызовом метода GetClusters().
Clusters = AgentConnection.GetClusters()
В этом месте скрипт выдал ошибку: "После '(' ожидалось выражение." Это весьма необычное сообщение для метода, который не принимает аргументов. Давайте выясним потенциальные причины этой ошибки и как её исправить.
Проанализировав исходный скрипт и сообщения на форуме, мы можем выделить несколько ключевых моментов, которые могли привести к ошибке и которые необходимо учитывать при работе с COM-объектами 1С:
") на фигурные (« »). VBScript, как и многие другие языки программирования, ожидает именно прямые кавычки для строковых литералов. Фигурные кавычки воспринимаются как неизвестные символы, что может приводить к синтаксическим ошибкам, включая те, что связаны с неожиданными символами вокруг скобок. В нашем случае, пользователь в сообщении 4 получил верный совет проверить кавычки. Это очень важный момент!Set Connector = CreateObject("V83.COMConnector") крайне важно указывать версию COM-объекта, которая соответствует версии установленной на вашем сервере платформы 1С:Предприятия. Если у вас установлена платформа 8.2, то необходимо использовать "V82.COMConnector". Для платформы 8.3 и выше обычно используется "V83.COMConnector". Если версия указана неверно, скрипт не сможет создать объект COM-соединителя, что приведет к ошибкам на самом раннем этапе.AgentConnection.Authenticate Cluster, "UserName", "UserPass" требует внимательности. Здесь необходимо указывать имя пользователя и пароль администратора кластера серверов 1С:Предприятия, а не пользователя информационной базы. Если администратор кластера не был назначен, то эти параметры следует передавать пустыми строками: AgentConnection.Authenticate Cluster, "", "" или закомментировать эту строку, если аутентификация не требуется.GetClusters(): Метод GetClusters() объекта AgentConnection действительно не принимает аргументов. Его вызов AgentConnection.GetClusters() является синтаксически верным. Если вы столкнулись с ошибкой на этой строке, то, скорее всего, причина кроется в предыдущих строках (например, ошибка с кавычками, которая влияет на парсинг всего скрипта) или в некорректной инициализации Connector или AgentConnection.Давайте теперь рассмотрим исправленный и улучшенный VBScript-скрипт, который учитывает вышеперечисленные рекомендации. Этот скрипт поможет нам программно завершать активные сеансы пользователей в кластере 1С:Предприятия.
Прежде чем запускать скрипт, убедитесь, что на сервере, где он будет выполняться, установлена соответствующая версия платформы 1С:Предприятия и зарегистрирован COM-объект. Для регистрации COMConnector обычно достаточно установить клиентскую часть платформы 1С.
Option Explicit
' ***************************************************************
' Параметры подключения к кластеру 1С:Предприятия
' ***************************************************************
' Имя пользователя администратора кластера 1С (если есть, иначе "")
Dim ClusterAdminUserName
ClusterAdminUserName = "ВашАдминКластера"
' Пароль администратора кластера 1С (если есть, иначе "")
Dim ClusterAdminUserPass
ClusterAdminUserPass = "ВашПарольКластера"
' Имя или IP-адрес сервера кластера 1С:Предприятия
Dim ServerName
ServerName = "127.0.0.1" ' Замените на IP-адрес или имя вашего сервера 1С
' Имя информационной базы 1С:Предприятия, сеансы которой нужно отключить
' Если нужно отключить сеансы во всех базах, оставьте пустым ""
Dim BaseNameFilter
BaseNameFilter = "TestTMC" ' Замените на имя вашей базы, например, "УТ11"
' ***************************************************************
' Переменные для работы скрипта
' ***************************************************************
Dim Connector
Dim AgentConnection
Dim Cluster
Dim Clusters
Dim InfoBase
Dim InfoBases
Dim Session
Dim Sessions
' ***************************************************************
' Инициализация COM-соединителя
' ***************************************************************
' Укажите версию платформы 1С: V8, V81, V82, V83
Set Connector = CreateObject("V83.COMConnector")
WScript.Echo "Начало выполнения скрипта."
On Error Resume Next ' Включаем обработку ошибок, чтобы скрипт не прерывался при первой же ошибке
' Подключаемся к агенту сервера 1С
Set AgentConnection = Connector.ConnectAgent(ServerName)
If Err.Number <> 0 Then
WScript.Echo "Ошибка подключения к агенту сервера 1С на " & ServerName & ": " & Err.Description
WScript.Quit
End If
On Error GoTo 0 ' Отключаем обработку ошибок
WScript.Echo "Подключение к агенту сервера успешно."
' ***************************************************************
' Получаем список кластеров
' ***************************************************************
Set Clusters = AgentConnection.GetClusters()
Dim Q
For Q = LBound(Clusters) To UBound(Clusters)
Set Cluster = Clusters(Q)
WScript.Echo " Обнаружен кластер: " & Cluster.Name & " (UUID: " & Cluster.Id & ")"
' Аутентификация администратора кластера (если требуется)
' Если администратор кластера не определен, можно использовать ""
If ClusterAdminUserName <> "" Then
On Error Resume Next
AgentConnection.Authenticate Cluster, ClusterAdminUserName, ClusterAdminUserPass
If Err.Number <> 0 Then
WScript.Echo " Ошибка аутентификации в кластере " & Cluster.Name & ": " & Err.Description
' Продолжаем работу, так как может быть, что админ кластера не установлен
End If
On Error GoTo 0
End If
' Получаем список информационных баз в текущем кластере
Set InfoBases = AgentConnection.GetInfoBases(Cluster)
Dim I
For I = LBound(InfoBases) To UBound(InfoBases)
Set InfoBase = InfoBases(I)
WScript.Echo " Обнаружена информационная база: " & InfoBase.Name & " (UUID: " & InfoBase.Id & ")"
' Проверяем, соответствует ли имя базы фильтру
If BaseNameFilter = "" Or StrComp(InfoBase.Name, BaseNameFilter, vbTextCompare) = 0 Then
' Получаем список сеансов для данной информационной базы
Set Sessions = AgentConnection.GetInfoBaseSessions(Cluster, InfoBase)
Dim ISe
For ISe = LBound(Sessions) To UBound(Sessions)
Set Session = Sessions(ISe)
' Исключаем служебные сеансы, такие как COM-консоль или фоновые задания
If (Session.AppID <> "COMConsole") And (Session.AppID <> "BackgroundJob") Then
On Error Resume Next
AgentConnection.TerminateSession Cluster, Session
If Err.Number <> 0 Then
WScript.Echo " Ошибка отключения сеанса " & Session.Id & " (" & Session.AppID & ", " & Session.UserName & "): " & Err.Description
Else
WScript.Echo " Отключен сеанс: " & Session.UserName & " (" & Session.AppID & "), ID: " & Session.Id
End If
On Error GoTo 0
Else
WScript.Echo " Пропущен служебный сеанс: " & Session.UserName & " (" & Session.AppID & "), ID: " & Session.Id
End If
Next
Else
WScript.Echo " База " & InfoBase.Name & " пропущена (не соответствует фильтру)."
End If
Next
Next
WScript.Echo "Конец выполнения скрипта."
Пояснения к исправленному скрипту:
ClusterAdminUserName, ClusterAdminUserPass, ServerName и BaseNameFilter. Последний параметр позволяет отключить сеансы только в конкретной информационной базе или во всех, если оставить его пустым.On Error Resume Next и If Err.Number <> 0 Then) для более устойчивой работы скрипта. Это позволяет скрипту не прерываться при возникновении незначительных проблем, например, с аутентификацией, а продолжать выполнять свою задачу.Connector.ConnectAgent(ServerName) для установки соединения с агентом сервера 1С.AgentConnection.GetClusters() и AgentConnection.GetInfoBases(Cluster) позволяют получить коллекции всех доступных кластеров и информационных баз в них.AgentConnection.Authenticate Cluster, ClusterAdminUserName, ClusterAdminUserPass. Важно помнить, что это должны быть учетные данные администратора кластера.AgentConnection.GetInfoBaseSessions(Cluster, InfoBase) возвращает все активные сеансы для заданной информационной базы. Мы добавили фильтрацию по AppID, чтобы избежать отключения служебных сеансов, таких как "COMConsole" (ваш собственный скрипт) или "BackgroundJob" (фоновые задания 1С).AgentConnection.TerminateSession Cluster, Session.WScript.Echo: Вместо MsgBox, который требует интерактивного подтверждения, мы используем WScript.Echo для вывода информации в консоль (если скрипт запускается через cscript.exe) или в окно сообщений (если через wscript.exe).Помимо использования VBScript, существуют и другие, более современные и часто более удобные способы управления сеансами пользователей в 1С:Предприятии. Давайте рассмотрим их подробнее.
rac
Утилита rac — это консольный инструмент, который входит в состав сервера 1С:Предприятия. Она предоставляет широкие возможности для администрирования кластера серверов, включая управление информационными базами, рабочими процессами и, конечно, сеансами пользователей. Этот инструмент очень мощный и гибок, особенно для автоматизации через командную строку или скрипты (например, на PowerShell).
rac
Для работы с rac нам потребуется знать уникальные идентификаторы (UUID) кластера и информационной базы. Их можно получить также с помощью команд rac.
Для начала нам нужно узнать ID кластера. Откройте командную строку и выполните:
rac cluster list
В выводе вы увидите список кластеров с их UUID. Пример вывода:
cluster:
host: "server-1c"
port: 1541
id: "a1b2c3d4-e5f6-7890-1234-567890abcdef"
name: "Localhost Cluster"
# ... другие параметры
Запишите id нужного вам кластера.
Теперь, зная ID кластера, мы можем получить список информационных баз в нем. Замените <id_кластера> на UUID, который вы получили на предыдущем шаге.
rac infobase --cluster= list
В выводе вы найдете список баз с их UUID. Пример вывода:
infobase:
id: "f0e9d8c7-b6a5-4321-fedc-ba9876543210"
name: "TestTMC"
# ... другие параметры
Запишите id нужной вам информационной базы.
Имея UUID кластера и информационной базы, мы можем завершить все сеансы в конкретной базе. Используем команду session terminate.
rac session --cluster= --infobase= terminate
Эта команда принудительно завершит все активные сеансы, подключенные к указанной информационной базе. Для более гранулированного управления (например, отключение конкретного сеанса или сеансов определенного пользователя) можно сначала получить список сеансов с помощью rac session --cluster=<id_кластера> --infobase=<id_базы> list, а затем использовать terminate с опцией --session=<id_сеанса>.
Преимущества
rac
PowerShell — это современный, объектно-ориентированный язык сценариев и командная оболочка от Microsoft, который предоставляет гораздо более мощные и гибкие возможности для автоматизации администрирования, чем VBScript. С помощью PowerShell мы также можем использовать COM-объекты 1С, но делать это будет удобнее и безопаснее.
Давайте посмотрим, как можно реализовать отключение сеансов с использованием COM-объектов 1С на PowerShell. Этот скрипт будет более читаемым и гибким.
# ***************************************************************
# Параметры подключения к кластеру 1С:Предприятия
# ***************************************************************
# Имя или IP-адрес сервера кластера 1С:Предприятия
$ServerName = "127.0.0.1" # Замените на IP-адрес или имя вашего сервера 1С
# Имя информационной базы 1С:Предприятия, сеансы которой нужно отключить
# Если нужно отключить сеансы во всех базах, оставьте пустым ""
$BaseNameFilter = "TestTMC" # Замените на имя вашей базы, например, "УТ11"
# Имя пользователя администратора кластера 1С (если есть, иначе "")
$ClusterAdminUserName = "ВашАдминКластера"
# Пароль администратора кластера 1С (если есть, иначе "")
$ClusterAdminUserPass = "ВашПарольКластера"
# ***************************************************************
# Инициализация COM-соединителя
# *****************************************************************
try {
# Укажите версию платформы 1С: V8, V81, V82, V83
$Connector = New-Object -ComObject V83.COMConnector
Write-Host "COM-соединитель успешно создан."
}
catch {
Write-Error "Ошибка создания COM-соединителя: $($_.Exception.Message)"
exit 1
}
# ***************************************************************
# Подключение к агенту сервера 1С
# ***************************************************************
try {
$Agent = $Connector.ConnectAgent($ServerName)
Write-Host "Подключение к агенту сервера на '$ServerName' успешно."
}
catch {
Write-Error "Ошибка подключения к агенту сервера на '$ServerName': $($_.Exception.Message)"
exit 1
}
# ***************************************************************
# Получаем список кластеров
# ***************************************************************
$Clusters = $Agent.GetClusters()
foreach ($Cluster in $Clusters) {
Write-Host "`nОбнаружен кластер: $($Cluster.Name) (UUID: $($Cluster.Id))"
# Аутентификация администратора кластера (если требуется)
if ($ClusterAdminUserName -ne "") {
try {
$Agent.Authenticate($Cluster, $ClusterAdminUserName, $ClusterAdminUserPass)
Write-Host " Аутентификация в кластере $($Cluster.Name) успешна."
}
catch {
Write-Warning " Ошибка аутентификации в кластере $($Cluster.Name): $($_.Exception.Message). Продолжаем без аутентификации."
}
}
# Получаем список информационных баз
$InfoBases = $Agent.GetInfoBases($Cluster)
foreach ($InfoBase in $InfoBases) {
Write-Host " Обнаружена информационная база: $($InfoBase.Name) (UUID: $($InfoBase.Id))"
# Проверяем, соответствует ли имя базы фильтру
if ([string]::IsNullOrEmpty($BaseNameFilter) -or ($InfoBase.Name -eq $BaseNameFilter)) {
# Получаем сеансы для текущей информационной базы
$Sessions = $Agent.GetInfoBaseSessions($Cluster, $InfoBase)
Write-Host " Найдено $($Sessions.Count) сеансов в базе $($InfoBase.Name)."
foreach ($Session in $Sessions) {
# Исключаем служебные сеансы
if ($Session.AppID -ne "COMConsole" -and $Session.AppID -ne "BackgroundJob") {
try {
$Agent.TerminateSession($Cluster, $Session)
Write-Host " Отключен сеанс: $($Session.UserName) (`$($Session.AppID)), ID: $($Session.Id)"
}
catch {
Write-Warning " Ошибка отключения сеанса $($Session.Id) (`$($Session.AppID), $($Session.UserName)): $($_.Exception.Message)"
}
}
else {
Write-Host " Пропущен служебный сеанс: $($Session.UserName) (`$($Session.AppID)), ID: $($Session.Id)"
}
}
}
else {
Write-Host " База $($InfoBase.Name) пропущена (не соответствует фильтру)."
}
}
}
Write-Host "`nКонец выполнения скрипта."
Пояснения к PowerShell-скрипту:
$. Мы используем те же параметры, что и в VBScript.New-Object -ComObject V83.COMConnector для создания COM-объекта. Обратите внимание на использование блока try-catch для обработки возможных ошибок при создании объекта.ConnectAgent(), GetClusters(), GetInfoBases(), GetInfoBaseSessions() работают аналогично VBScript.foreach ($item in $collection) для итерации по коллекциям.-eq (равно), для "не равно" — -ne. Для проверки пустой строки можно использовать [string]::IsNullOrEmpty().WScript.Echo используем Write-Host для вывода сообщений в консоль. Для ошибок и предупреждений доступны Write-Error и Write-Warning.try-catch, что делает скрипты более надежными.Для платформ 1С:Предприятие 8.3 и выше существуют встроенные механизмы, которые позволяют более удобно и безопасно управлять сеансами пользователей, особенно при проведении регламентных работ.
Эта функциональность обычно доступна в режиме "Конфигуратор" или через консоль администрирования серверов 1С.
Администрирование -> Блокировка установления соединений с информационной базой.Преимущества встроенных средств:
Независимо от выбранного метода, при принудительном отключении пользователей всегда следует придерживаться некоторых лучших практик:
rac, должна обладать достаточными правами на сервере 1С:Предприятия. Как правило, это должны быть права администратора кластера. Без этих прав операции по управлению сеансами будут отклонены.AppID), чтобы случайно не отключить служебные процессы. К ним относятся сеансы самого COM-соединения (COMConsole), фоновые задания (BackgroundJob), а также сеансы обновлений (Update) или других системных операций. Принудительное завершение таких сеансов может привести к нестабильной работе системы или повреждению данных. В наших скриптах мы уже включили эту проверку.Таким образом, мы рассмотрели различные способы программного отключения пользователей 1С:Предприятия: от VBScript с его нюансами, до мощных инструментов rac и PowerShell, а также удобных встроенных средств платформы. Каждый метод имеет свои преимущества и недостатки, и выбор конкретного инструмента будет зависеть от ваших задач, навыков и специфики инфраструктуры.