Конвейер доставки 1С там, где нет SSH: RDP-диск как транспорт

10.09.26

Разработка - DevOps и автоматизация разработки

Я автоматизировал доставку доработок в базы 1С, к которым можно подключиться только по RDP через шлюз. У меня не было ни SSH, ни WinRM, ни общих папок, ни права устанавливать на сервер свои программы. Каналом связи стал диск рабочей станции, проброшенный в RDP-сеанс, а исполнителем команд служит PowerShell-агент в этом сеансе. В статье расскажу о захвате объектов и помещении изменений в хранилище, динамическом обновлении боевой базы с автоматической остановкой, установке расширений и доступе к базе через MCP по COM без клиента 1С. Ещё разберу несколько неочевидных ограничений платформы и RDP, с которыми столкнулся по ходу работы. Часть из них описана на форумах, а упоминаний о других я не нашёл.

1. Откуда взялась задача

Я работаю с самописной конфигурацией на платформе 8.3 в режиме совместимости 8.2. В ней используются обычные формы, хранилище конфигурации находится на тестовом сервере, а боевой сервер доступен через шлюз удалённых рабочих столов. Рядом есть вторая база, типовая бухгалтерия. Хранилища у неё нет, поэтому доработки доставляются в виде расширения.

До автоматизации мой рабочий цикл выглядел так. Я открывал RDP, вручную обновлял тестовую базу из хранилища в Конфигураторе, захватывал объекты, объединял конфигурацию со своей сборкой, проверял результат, помещал изменения в хранилище и снимал захват. Затем открывал ещё один RDP-сеанс, уже на боевом сервере. Каждая доработка требовала около часа однообразных действий. Невнимательность обходилась дорого: можно было забыть завершить сеансы или объединить не те объекты. При десяти доработках в неделю на эту работу уходила заметная часть времени.

Я посмотрел, какие готовые инструменты есть в открытом доступе:

  • Режим агента Конфигуратора (/AgentMode; обзор, обвязка на Python): платформа принимает команды по SSH. По назначению этот вариант ближе всего к моей задаче, но для него нужен открытый порт на сервере.
  • vanessa-runner (OneScript): обёртка над пакетным Конфигуратором с группами команд cf, cfe, epf, infobase, repo, cluster. Она закрывает весь мой цикл: обновляет конфигурацию из хранилища, захватывает объекты по списку (repo lock --objects), объединяет конфигурацию с .cf по файлу настроек (cf merge --merge-settings), помещает изменения с комментарием (repo commit), снимает захват и связь с хранилищем, управляет сеансами и расширениями, делает выгрузки. На сервере я могу запустить её только вручную в RDP-сеансе или через собственного агента. Поэтому канал доставки команд всё равно пришлось бы разрабатывать. Вызовы Конфигуратора внутри агента можно заменить на vrunner, но тогда на каждом сервере потребуется OneScript. К тому времени мои обёртки уже прошли проверку на рабочем хранилище.
  • deployka (OneScript): loadrepo, loadcfg, dbupdate, session. Проект объявлен устаревшим, вместо него рекомендуют vanessa-runner.
  • Конвейеры на OneScript + Jenkins (типовая сборка) и «1С on demand» с агентом сборки, который запускается по требованию.
  • MCP-серверы для 1С (mcp-1c, MCP:RSV Data, INFATON, Infostart MCP): они обращаются к базе через HTTP-сервис или напрямую из внешнего процесса.

В моих условиях все эти варианты упирались в один вопрос: как запустить инструмент на сервере. Из доступных каналов у меня был только RDP. Открытых портов и WinRM не было, а установить OneScript или агент Jenkins мне не разрешали. Системные администраторы на такие запросы отвечали вежливым отказом.

2. Идея: диск как канал связи

RDP позволяет пробросить в сеанс локальный диск рабочей станции. На сервере он виден как \\tsclient\F. Сервер может читать и записывать файлы на этом диске, а локальным сценариям тот же диск доступен по обычному пути F:\.

