#ПЕРЕМЕННЫЕ
#Параметры запуска: адрес сервера, основной порт кластера, информационная база, логины, пароли
$LoginDB = 'ЛогинБД' #Логин на доступ к базе данных
$PassDB = 'ПарольБД' #Пароль на доступ к базе данных
$LoginHRN = 'ЛогинХранилища' #Логин на доступ к хранилищу конфигурации
$PassHRN = 'ПарольХранилища' #Пароль на доступ к хранилищу конфигурации
$PassUC = 'ПарольUC' #Пароль разрешения на подключение к БД (UC)
$SrvName = 'ИмяСервера' #Имя сервера
$DBName = 'ИмяБазы' #Имя базы данных
$SrvAddr = 'tcp://' + $SrvName + ':1540' #Сетевой путь к серверу БД для подключения
$MainPort = "1541" #Главный порт для подключения к БД
$ComConnector = New-Object -COMObject "V83.COMConnector" #COM коннектор
$Dir = 'C:Program Files1cv8common1cestart.exe' #Путь к файлу запуска 1С
$DirLog = 'D:Scriptslog' #Путь к каталогу журналов ошибок
$OutLog = '/Out"' + $DirLog + 'logFile_1C.txt" -NoTruncate' #Место хранения лога из 1С, каталог LOG должен быть рядом с файлом ps1
#Строковые параметры. Для удобства дальнейшего использования разобрал на параметры и собираем из них нужную последовательность в массивы ниже:
#Путь запуска и параметры запуска
$EntPath = 'ENTERPRISE /s"' + $SrvName + '' + $DBName + '"'
$ConfPath = 'CONFIG /s"' + $SrvName + '' + $DBName + '"'
$PassUCParam = '/UC"' + $PassUC + '"'
#Параметры работы.
$DisableWinAuth = '/WA-'
$DisableUpdateQuestion = '/AU-'
$DisableMasseges = '/DisableStartupMessages'
$DisableUsers = '/C"ЗавершитьРаботуПользователей"'
$EnableUsers = '/C"РазрешитьРаботуПользователей"'
$UpdateFromHRN = '/ConfigurationRepositoryUpdateCfg'
$UpdateDB = '/UpdateDBCfg'
#Доступы к БД и хранилищу
$LoginDBParam = '/n"' + $LoginDB + '"'
$PassDBParam = '/p"' + $PassDB + '"'
$PathHRN = '/ConfigurationRepositoryF"\\' + $SrvName + 'hrnTLE"'
$LoginHRNParam = '/ConfigurationRepositoryN"' + $LoginHRN + '"'
$PassHRNParam = '/ConfigurationRepositoryP"' + $PassHRN + '"'
$WorkBegin = $True
#Собираем параметры в массивы. Шаг 1 и 4 закомментированы, в них производится отключение пользователей через обработку "блокировка работы пользователей" из интерфейса 1С.
#Мы же будем использовать консоль администрирования 1С и устанавливать блокировки через функцию ниже.
#$Step1 = $EntPath,$LoginDB,$PassDB,$DisableWinAuth,$DisableUpdateQuestion,$DisableMasseges,$DisableUpdateQuestion,$DisableUsers,$PassUCParam
$Step2 = $ConfPath,$LoginDBParam,$PassDBParam,$PathHRN,$LoginHRNParam,$PassHRNParam,$UpdateFromHRN,$PassUCParam,$OutLog
$Step3 = $ConfPath,$LoginDBParam,$PassDBParam,$PathHRN,$LoginHRNParam,$PassHRNParam,$UpdateDB,$PassUCParam,$OutLog
#$Step4 = $EntPath,$LoginDB,$PassDB,$DisableWinAuth,$DisableUpdateQuestion,$DisableMasseges,$DisableUpdateQuestion,$EnableUsers,$PassUCParam
#-----Функция устанавливает блокировки к базе данных и завершает все сеансы пользователей, если переданны соответсвующие параметры
Function BlockDB($AccessUsers,$TerminateSessions,$DropDesigner) {
# Подключение к агенту сервера
$ServerAgent = $ComConnector.ConnectAgent($SrvAddr)
$ClusterFound = $FALSE
$InfoBaseFound = $FALSE
#Получим массив кластеров сервера
$Clasters = $ServerAgent.GetClusters()
foreach ($Claster in $Clasters){
if ($Claster.MainPort -eq $MainPort){
$ClusterFound = $TRUE
break
}
}
if (!($ClusterFound)){
break
}
# Подключаемся к выбранному кластеру
# если у пользователя под которым будет выполняться сценарий нет прав на кластер,
# можно прописать ниже имя пользователя и пароль администратора кластера
$ServerAgent.Authenticate($Claster,"","")
# Получаем список рабочих процессов кластера
$WorkingProcesses = $ServerAgent.GetWorkingProcesses($Claster)
# Проверяем, если запущен конфигуратор, то отменяем дальнейшую работу
$WorkingBase = $ServerAgent.GetInfoBases($Claster)
foreach ($DBase in $WorkingBase){
if($DBase.Name -eq $DBName){
$DBSessions = $ServerAgent.GetInfoBaseSessions($Claster,$DBase)
foreach ($Session in $DBSessions){
if(!($DropDesigner) -and $Session.AppID -eq 'Designer'){
$WorkBegin = $False
$BreakText = 'Отмена работы скрипта. Запущен конфигуратор в сессии - ИД:' + $Session.SessionID + ', пользователь: ' + $Session.userName + ' использует приложение: ' + $Session.AppID + ', начало сеанса: ' + $Session.StartedAt + ', последняя активность: ' + $Session.LastActiveAT
Write-Host $BreakText
}
}
}
}
# Если разрешено блокировать базу, тогда продолжаем работу
if($WorkBegin){
# Включаем и выключаем блокировку сеансов и регламентных заданий
foreach ($WorkingProcess in $WorkingProcesses){
if (!($WorkingProcess.Running -eq 1) ){
continue
}
$CWPAddr = "tcp://"+$WorkingProcess.HostName+":"+$WorkingProcess.MainPort
$CWP = $ComConnector.ConnectWorkingProcess($CWPAddr)
$CWP.AddAuthentication($LoginDB, $PassDB)
$DBs = $CWP.GetInfoBases()
foreach ($DB in $DBs){
if ($DB.Name -eq $DBName ){
# Устанавливаем/снимаем блокировку соединений и рекламентных заданий БД
$DB.SessionsDenied = $AccessUsers
$DB.ScheduledJobsDenied = $AccessUsers
$DB.PermissionCode = $PassUC
$CWP.UpdateInfoBase($DB)
}
}
}
# Завершаем сеансы пользователя, если требуется
if ($TerminateSessions){
foreach ($DBase in $WorkingBase){
if($DBase.Name -eq $DBName){
$DBSessions = $ServerAgent.GetInfoBaseSessions($Claster,$DBase)
foreach ($Session in $DBSessions){
$ServerAgent.TerminateSession($Claster,$Session)
$ExitSessionText = 'Завершена сессия - ИД: ' + $Session.SessionID + ', пользователь: ' + $Session.userName + ', приложение: ' + $Session.AppID + ', начало сеанса: ' + $Session.StartedAt + ', последняя активность: ' + $Session.LastActiveAT
Write-Host $ExitSessionText
}
}
}
}
}
$ComConnector = ""
}
#-----Функция Обновление базы данных
Function UpdateDB{
Start-Process -FilePath $Dir -ArgumentList $Step2 -Wait
Start-Process -FilePath $Dir -ArgumentList $Step3 -Wait
}
#-----Добавимв в лог 1С строку начала операции с датами:
$Date = Get-Date -Format "dd.MM.yyyy HH:mm:ss"
$StringLog1C = "Operation was started at " + $Date + ": " + "`r`n"
$StringLog1C | out-file $DirLoglogFile_1C.txt -append
#-----Выполнение с выводом в лог
Start-Transcript -Path $DirLoglogfilePS.log
BlockDB $True $True $False
Wait-Event -Timeout 15
UpdateDB
BlockDB $False $True $False
#-----Добавим в лог 1С строку окончания операции с датами:
$Date = Get-Date -Format "dd.MM.yyyy HH:mm:ss"
$EndingLog1C = "`r`n" + "Operation was finished at " + $Date
$EndingLog1C | out-file $DirLoglogFile_1C.txt -append
"////////////////////////////////////////`r`n" | out-file $DirLoglogFile_1C.txt -append
Т.е. десяток готовых решений на github не подошёл? Интересно чем?
(1) Ну что вы ругаетесь, автор ж написал не нашел на ИС 🙂
Хотя как автор искал, непонятно, например вот целое how to, в которую вложения в виде СМ не нужны.
А ваша то чем отличается от других? она так же стоит СМ и тд…
» … готового механизма нет, чтобы вот так взять, скачать, установить в планировщик и все заработало.»
«…. посмотрел примеры кода в интернетах … и накарябал своего кодового «франкинштейна»
…
«При необходимости не сложно будет адаптировать под свои нужды и запустить в работу, не тратя время на долгие поиски и изучение мануалов»
очередной НЕ ГОТОВЫЙ вариант?
А почему только из хранилища обновление? А где обновление типовых баз ?
При обновлении кучи баз через автоматизатор, как решен вопрос с запусков в режиме Предприятия, подтверждением легальности обновления и выполнением отложенных обработчиков?
Что только не придумают, чтоб на картошку не ездить… (с) возьмите vrunner или deployka
(3) Она не стоит ничего. Файл просто приложен, по сути листинг на странице и в файле идентичны. Просто скопируйте текст в файл, назовите его любым именем с расширением ps1 и все будет работать. Т.е. качать ничего не надо. Файл приложен, если кто-то вдруг ну очень захочет спасибо сказать таким образом.
(4) Это готовый вариант под ту задачу, которую я описал. Прописал пароли, логины, пути в скрипте и он обновил из хранилища конфигурацию.
Вы там что употребляли, что обновление типовых баз и обновление из хранилища в одну шеренгу поставили?
Объясняю на пальцах. Вот у вас конфигурация, пусть даже типовая, которую вы решили дорабатывать с использованием хранилища конфигураций (ну чтобы много людей работало). Написали код, поместили в хранилище. Теперь, чтобы его увидели пользователи нужно обновить вашу конфигурацию на ту, что находится в хранилище с внесенными изменениями, вот для того, чтобы не делать это руками и предназначен скрипт.
Соответственно отпадает вопрос о проверке легальности. Вы обновляетесь ИЗ ХРАНИЛИЩА конфигураций. Если вы не знаете что такое хранилище… то я даже не знаю что еще сказать )))). Короче ваш комментарий мимо кассы. Вы внимательно прочитайте, что там написано.
(7)
Да собственно то же что и все употребляют.
ну если из хранилища обновлять тот же релиз, что и рабочая, то естественно никакой проверки легальности не будет. А если в хранилище обновить релиз? вы же не сидите вечно на одном релизе, если это только не самописка.
У меня на поддержке 80 типовых Бух баз из них 10 с дописками и 80 Зупов. Есть самописная конфа по администрированию и обслуживанию этих баз. И в ней были написаны (до меня) модули по групповому обновлению всех баз, только все последовательные операции надо было запускать вручную, в том числе и запуск каждой базы для подтверждения легальности получения обновления. Меня это не сильно радовало. Перелопатил что нашел в инете по автоматизации и что имелось у нас. Сделал расширение для автоматического подтверждения легальности обновления. И вуаля, у меня теперь полностью в автоматическом режиме (даже обновления релизов скачиваются сами). И обновление 80 баз проходит за 5 часов и без моего участия.
И не стал мудрить со скриптами, а написал на родном и понятном языке
(8) Да, ваша задача совсем про другое уже. Масштаб не тот. У меня ситуация гораздо проще, поэтому и решение проще. Т.е. только обновление из хранилища одной базы, доступы к которой прописаны в скрипте.
Соглашусь, что в вашем случае правильнее писать уже полноценное решение. Скрипты не для всех задач подходят, ну это сугубо мое мнение. Данный скрипт поможет людям с небольшим количеством баз.
Спасибо! Продолжай. Нужно больше статей про повершел )
+1. Отличная статья, отлично оформлена! тоже недавно с повершел знакомился) —https://infostart.ru/public/1114012/
(8) Может для типовых баз использовать «Обновлятор»?
(8)Вы бы выложили конфу на infostart’е 🙂
Нубский вопрос на тему «а можно такой же,но с перламутровыми пуговицами» 🙂 В Powershell есть возможность несколько задач запустить параллельно? Чтобы 10 идентичных баз разом обновлять, а не по одной?
(14)По идее можно, PowerShell поддерживает асинхронный вызов с помощью заданий (job). Если проще, то командлет Start-Job стартует код в фоне.Копайте в эту строну.
З.Ы. Т.е. на каждую базу создать свой скрипт на основе того, что здесь. После этого написать еще один скрипт, который будет запускать нужные скрипты в задачи параллельно. Как-то так.
(12) «Обновлятор» умеет подтверждать легальность получения обновления на серверных базах ?
(13) Я не являюсь Автором этой конфигурации.
Это групповое творчество по автоматизации обслуживания для отдела 1С.
Разработки делались несколькими людьми и отвечать за работоспособность всей конфы у меня нет желания.
Все же PS — нечитаемый язык. Что-то в нем есть от Perl.
(18) да, согласен. Но мне он показался похожим на ActionScript, что используется при программировании на Flash. Помнится давно я писал на AS, даже игра платформер есть =)). В целом для своих задач замечательный инструмент, но всему нужна мера. Если задача охватывает сложные процессы, либо объемную цепочку операций, то скриптами такие вещи решать не всегда корректно, иногда правильнее разработать полноценный инструмент. Просто есть люди, которые все на скриптах делают даже там, где это просто глупо. В моей статье про ректальное администрирование как раз этот нюанс описан. Статья, кстати, с реального админа списана, но личность его раскрывать не буду — не этично =)).