fix: Deploy-DomainMonitors encoding for PS 5.1 / NETLOGON (v1.6.2)
- ASCII runtime strings in domain deploy/install scripts - Publish *.ps1 to NETLOGON with UTF-8 BOM
This commit is contained in:
+14
-14
@@ -1,8 +1,8 @@
|
|||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Доставка скриптов доменных мониторов (Exchange / AD) с шары в ProgramData.
|
Deploy domain monitor scripts (Exchange / AD) from share to ProgramData.
|
||||||
.PARAMETER Target
|
.PARAMETER Target
|
||||||
Exchange — Exchange-MailSecurity.ps1 + Notify-Common.ps1; Ad — зарезервировано.
|
Exchange - Exchange-MailSecurity.ps1 + Notify-Common.ps1; Ad - reserved.
|
||||||
#>
|
#>
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param(
|
param(
|
||||||
@@ -54,7 +54,7 @@ function Resolve-SourceShareRoot {
|
|||||||
$here = $PSCommandPath
|
$here = $PSCommandPath
|
||||||
if ([string]::IsNullOrWhiteSpace($here)) { $here = $MyInvocation.MyCommand.Path }
|
if ([string]::IsNullOrWhiteSpace($here)) { $here = $MyInvocation.MyCommand.Path }
|
||||||
if ([string]::IsNullOrWhiteSpace($here)) {
|
if ([string]::IsNullOrWhiteSpace($here)) {
|
||||||
throw 'Укажите -SourceShareRoot или запускайте скрипт с UNC-шары.'
|
throw 'Specify -SourceShareRoot or run this script by full UNC path to the .ps1 file on the share.'
|
||||||
}
|
}
|
||||||
return [System.IO.Path]::GetFullPath((Split-Path -Parent $here))
|
return [System.IO.Path]::GetFullPath((Split-Path -Parent $here))
|
||||||
}
|
}
|
||||||
@@ -81,25 +81,25 @@ function Compare-SemVerLike {
|
|||||||
$shareRoot = Resolve-SourceShareRoot
|
$shareRoot = Resolve-SourceShareRoot
|
||||||
$filesToCopy = switch ($Target) {
|
$filesToCopy = switch ($Target) {
|
||||||
'Exchange' { $ExchangeFiles }
|
'Exchange' { $ExchangeFiles }
|
||||||
'Ad' { throw 'Target Ad пока не поддерживается.' }
|
'Ad' { throw 'Target Ad is not supported yet.' }
|
||||||
}
|
}
|
||||||
|
|
||||||
$sourceVersionFile = Join-Path $shareRoot $VersionFileName
|
$sourceVersionFile = Join-Path $shareRoot $VersionFileName
|
||||||
if (-not (Test-Path -LiteralPath $sourceVersionFile)) {
|
if (-not (Test-Path -LiteralPath $sourceVersionFile)) {
|
||||||
Write-DeployLog "ОШИБКА: нет $sourceVersionFile на шаре."
|
Write-DeployLog "ERROR: missing on share: $sourceVersionFile"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
$shareVer = Read-VersionLineFromFile -Path $sourceVersionFile
|
$shareVer = Read-VersionLineFromFile -Path $sourceVersionFile
|
||||||
$localVer = Read-VersionLineFromFile -Path $VersionStampPath
|
$localVer = Read-VersionLineFromFile -Path $VersionStampPath
|
||||||
Write-DeployLog "Шара version=$shareVer локальная метка=$localVer"
|
Write-DeployLog "Share version=$shareVer local stamp=$localVer"
|
||||||
|
|
||||||
if (-not [string]::IsNullOrWhiteSpace($localVer)) {
|
if (-not [string]::IsNullOrWhiteSpace($localVer)) {
|
||||||
$cmp = Compare-SemVerLike -A $shareVer -B $localVer
|
$cmp = Compare-SemVerLike -A $shareVer -B $localVer
|
||||||
if ($cmp -eq 0) {
|
if ($cmp -eq 0) {
|
||||||
Write-DeployLog 'Версия совпадает — копирование не требуется.'
|
Write-DeployLog 'Version match - skip copy.'
|
||||||
if (-not $SkipInstallTasks) {
|
if (-not $SkipInstallTasks) {
|
||||||
Write-DeployLog 'Проверка InstallTasks...'
|
Write-DeployLog 'Running InstallTasks check...'
|
||||||
if (-not $WhatIf) {
|
if (-not $WhatIf) {
|
||||||
& $PsExe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $InstallRoot 'Install-DomainMonitors.ps1') -Target $Target
|
& $PsExe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $InstallRoot 'Install-DomainMonitors.ps1') -Target $Target
|
||||||
}
|
}
|
||||||
@@ -107,13 +107,13 @@ if (-not [string]::IsNullOrWhiteSpace($localVer)) {
|
|||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
if ($cmp -lt 0 -and -not $AllowDowngrade) {
|
if ($cmp -lt 0 -and -not $AllowDowngrade) {
|
||||||
Write-DeployLog 'Версия на шаре старее локальной — пропуск (AllowDowngrade).'
|
Write-DeployLog 'Share version older than local - skip (use -AllowDowngrade to force).'
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-not (Test-Path -LiteralPath $InstallRoot)) {
|
if (-not (Test-Path -LiteralPath $InstallRoot)) {
|
||||||
if ($WhatIf) { Write-DeployLog "WhatIf: создать $InstallRoot"; exit 0 }
|
if ($WhatIf) { Write-DeployLog "WhatIf: create $InstallRoot"; exit 0 }
|
||||||
New-Item -ItemType Directory -Path $InstallRoot -Force | Out-Null
|
New-Item -ItemType Directory -Path $InstallRoot -Force | Out-Null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ foreach ($name in $filesToCopy) {
|
|||||||
$src = Join-Path $shareRoot $name
|
$src = Join-Path $shareRoot $name
|
||||||
$dst = Join-Path $InstallRoot $name
|
$dst = Join-Path $InstallRoot $name
|
||||||
if (-not (Test-Path -LiteralPath $src)) {
|
if (-not (Test-Path -LiteralPath $src)) {
|
||||||
Write-DeployLog "ОШИБКА: на шаре нет $name"
|
Write-DeployLog "ERROR: missing on share: $name"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
if ($WhatIf) {
|
if ($WhatIf) {
|
||||||
@@ -129,7 +129,7 @@ foreach ($name in $filesToCopy) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
Copy-Item -LiteralPath $src -Destination $dst -Force
|
Copy-Item -LiteralPath $src -Destination $dst -Force
|
||||||
Write-DeployLog "Скопировано: $name"
|
Write-DeployLog "Copied: $name"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-not $WhatIf) {
|
if (-not $WhatIf) {
|
||||||
@@ -138,11 +138,11 @@ if (-not $WhatIf) {
|
|||||||
$installer = Join-Path $InstallRoot 'Install-DomainMonitors.ps1'
|
$installer = Join-Path $InstallRoot 'Install-DomainMonitors.ps1'
|
||||||
& $PsExe -NoProfile -ExecutionPolicy Bypass -File $installer -Target $Target
|
& $PsExe -NoProfile -ExecutionPolicy Bypass -File $installer -Target $Target
|
||||||
if ($LASTEXITCODE -ne 0) {
|
if ($LASTEXITCODE -ne 0) {
|
||||||
Write-DeployLog "Install-DomainMonitors завершился с кодом $LASTEXITCODE"
|
Write-DeployLog "Install-DomainMonitors exit code: $LASTEXITCODE"
|
||||||
exit $LASTEXITCODE
|
exit $LASTEXITCODE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-DeployLog 'Deploy-DomainMonitors завершён.'
|
Write-DeployLog 'Deploy-DomainMonitors finished.'
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -31,3 +31,5 @@ powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\soft\update-rdp-monit
|
|||||||
```
|
```
|
||||||
|
|
||||||
После pull обязательно проверьте **`version.txt`** на шаре — его номер определяет, подтянут ли обновления на клиентах и Exchange.
|
После pull обязательно проверьте **`version.txt`** на шаре — его номер определяет, подтянут ли обновления на клиентах и Exchange.
|
||||||
|
|
||||||
|
Файлы **`*.ps1`** при копировании пересохраняются как **UTF-8 с BOM** (иначе PowerShell 5.1 с NETLOGON может не разобрать кириллицу в скриптах). Скрипты **`Deploy-DomainMonitors.ps1`** и **`Install-DomainMonitors.ps1`** используют **ASCII** в рабочих строках — их можно запускать и без перепубликации.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Регистрирует задачи планировщика для доменных мониторов (Exchange; AD — позже).
|
Register scheduled tasks for domain monitors (Exchange; AD later).
|
||||||
.PARAMETER Target
|
.PARAMETER Target
|
||||||
Exchange — Exchange-MailSecurity.ps1; Ad — зарезервировано.
|
Exchange - Exchange-MailSecurity.ps1; Ad - reserved.
|
||||||
#>
|
#>
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param(
|
param(
|
||||||
@@ -25,25 +25,25 @@ function Test-RunningElevated {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (-not (Test-RunningElevated)) {
|
if (-not (Test-RunningElevated)) {
|
||||||
throw 'Запустите Install-DomainMonitors.ps1 от имени администратора.'
|
throw 'Run Install-DomainMonitors.ps1 as Administrator.'
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($Target) {
|
switch ($Target) {
|
||||||
'Exchange' {
|
'Exchange' {
|
||||||
$scriptPath = Join-Path $InstallRoot 'Exchange-MailSecurity.ps1'
|
$scriptPath = Join-Path $InstallRoot 'Exchange-MailSecurity.ps1'
|
||||||
if (-not (Test-Path -LiteralPath $scriptPath)) {
|
if (-not (Test-Path -LiteralPath $scriptPath)) {
|
||||||
throw "Не найден: $scriptPath"
|
throw "Not found: $scriptPath"
|
||||||
}
|
}
|
||||||
$notifyPath = Join-Path $InstallRoot 'Notify-Common.ps1'
|
$notifyPath = Join-Path $InstallRoot 'Notify-Common.ps1'
|
||||||
if (-not (Test-Path -LiteralPath $notifyPath)) {
|
if (-not (Test-Path -LiteralPath $notifyPath)) {
|
||||||
throw "Не найден: $notifyPath"
|
throw "Not found: $notifyPath"
|
||||||
}
|
}
|
||||||
& $PsExe -NoProfile -ExecutionPolicy Bypass -File $scriptPath -InstallTasks
|
& $PsExe -NoProfile -ExecutionPolicy Bypass -File $scriptPath -InstallTasks
|
||||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||||
Write-Host "Exchange: задачи планировщика зарегистрированы."
|
Write-Host 'Exchange: scheduled tasks registered.'
|
||||||
}
|
}
|
||||||
'Ad' {
|
'Ad' {
|
||||||
Write-Host 'AD-SecurityMonitor.ps1 пока не реализован — используйте Target Exchange.'
|
Write-Host 'AD-SecurityMonitor.ps1 is not implemented yet. Use -Target Exchange.'
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-1
@@ -110,6 +110,25 @@ function Update-Repository {
|
|||||||
$null = Invoke-GitCommand -Arguments @('rev-parse', '--short', 'HEAD')
|
$null = Invoke-GitCommand -Arguments @('rev-parse', '--short', 'HEAD')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Copy-FileToNetlogon {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)][string]$SourcePath,
|
||||||
|
[Parameter(Mandatory = $true)][string]$DestPath
|
||||||
|
)
|
||||||
|
if ($SourcePath -like '*.ps1') {
|
||||||
|
$raw = [System.IO.File]::ReadAllBytes($SourcePath)
|
||||||
|
$utf8NoBom = New-Object System.Text.UTF8Encoding $false
|
||||||
|
$text = $utf8NoBom.GetString($raw)
|
||||||
|
if ($text.Length -gt 0 -and [int][char]$text[0] -eq 0xFEFF) {
|
||||||
|
$text = $text.Substring(1)
|
||||||
|
}
|
||||||
|
$utf8Bom = New-Object System.Text.UTF8Encoding $true
|
||||||
|
[System.IO.File]::WriteAllText($DestPath, $text, $utf8Bom)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Copy-Item -LiteralPath $SourcePath -Destination $DestPath -Force
|
||||||
|
}
|
||||||
|
|
||||||
function Publish-DistributionFiles {
|
function Publish-DistributionFiles {
|
||||||
if (-not (Test-Path -LiteralPath $NetlogonDest)) {
|
if (-not (Test-Path -LiteralPath $NetlogonDest)) {
|
||||||
if ($PSCmdlet.ShouldProcess($NetlogonDest, 'Create directory')) {
|
if ($PSCmdlet.ShouldProcess($NetlogonDest, 'Create directory')) {
|
||||||
@@ -124,7 +143,7 @@ function Publish-DistributionFiles {
|
|||||||
}
|
}
|
||||||
$dst = Join-Path $NetlogonDest $name
|
$dst = Join-Path $NetlogonDest $name
|
||||||
if ($PSCmdlet.ShouldProcess($dst, "Copy from $src")) {
|
if ($PSCmdlet.ShouldProcess($dst, "Copy from $src")) {
|
||||||
Copy-Item -LiteralPath $src -Destination $dst -Force
|
Copy-FileToNetlogon -SourcePath $src -DestPath $dst
|
||||||
Write-UpdateLog "Copied: $name -> $NetlogonDest"
|
Write-UpdateLog "Copied: $name -> $NetlogonDest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
1.6.1
|
1.6.2
|
||||||
|
|||||||
Reference in New Issue
Block a user