На этом и построена схема. В RDP-сеансе на сервере работает PowerShell-скрипт, то есть агент. Раз в несколько секунд он проверяет папку \\tsclient\F\deploy\test\in. Увидев JSON с командой, агент запускает пакетный Конфигуратор, rac или COM, а затем кладёт ответ в формате JSON в папку out. На рабочей станции другой скрипт, оркестратор, записывает команду, ждёт ответ и выводит результат. Мне не понадобились сетевые порты, службы и установка программ. Агент работает, пока в RDP-сеансе открыто окно PowerShell.

 рабочая станция                      RDP-сеанс на сервере 1С
 deploy.ps1 pull  ^72;`54; F:\deploy\test\in\20260907-1015-pull.json
                                      deploy-agent.ps1: rac (снять сеансы)
                                        1cv8 /ConfigurationRepositoryUpdateCfg
                                        1cv8 /UpdateDBCfg
                                        1cv8 /DumpCfg U94; artifacts\snapshot-….cf
 deploy.ps1      `64;^72; F:\deploy\test\out\20260907-1015-pull.json  {status: ok, sha256: …}

Звучит примитивно. Так и есть, и в этом смысл: схема работает на любом Windows-сервере 1С, если есть RDP с перенаправлением диска и PowerShell.

Окно агента в RDP-сеансе на тестовом сервере: запуск, ping и pull с обновлением из хранилища и снимком .cf

Окно агента в RDP-сеансе. Имена машин и баз заменены, тексты платформы и тайминги настоящие.

3. Что умеет агент

Команды появлялись по мере необходимости. За два месяца их набралось около тридцати. Вот основные:

  • Хранилище: pull обновляет тестовую базу и делает снимок .cf; test захватывает объекты по списку и накладывает сборку через MergeCfg; commit помещает версию; unlock отменяет захват; repo-bind и repo-unbind управляют связью базы с хранилищем.
  • Боевая: update-prod -Mode hot|full. Сначала агент делает резервную копию конфигурации. Затем он либо выполняет динамическое обновление без завершения сеансов, либо запускает полное обновление во время выделенного для этого окна. Если динамическое обновление не применилось из-за реструктуризации, агент останавливается и ждёт решения человека. Самостоятельно переходить на full он не будет, поскольку полное обновление затронет сотню работающих людей.
  • База без хранилища: ext-list, ext-dump, ext-install с автоматической резервной копией прежней версии, а также dump-cf и dump-dt.
  • Диагностика: sessions; peek, чтобы посмотреть файл или каталог на сервере; windows, чтобы получить список всех окон 1С, включая модальные диалоги; screenshot; com-check, чтобы проверить доступность базы по COM и собрать подробности для заявки системным администраторам; fetch, чтобы забрать файл с сервера.
  • MCP: mcp-start/mcp-stop/mcp-list. Об этих командах расскажу отдельно ниже.

Вывод оркестратора на рабочей станции: команда test, захват объектов, копирование сборки, MergeCfg, UpdateDBCfg

Команда test на рабочей станции: захват по списку, локальная копия сборки, объединение, применение. Ответ агента печатается целиком.

Перед опасными командами оркестратор выводит заметное предупреждение. Команды test и commit меняют общее хранилище, update-prod обновляет боевую базу, а dump-dt завершает все сеансы. Я запускаю эти команды через ИИ-агента Claude Code. В его инструкциях прямо запрещено выполнять commit и update-prod без моего явного «да».

4. Неочевидные особенности, ради которых стоило написать статью

Эта часть для меня самая полезная. О некоторых особенностях я позже прочитал на форумах, а упоминаний о других не нашёл. Но со всеми сначала познакомился на практике, когда что-то уже переставало работать.

4.1. Файловые операции через \tsclient очень медленны

Первая версия агента записывала лог в папку обмена построчно с помощью Add-Content. Одна строка записывалась около десяти секунд. Теперь лог хранится локально в %TEMP%, а после каждой команды копируется в папку обмена целиком.

