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( param(
[string[]]$Servers, [string[]]$Servers,
[string]$Command, [string]$Command,
[bool]$UseRemote,
[scriptblock]$Log [scriptblock]$Log
) )
@@ -248,13 +249,27 @@ function Invoke-Replication {
} }
foreach ($server in $targets) { 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() $cmd = $cmd.Trim()
if ($cmd -match "^(?i)\s*/repadmin\b") { if ($cmd -match "^(?i)\s*/repadmin\b") {
$cmd = $cmd -replace "^(?i)\s*/repadmin\b", "repadmin" $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\}") { if ($UseRemote -and $cmd -match "(?i)\brepadmin\b" -and $cmd -match "(?i)\bsyncall\b") {
$cmd = $cmd -replace "(?i)\bsyncall\b", "syncall $server" $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 } if ([string]::IsNullOrWhiteSpace($cmd)) { continue }
& $Log "Replication: $cmd" & $Log "Replication: $cmd"
@@ -597,7 +612,18 @@ $y += 70 + $gap
Add-Label "Replication command ({server} optional)" $xLabel $y $labelWidth $rowHeight Add-Label "Replication command ({server} optional)" $xLabel $y $labelWidth $rowHeight
$replicationCmdBox = Add-TextBox $xInput $y $inputWidth $rowHeight $false $replicationCmdBox = Add-TextBox $xInput $y $inputWidth $rowHeight $false
$replicationCmdBox.Text = "repadmin /syncall {server} /AdeP" $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-SectionHeader "ACME / Output"
Add-Label "WACS path" $xLabel $y $labelWidth $rowHeight Add-Label "WACS path" $xLabel $y $labelWidth $rowHeight
@@ -705,6 +731,8 @@ function Update-ReplicationUI {
$replicationFromSelectedBtn.Enabled = $enabled $replicationFromSelectedBtn.Enabled = $enabled
$primaryFromSelectedBtn.Enabled = $enabled $primaryFromSelectedBtn.Enabled = $enabled
$replicationCmdBox.Enabled = $enabled $replicationCmdBox.Enabled = $enabled
$replicationDelayBox.Enabled = $enabled
$replicationRemoteBox.Enabled = $enabled
$dnsListBox.Enabled = $enabled $dnsListBox.Enabled = $enabled
} }
@@ -725,6 +753,16 @@ function Update-CertGenerationUI {
$validationPortBox.Enabled = -not $disabled $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 $loadedDefaults = Load-Defaults
if ($loadedDefaults) { if ($loadedDefaults) {
$value = Get-DefaultValue -Defaults $loadedDefaults -Name "DefaultZone" $value = Get-DefaultValue -Defaults $loadedDefaults -Name "DefaultZone"
@@ -745,6 +783,12 @@ if ($loadedDefaults) {
$value = Get-DefaultValue -Defaults $loadedDefaults -Name "ReplicationEnabled" $value = Get-DefaultValue -Defaults $loadedDefaults -Name "ReplicationEnabled"
if ($null -ne $value) { $replicationEnabledBox.Checked = [bool]$value } 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" $value = Get-DefaultValue -Defaults $loadedDefaults -Name "WacsPath"
if (-not [string]::IsNullOrWhiteSpace($value)) { $wacsPathBox.Text = $value } if (-not [string]::IsNullOrWhiteSpace($value)) { $wacsPathBox.Text = $value }
@@ -817,6 +861,8 @@ function Apply-Layout {
$replicationFromSelectedBtn.Left = $xInput + $inputWidthCalc - ((2 * $buttonWidth) + $buttonGap) $replicationFromSelectedBtn.Left = $xInput + $inputWidthCalc - ((2 * $buttonWidth) + $buttonGap)
$primaryFromSelectedBtn.Left = $xInput + $inputWidthCalc - $buttonWidth $primaryFromSelectedBtn.Left = $xInput + $inputWidthCalc - $buttonWidth
$replicationCmdBox.Width = $inputWidthCalc $replicationCmdBox.Width = $inputWidthCalc
$replicationDelayBox.Width = $inputWidthCalc
$replicationRemoteBox.Width = $inputWidthCalc
$wacsPathBox.Width = $inputWidthCalc $wacsPathBox.Width = $inputWidthCalc
$outputTypeBox.Width = $inputWidthCalc $outputTypeBox.Width = $inputWidthCalc
$outputPathBox.Width = $inputWidthCalc $outputPathBox.Width = $inputWidthCalc
@@ -954,6 +1000,10 @@ $outputTypeBox.Add_SelectedIndexChanged({
Update-OutputTypeUI Update-OutputTypeUI
}) })
$hostsBox.Add_TextChanged({
Update-ZoneFromHostInput
})
$disableCertsBox.Add_CheckedChanged({ $disableCertsBox.Add_CheckedChanged({
Update-CertGenerationUI Update-CertGenerationUI
}) })
@@ -966,6 +1016,8 @@ $saveDefaultsBtn.Add_Click({
ReplicationTargets = $replicationTargetsBox.Text ReplicationTargets = $replicationTargetsBox.Text
ReplicationCommand = $replicationCmdBox.Text ReplicationCommand = $replicationCmdBox.Text
ReplicationEnabled = $replicationEnabledBox.Checked ReplicationEnabled = $replicationEnabledBox.Checked
ReplicationDelaySeconds = $replicationDelayBox.Text
ReplicationRemote = $replicationRemoteBox.Checked
WacsPath = $wacsPathBox.Text WacsPath = $wacsPathBox.Text
OutputType = $outputTypeBox.SelectedItem.ToString() OutputType = $outputTypeBox.SelectedItem.ToString()
OutputPath = $outputPathBox.Text OutputPath = $outputPathBox.Text
@@ -1034,6 +1086,13 @@ $runBtn.Add_Click({
} }
if ($replicationEnabledBox.Checked) { 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) { if ($selectedReplicationTargets.Count -gt 0) {
$replicationTargets = $selectedReplicationTargets $replicationTargets = $selectedReplicationTargets
} else { } else {
@@ -1043,7 +1102,11 @@ $runBtn.Add_Click({
& $logAction "Replication targets empty; using primary DNS server $dnsServer." & $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 { } else {
& $logAction "Replication disabled." & $logAction "Replication disabled."
} }