Auto-detect zone from host input and remote repadmin

This commit is contained in:
2026-01-29 11:44:58 +13:00
parent 81d1e5a919
commit a047a562fb

View File

@@ -237,6 +237,7 @@ function Invoke-Replication {
param(
[string[]]$Servers,
[string]$Command,
[bool]$UseRemote,
[scriptblock]$Log
)
@@ -248,13 +249,27 @@ function Invoke-Replication {
}
foreach ($server in $targets) {
$cmd = if ($Command -match "\{server\}") { $Command.Replace("{server}", $server) } else { $Command }
$usesToken = $Command -match "\{server\}"
$cmd = if ($usesToken) { $Command.Replace("{server}", $server) } else { $Command }
$cmd = $cmd.Trim()
if ($cmd -match "^(?i)\s*/repadmin\b") {
$cmd = $cmd -replace "^(?i)\s*/repadmin\b", "repadmin"
}
if ($server -and $cmd -match "(?i)\brepadmin\b" -and $cmd -match "(?i)\bsyncall\b" -and $cmd -notmatch "\{server\}") {
$cmd = $cmd -replace "(?i)\bsyncall\b", "syncall $server"
if ($UseRemote -and $cmd -match "(?i)\brepadmin\b" -and $cmd -match "(?i)\bsyncall\b") {
$remoteCmd = [regex]::Replace($cmd, "(?i)\\brepadmin\\s+/syncall\\s+\\S+", "repadmin /syncall")
& $Log "Replication (remote): $server -> $remoteCmd"
try {
Invoke-Command -ComputerName $server -ScriptBlock { param($c) & $env:ComSpec /c $c } -ArgumentList $remoteCmd |
ForEach-Object { & $Log $_ }
} catch {
& $Log "Replication error on $server: $($_.Exception.Message)"
}
continue
}
if (-not $usesToken -and $server -and $cmd -match "(?i)\brepadmin\b" -and $cmd -match "(?i)\bsyncall\b") {
if ($cmd -notmatch "(?i)\\bsyncall\\s+\\S+") {
$cmd = $cmd -replace "(?i)\\bsyncall\\b", "syncall $server"
}
}
if ([string]::IsNullOrWhiteSpace($cmd)) { continue }
& $Log "Replication: $cmd"
@@ -597,7 +612,18 @@ $y += 70 + $gap
Add-Label "Replication command ({server} optional)" $xLabel $y $labelWidth $rowHeight
$replicationCmdBox = Add-TextBox $xInput $y $inputWidth $rowHeight $false
$replicationCmdBox.Text = "repadmin /syncall {server} /AdeP"
$y += $rowHeight + ($gap * 2)
$y += $rowHeight + $gap
Add-Label "Replication wait (seconds)" $xLabel $y $labelWidth $rowHeight
$replicationDelayBox = Add-TextBox $xInput $y $inputWidth $rowHeight $false
$replicationDelayBox.Text = "30"
$y += $rowHeight + $gap
$replicationRemoteBox = Add-CheckBox "Run repadmin remotely (PowerShell)" $xInput $y $inputWidth $rowHeight
$replicationRemoteBox.Checked = $true
$y += $rowHeight + $gap
$y += $gap
Add-SectionHeader "ACME / Output"
Add-Label "WACS path" $xLabel $y $labelWidth $rowHeight
@@ -705,6 +731,8 @@ function Update-ReplicationUI {
$replicationFromSelectedBtn.Enabled = $enabled
$primaryFromSelectedBtn.Enabled = $enabled
$replicationCmdBox.Enabled = $enabled
$replicationDelayBox.Enabled = $enabled
$replicationRemoteBox.Enabled = $enabled
$dnsListBox.Enabled = $enabled
}
@@ -725,6 +753,16 @@ function Update-CertGenerationUI {
$validationPortBox.Enabled = -not $disabled
}
function Update-ZoneFromHostInput {
$hostList = @(Split-List $hostsBox.Text)
if ($hostList.Count -eq 0) { return }
$zoneGuess = Get-CommonZoneFromHosts -Hosts $hostList
if (-not [string]::IsNullOrWhiteSpace($zoneGuess) -and $zoneBox.Text -ne $zoneGuess) {
$zoneBox.Text = $zoneGuess
& $logAction "Default DNS zone set to $zoneGuess (from hostnames)."
}
}
$loadedDefaults = Load-Defaults
if ($loadedDefaults) {
$value = Get-DefaultValue -Defaults $loadedDefaults -Name "DefaultZone"
@@ -745,6 +783,12 @@ if ($loadedDefaults) {
$value = Get-DefaultValue -Defaults $loadedDefaults -Name "ReplicationEnabled"
if ($null -ne $value) { $replicationEnabledBox.Checked = [bool]$value }
$value = Get-DefaultValue -Defaults $loadedDefaults -Name "ReplicationDelaySeconds"
if ($null -ne $value) { $replicationDelayBox.Text = $value.ToString() }
$value = Get-DefaultValue -Defaults $loadedDefaults -Name "ReplicationRemote"
if ($null -ne $value) { $replicationRemoteBox.Checked = [bool]$value }
$value = Get-DefaultValue -Defaults $loadedDefaults -Name "WacsPath"
if (-not [string]::IsNullOrWhiteSpace($value)) { $wacsPathBox.Text = $value }
@@ -817,6 +861,8 @@ function Apply-Layout {
$replicationFromSelectedBtn.Left = $xInput + $inputWidthCalc - ((2 * $buttonWidth) + $buttonGap)
$primaryFromSelectedBtn.Left = $xInput + $inputWidthCalc - $buttonWidth
$replicationCmdBox.Width = $inputWidthCalc
$replicationDelayBox.Width = $inputWidthCalc
$replicationRemoteBox.Width = $inputWidthCalc
$wacsPathBox.Width = $inputWidthCalc
$outputTypeBox.Width = $inputWidthCalc
$outputPathBox.Width = $inputWidthCalc
@@ -954,6 +1000,10 @@ $outputTypeBox.Add_SelectedIndexChanged({
Update-OutputTypeUI
})
$hostsBox.Add_TextChanged({
Update-ZoneFromHostInput
})
$disableCertsBox.Add_CheckedChanged({
Update-CertGenerationUI
})
@@ -966,6 +1016,8 @@ $saveDefaultsBtn.Add_Click({
ReplicationTargets = $replicationTargetsBox.Text
ReplicationCommand = $replicationCmdBox.Text
ReplicationEnabled = $replicationEnabledBox.Checked
ReplicationDelaySeconds = $replicationDelayBox.Text
ReplicationRemote = $replicationRemoteBox.Checked
WacsPath = $wacsPathBox.Text
OutputType = $outputTypeBox.SelectedItem.ToString()
OutputPath = $outputPathBox.Text
@@ -1034,6 +1086,13 @@ $runBtn.Add_Click({
}
if ($replicationEnabledBox.Checked) {
$replicationDelaySeconds = 0
$delayRaw = $replicationDelayBox.Text.Trim()
if (-not [string]::IsNullOrWhiteSpace($delayRaw)) {
if (-not [int]::TryParse($delayRaw, [ref]$replicationDelaySeconds) -or $replicationDelaySeconds -lt 0) {
throw "Replication wait seconds must be a non-negative integer."
}
}
if ($selectedReplicationTargets.Count -gt 0) {
$replicationTargets = $selectedReplicationTargets
} else {
@@ -1043,7 +1102,11 @@ $runBtn.Add_Click({
& $logAction "Replication targets empty; using primary DNS server $dnsServer."
}
}
Invoke-Replication -Servers $replicationTargets -Command $replicationCmdBox.Text -Log $logAction
Invoke-Replication -Servers $replicationTargets -Command $replicationCmdBox.Text -UseRemote $replicationRemoteBox.Checked -Log $logAction
if ($replicationDelaySeconds -gt 0) {
& $logAction "Waiting $replicationDelaySeconds seconds for replication."
Start-Sleep -Seconds $replicationDelaySeconds
}
} else {
& $logAction "Replication disabled."
}