Следующая проблема оказалась серьёзнее. MergeCfg обрабатывал сборку размером 54 МБ тридцать минут. Сначала я винил размер конфигурации, но затем запустил тот же MergeCfg с файлом на локальном диске сервера. Операция заняла 22 секунды. При объединении .cf читается многократно, а каждое чтение через перенаправленный RDP-диск обходится дорого. Поэтому теперь агент сначала копирует крупные файлы, в том числе сборки, расширения и снимки, на локальный диск сервера и лишь потом передаёт их платформе. Копирование 54 МБ занимает две с половиной минуты, а весь test выполняется за три с половиной вместо тридцати.

Скорость канала держится примерно на уровне 1 МБ/с. Выгрузка базы размером 17 ГБ передавалась четыре с лишним часа. Поэтому dump-dt оставляет файл на сервере. Затем его можно забрать отдельной командой fetch, причём оркестратор сразу предупреждает, что операция будет долгой.

4.2. Два разных \tsclient в одном сеансе

Однажды мне понадобилось скопировать выгрузку с сервера. Сначала я решил запустить robocopy через com-exec, поскольку агент умеет выполнять на сервере VBScript. Команда завершилась без единой ошибки и сообщила, что файл «скопирован», но на рабочей станции его не оказалось.

Выяснилось, что путь \\tsclient\F для процесса, запущенного через cscript, указывал на другой RDP-сеанс того же пользователя. В тот момент у меня были открыты два сеанса на одном сервере. В результате robocopy записал 16 ГБ на диск другой машины. Теперь файлы копирует сам агент с помощью Copy-Item, а после копирования он сверяет размеры исходного и полученного файлов.

4.3. Закрытое окно Конфигуратора не означает, что сеанс завершён

В теории это очевидно, но на практике легко забыть. Команда ConfigurationRepositoryUpdateCfg останавливается из-за блокировки, хотя кажется, что «никто не работает». Поэтому перед каждой пакетной операцией агент завершает через rac все сеансы базы. В ответе он указывает, сколько сеансов завершено и сколько осталось.

Есть и побочный эффект. Завершение сеансов разрывает COM-соединение демона MCP, если тот подключён к этой же базе. Я добавил в демон одну повторную попытку: он восстанавливает соединение и снова отправляет запрос.

4.4. LoadCfg и UpdateDBCfg в одном запуске платформа не принимает

Команда /LoadCfg file.cfe -Extension Имя /UpdateDBCfg -Extension Имя возвращает «Ошибка в параметрах командной строки». Если выполнить её за два отдельных запуска, всё работает. На выяснение причины у меня ушёл час. В документации я не нашёл описания этого ограничения. На форуме такая тема есть (пакетное обновление расширения из хранилища), но увидел я её уже после.

4.5. Как понять, что динамическое обновление боевой базы не применилось

При активных сеансах и необходимости реструктуризации UpdateDBCfg -Dynamic+ завершается ошибкой исключительной блокировки и печатает список сеансов, которые её держат. Конфигурация при этом остаётся полученной из хранилища, но к базе не применяется, то есть база и её конфигурация расходятся. По одному коду возврата не понять, что именно случилось: нужен монопольный режим или обновление сломалось по другой причине. Поэтому агент считает динамическое обновление применённым только при нулевом коде и строке «Обновление конфигурации успешно завершено» в выводе. Всё остальное он возвращает отдельным статусом «динамика не применилась, стоп» вместе с полным выводом платформы. На всякий случай он ещё ищет в выводе слова «монопол» и «реструктуриз»: нулевой код с такими словами тоже считается стопом. Да, это русская локаль и регулярные выражения. Я проверил такое поведение на работающей боевой базе со 112 сеансами.

Ответ агента на update-prod в режиме hot: динамика не применилась, ошибка исключительной блокировки, список сеансов, стоп

Тот самый стоп: платформа вернула ошибку исключительной блокировки и 112 сеансов, агент не стал переключаться на полное обновление.

4.6. Связь с хранилищем рвётся после перезаливки базы

После того как тестовую базу перезалили из .dt, команда pull стала возвращать ошибку: «Пользователь существующей связи отличается от текущего». В Конфигураторе эту известную проблему решают отключением от хранилища. Пакетно сменить пользователя существующей связи нельзя. Можно только выполнить /ConfigurationRepositoryUnbindCfg -force, а при следующем обновлении привязаться заново. Для этого я добавил команду repo-unbind.

