Public/Install-1CServer.ps1
|
<#
.SYNOPSIS Простой установщик сервера 1С с выбором префикса портов. Поддерживает -SetupPath и -Credential. .DESCRIPTION 1) Ставит/обновляет платформу (Install-1CPlatform; при -SetupPath — из указанного каталога/корня). 2) Настраивает учётку USR1CV8 (принимает -Credential, иначе: passfile → запрос пароля). 3) Создаёт каталог srvinfo(XX), ACL. 4) Регистрирует comcntr.dll и radmin.dll. 5) Создаёт службу агента с портами на базе префикса. ИМЕНА СЛУЖБ (без версий): • Имя службы зависит ТОЛЬКО от префикса портов (параметр -PortPrefix). Параметр -Version на имя не влияет. PortPrefix 15 → '1C:Enterprise 8.3 Server Agent Current' PortPrefix !=15 → '1C:Enterprise 8.3 Server Agent Current<PortPrefix>' (например Current25) ПУТЬ К БИНАРНИКАМ • Путь ragent.exe в службе всегда указывает на '...\\current\\bin'. Параметр -Version влияет только на то, какая версия платформы будет установлена/подготовлена (Install-1CPlatform), но НЕ влияет на имя службы и путь к бинарникам в службе. .PARAMETER PortPrefix Первые две цифры портов (например 15, 25, 35). По умолчанию 15. .PARAMETER Version 'current' (по умолчанию) или конкретная версия (например '8.3.22.1704'). .PARAMETER SetupPath Папка версии или общий корень с архивами. Передаётся в Install-1CPlatform. .PARAMETER Credential PSCredential для USR1CV8. Если не задан — будет использован passfile или интерактивный запрос пароля. .EXAMPLE Install-1CServer -PortPrefix 25 -Version 8.3.22.1704 -SetupPath "\\server\\distr" #> function Install-1CServer { param( [ValidatePattern('^\d{2}$')] [string]$PortPrefix = '15', [ValidateNotNullOrEmpty()] [string]$Version = 'current', [string]$SetupPath, [System.Management.Automation.PSCredential]$Credential ) # 0) Если переданы SetupPath + конкретная Version — обязательно найдём нужный архив, иначе прервём установку $ResolvedSetupPath = $SetupPath if ($SetupPath -and $Version -ne 'current') { if (-not (Test-Path -LiteralPath $SetupPath)) { throw "Каталог не найден: $SetupPath" } $vU = ($Version -replace '\.','_') $wanted = "windows64full_$vU.rar" $leaf = Split-Path -Leaf $SetupPath $hit = $null try { if ($leaf -eq $Version) { # Ожидаем архив прямо в этой папке $hit = Get-ChildItem -LiteralPath $SetupPath -Filter $wanted -File -ErrorAction SilentlyContinue | Select-Object -First 1 if (-not $hit) { # На всякий случай — проверим рекурсивно внутри версии $hit = Get-ChildItem -LiteralPath $SetupPath -Recurse -Filter $wanted -File -ErrorAction SilentlyContinue | Select-Object -First 1 } } else { # Общий корень — ищем рекурсивно $hit = Get-ChildItem -LiteralPath $SetupPath -Recurse -Filter $wanted -File -ErrorAction SilentlyContinue | Select-Object -First 1 } } catch { throw "Ошибка при поиске архива '$wanted' в '$SetupPath': $($_.Exception.Message)" } if ($hit) { $ResolvedSetupPath = $hit.DirectoryName Write-Host "Найдена версия $Version по архиву '$wanted'. Использую каталог: $ResolvedSetupPath" -ForegroundColor Cyan } else { throw "Не найден архив '$wanted' в '$SetupPath'. Установка прервана по требованию — версия должна соответствовать параметру -Version." } } # 1) Платформа (если путь разрешён — ставим строго из него) if ($ResolvedSetupPath) { Install-1CPlatform -SetupPath $ResolvedSetupPath } elseif ($SetupPath) { Install-1CPlatform -SetupPath $SetupPath } else { Install-1CPlatform } # 2) Учетка USR1CV8 и креды $username = "$env:COMPUTERNAME\USR1CV8" $localUser = Get-LocalUser -Name 'USR1CV8' -ErrorAction SilentlyContinue if (-not $Credential) { if (Test-Path 'C:\passfile.txt') { $secure = Get-Content 'C:\passfile.txt' | ConvertTo-SecureString $Credential = [pscredential]::new($username, $secure) Remove-Item 'C:\passfile.txt' -Force -ErrorAction SilentlyContinue } elseif ($localUser) { $secure = Read-Host -Prompt "Введите пароль для $username" -AsSecureString $Credential = [pscredential]::new($username, $secure) } else { New-1CServiceUser if (Test-Path 'C:\passfile.txt') { $secure = Get-Content 'C:\passfile.txt' | ConvertTo-SecureString $Credential = [pscredential]::new($username, $secure) Remove-Item 'C:\passfile.txt' -Force -ErrorAction SilentlyContinue } else { $secure = Read-Host -Prompt "Введите пароль для $username" -AsSecureString $Credential = [pscredential]::new($username, $secure) } } } # 3) Порты $BasePort = "{0}41" -f $PortPrefix $CtrlPort = "{0}40" -f $PortPrefix $RangePort = "{0}60:{0}91" -f $PortPrefix # 4) Пути и файлы $ProgramFiles1C = 'C:\Program Files\1cv8' $SrvinfoName = if ($PortPrefix -eq '15') { 'srvinfo' } else { "srvinfo$PortPrefix" } $SrvCatalog = Join-Path $ProgramFiles1C $SrvinfoName $BinPath = Join-Path $ProgramFiles1C (Join-Path 'current' 'bin') # всегда 'current\bin' для бесшовных апгрейдов $RunExe = Join-Path $BinPath 'ragent.exe' $ComCntrl = Join-Path $BinPath 'comcntr.dll' $Radmin = Join-Path $BinPath 'radmin.dll' # 5) Имя службы: зависит только от PortPrefix, -Version игнорируется в названии if ($PortPrefix -eq '15') { $ServiceName = '1C:Enterprise 8.3 Server Agent Current' } else { $ServiceName = "1C:Enterprise 8.3 Server Agent Current$PortPrefix" } # 6) Каталог и ACL if (-not (Test-Path $SrvCatalog)) { New-Item -ItemType Directory -Path $SrvCatalog | Out-Null } $acl = Get-Acl $SrvCatalog $access = New-Object System.Security.AccessControl.FileSystemAccessRule($username,'FullControl','ContainerInherit, ObjectInherit','None','Allow') $acl.SetAccessRule($access) $acl.SetAccessRuleProtection($false,$true) $acl | Set-Acl $SrvCatalog # 7) Регистрация DLL (тихо) regsvr32.exe "`"$ComCntrl`"" -s regsvr32.exe "`"$Radmin`"" -s # 8) Команда запуска агента $ServicePath = @( "`"$RunExe`"" '-srvc','-agent' '-regport', $BasePort '-port', $CtrlPort '-range', $RangePort '-debug' '-d', "`"$SrvCatalog`"" ) -join ' ' # 9) Пересоздание службы $existing = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue if ($existing) { Stop-Service -Name $ServiceName -ErrorAction SilentlyContinue sc.exe delete "$ServiceName" | Out-Null Start-Sleep -Seconds 1 } New-Service -Name $ServiceName -BinaryPathName $ServicePath -DisplayName $ServiceName -StartupType Automatic -Credential $Credential Start-Service -Name $ServiceName Write-Host "OK: $ServiceName (base=$BasePort ctrl=$CtrlPort range=$RangePort)" } |