Отвязанная база подводит ещё раз, и уже незаметно: pull на ней завершается успешно, а вот захват падает с пустым «Ошибка захвата объектов в хранилище» — ровно так же, как если бы объект держал коллега. Разбираться в этом посреди доставки неприятно, поэтому теперь агент делает это сам: разбирает текст ошибки платформы, выполняет /ConfigurationRepositoryBindCfg -forceBindAlreadyBindedUser под учётной записью из конфига и один раз повторяет упавший шаг. Замену конфигурации базы хранилищной (-forceReplaceCfg) он включает только внутри pull, где база и так приводится к состоянию хранилища, и никогда на боевой роли. Отдельно связь ставится командой repo-bind.

Одно лечению не поддаётся: отказ «Пользователь уже аутентифицирован в хранилище». Файловое хранилище держит одну сессию на пользователя, и если она залипла, повторный вход отвергается до тех пор, пока сессия не отвалится сама. Помогает либо другая учётная запись, либо ожидание.

4.7. Пакетный Конфигуратор молчит, и это выглядит как зависание

1cv8 DESIGNER в пакетном режиме не пишет в консоль ничего до самого выхода, а Copy-Item не показывает прогресс. В итоге копирование сборки на 55 МБ через канал RDP занимало восемь минут абсолютной тишины, и в эти минуты трудно отличить работу от повисшего процесса. Теперь агент раз в десять секунд переписывает в своём окне строку «шаг: идёт, N с», а крупные файлы копирует потоком и показывает проценты. В файл лога счётчик не идёт: там остаются только начало, четверти и итог.

4.8. Внешняя обработка со старшей платформы без сообщения не открывается на младшей

На рабочей станции установлена платформа 8.3.27, а на сервере 8.3.24. Собранный на рабочей станции файл .epf сервер не открывает и не показывает причину. Только в глубине лога я нашёл сообщение «Неизвестная версия формата 2.20». Поэтому команда build-epf собирает обработку из XML на платформе сервера через LoadExternalDataProcessorOrReportFromFiles.

4.9. Расширение нужно собирать на той версии типовой конфигурации, которая установлена в боевой базе

Команда UpdateDBCfg -Extension завершилась сообщением «Значение контролируемого свойства Тип у объекта … не совпадает со значением в расширяемой конфигурации». Моя копия бухгалтерии для разработки отставала на семь релизов. При этом база осталась в промежуточном состоянии: LoadCfg выполнился, а UpdateDBCfg нет. Помогла автоматическая резервная копия, которую ext-install создаёт перед установкой. Я установил прежнюю версию с -NoBackup, и база вернулась в нормальное состояние. Автоматическую резервную копию можно отключить, но я этого не делаю.

5. Доступ к базе через MCP по COM, без клиента 1С

Параллельно возникла другая задача. Я хотел, чтобы ИИ-агент на рабочей станции мог выполнять запросы только на чтение к боевой базе и помогать с анализом задач. Заказчик не разрешил публиковать на боевой базе HTTP-сервис, и это разумное ограничение.

Я снова использовал файловый канал. Внешняя обработка содержит ядро MCP: разбор JSON-RPC, инструменты execute_query, метаданные и историю изменений. Она открывается во внешнем соединении через V83.COMConnector. Небольшой демон на VBScript передаёт обработке запросы из папки in, а ответы складывает в out. Для работы не нужны окна и клиент 1С, но требуется одна лицензия на внешнее соединение.

Я пробовал обойтись тонким клиентом с /Execute. В обычном приложении ключ /Execute запускает клиент и показывает рабочий стол, однако модуль обработки не выполняется. В управляемом приложении обработка подключается, что видно в журнале регистрации по событию ExternalDataProcessorConnect, но её форма не открывается и автоматический запуск из ПриОткрытии не срабатывает. Обработчик ожидания в клиенте, запущенном в пакетном режиме, тоже не тикает. Из проверенных вариантов сработало COM-соединение.

При настройке COM-соединения я столкнулся ещё с несколькими особенностями:

  • Файл .epf открывает сервер 1С, а не скрипт. Процесс rphost не видит проброшенный \\tsclient, поэтому обработка должна находиться на диске, доступном серверу. Если кластер работает не на той машине, где запущен агент, как в случае с бухгалтерией, путь к файлу приходится вручную задавать в файле настроек.
  • Кэш rphost привязан к пути к файлу. Я перезаписал .epf под прежним именем, но сервер продолжил загружать старую редакцию. Новые методы возвращали COM-ошибку 438 «Object doesn't support this property or method», хотя в файле они были. Поэтому при обновлении обработки я меняю имя файла.
  • При позднем связывании PowerShell получал от объектов 1С $null вместо значений свойств. Поэтому работу через COM я написал на VBScript.
  • В VBScript нет CallByName, он есть в VBA. Кроме того, VBScript не вызывает методы с кириллическими именами. Поэтому точка входа обработки названа латиницей, ProcessMCPRequest, а для ядра с кириллическим именем сделана экспортная обёртка.
  • Лицензии. На боевой бухгалтерии с двумя десятками пользователей второе внешнее соединение уже возвращает «Не обнаружено свободной лицензии». Поэтому я не держу запущенными лишние демоны.

Я не включил ядро MCP в репозиторий: у каждого оно своё, а на Инфостарте есть несколько готовых вариантов, от mcp-1c до INFATON. Демону и агенту нужен от обработки только один экспортный метод.

6. Что не вошло и что пока не решено

  • Сборка release.cf из исходников. Я использую ibcmd config import files --partial --no-check поверх снимка хранилища, но эта тема заслуживает отдельного рассказа. Например, LoadConfigFromFiles -files <манифест> в Конфигураторе успешно завершается, но добавляет ноль новых объектов. Возможно, я вернусь к этому в следующей статье.
  • Агент работает, пока существует RDP-сеанс. Если отключиться от сеанса, агент продолжит работать, но перезагрузка сервера его остановит. Скрипт rdp-open.ps1 умеет открыть сеанс и запустить через Win+R сценарий запуска, используя SendKeys. Такой обходной путь нельзя считать надёжным решением.
  • В папке обмена нет аутентификации. Команды может отправлять тот, у кого есть доступ на запись к диску рабочей станции. В моих условиях это приемлемо, поскольку диск принадлежит мне.
  • Агент разбирает тексты платформы в русской локали.
  • Вызовы Конфигуратора внутри агента можно передать vanessa-runner. Агент тогда останется каналом доставки, а repo lock, cf merge, repo commit и остальные операции выполнит vrunner. Для этого политика сервера должна разрешать запуск портативного OneScript. В моём окружении я такой вариант не проверял, поскольку собственные обёртки к тому времени уже работали.

7. Итог

За полтора месяца с помощью конвейера я сорок раз поместил изменения в хранилище и восемь раз обновил боевую базу. В это число вошли полные обновления с завершением сеансов. Вместо часа однообразных действий я теперь запускаю четыре команды и один раз проверяю результат в тестовой базе вручную.

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

Код: https://github.com/ShcherbakovP/1c-deploy-agent, лицензия MIT. В репозитории лежат агент, оркестратор, сценарий запуска, демон COM и README со списком ограничений, с которыми я столкнулся на практике.

Вступайте в нашу телеграмм-группу Инфостарт

RDP tsclient конвейер доставки хранилище конфигурации пакетный Конфигуратор UpdateDBCfg динамическое обновление MergeCfg ConfigurationRepositoryLock расширения PowerShell rac COM-соединение V83.COMConnector MCP внешняя обработка автоматизация обновления DevOps 1С боевая база RD Gateway

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Системный администратор Разработчик 1С 8.3 1С 8.5 Бесплатно (free)

В прошлой статье у ERP оставалось 89 отказов загрузки, у ЗУП — 19. Теперь обе конфигурации совпали с эталонами, а собранные файлы прошли круг через платформу. Развертка выделена в открытый репозиторий cf-unwrapper: библиотека на Rust и консольная утилита. Показываю результаты, объясняю границы «100%» и приглашаю к проверкам и развитию проекта.

02.11.2026    233    oyti    1    

1

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Разработчик 1С:Предприятие 8 Россия Бесплатно (free)

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

02.11.2026    466    vanya_gonchar    2    

5

Файловый обмен (TXT, XML, DBF), FTP DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Системный администратор Разработчик 1С 8.5 Бесплатно (free)

В прошлой статье я выгрузил Бухгалтерию в XML байт в байт и спросил, на чем проверить дальше. Вы ответили: ERP, старые релизы, зарплата. Прогнал пять конфигураций, от клиента ЭДО до ERP на 120 тысяч файлов. Рассказываю, что сломалось после Бухгалтерии, почему эталону платформы нельзя верить на слово, как выгрузить одну конфигурацию в формат трех версий платформы - и почему cf-конвертер становится отдельным продуктом, Разверткой.

02.11.2026    310    oyti    2    

3

Инструментарий разработчика DevOps и автоматизация разработки Разработчик 1С 8.3 Абонемент ($m)

Как отличить срочное исправление от обычного вечернего коммита? Проверила расчёт показателей поставок по отчёту хранилища 1С и истории двух открытых проектов. На стенде счётчики совпали со сценарием, а в выборке открытого проекта правило «те же объекты» ошиблось во всех шести случаях. Показываю границы такого замера и отличие от метрик DORA. Прилагаются инструмент и материалы опыта.

1 стартмани

29.10.2026    303    Ninel_S    0    

0

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Файловый обмен (TXT, XML, DBF), FTP Системный администратор Разработчик 1С 8.5 Бесплатно (free)

Выгрузка типовой Бухгалтерии в XML через базу занимает больше четырёх минут. Я написал движок, который читает файл конфигурации напрямую и выгружает его за 35 секунд, совпадая с выгрузкой платформы байт в байт во всех 90 385 файлах. Загрузка обратно тоже работает: круг через платформу совпадает полностью. Рассказываю, как ускоряли, как проверяем и что при загрузке XML теряет сама платформа. А в конце спрашиваю, нужно ли это кому-то, кроме меня, и на какой конфигурации проверить следующей.

27.10.2026    880    oyti    20    

16

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Разработчик 1С 8.3 Абонемент ($m)

Хук pre-commit проверяет полный снимок индекса Git в отдельной базе 1С. На «Нано-УТ» и платформе 8.3.27 повторила 12 попыток коммита: восемь прошли, четыре остановлены. Чистый коммит занял 31,8 с. Вызов несуществующего метода общего модуля хук останавливает только с ключом -ExtendedModulesCheck. В архиве версия 2, тесты, инструкция и журналы.

1 стартмани

26.10.2026    341    Ninel_S    2    

-1

Нейросети DevOps и автоматизация разработки Разработчик 1С 8.3 Абонемент ($m)

Я дала агенту Claude Code задачу словами: добавить в учебную конфигурацию документ «Внутреннее потребление товаров», который списывает товар по средней стоимости и не даёт уйти в минус. Три запуска с нуля, каждый принят проверкой на платформе 1С: 1 мин 49 с, 2 мин 33 с и 2 мин 56 с. Показываю, что агент поменял, где ошибался и почему на типовой УТ так быстро не будет.

1 стартмани

26.10.2026    598    Ninel_S    0    

-1

Нейросети DevOps и автоматизация разработки Разработчик 1С 8.3 Бесплатно (free)

ИИ пишет код на 1С все быстрее, а разработчик по-прежнему носит вопросы, ответы и статусы между чатом с агентом, аналитиком и архитектором. Показываю другой подход и демо-стенд: задача из Яндекс Трекера сама идет по этапам, ИИ-агент работает в GitLab CI, а люди только утверждают спецификацию, архитектуру, план и код. Живой пример задачи от заявки до merge, честный отказ агента, права агента, время и стоимость: вся задача обошлась в 68 центов.

22.10.2026    717    maxrubtsoff    1    

3
Для отправки сообщения требуется регистрация/авторизация