From 28dc291c80b4395a3bf33f3292db60cd01003033 Mon Sep 17 00:00:00 2001 From: Rephl3x Date: Thu, 29 Jan 2026 09:56:51 +1300 Subject: [PATCH] Fix host loop variable --- certy.ps1 | 94 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 9 deletions(-) diff --git a/certy.ps1 b/certy.ps1 index c5951a1..e34b28d 100644 --- a/certy.ps1 +++ b/certy.ps1 @@ -69,6 +69,39 @@ function Get-FilePreview { } } +function Get-CommonZoneFromHosts { + param([string[]]$Hosts) + $fqdnHosts = $Hosts | Where-Object { $_ -and $_.Contains(".") } + if (-not $fqdnHosts -or $fqdnHosts.Count -eq 0) { return "" } + + $commonSuffix = $null + foreach ($host in $fqdnHosts) { + $clean = $host.Trim().TrimEnd(".") + $labels = $clean -split "\." + if ($labels.Count -lt 2) { continue } + $zoneLabels = $labels[1..($labels.Count - 1)] + if (-not $commonSuffix) { + $commonSuffix = $zoneLabels + continue + } + + $i = $commonSuffix.Count - 1 + $j = $zoneLabels.Count - 1 + $newSuffix = @() + while ($i -ge 0 -and $j -ge 0) { + if ($commonSuffix[$i].ToLower() -ne $zoneLabels[$j].ToLower()) { break } + $newSuffix = ,$zoneLabels[$j] + $newSuffix + $i-- + $j-- + } + $commonSuffix = $newSuffix + if (-not $commonSuffix -or $commonSuffix.Count -eq 0) { break } + } + + if (-not $commonSuffix -or $commonSuffix.Count -eq 0) { return "" } + return ($commonSuffix -join ".") +} + function Get-DefaultsPath { $dir = Join-Path $env:ProgramData "Certy" return Join-Path $dir "defaults.json" @@ -196,10 +229,15 @@ function Invoke-Replication { ) if ([string]::IsNullOrWhiteSpace($Command)) { return } - $targets = if ($Servers.Count -gt 0) { $Servers } else { @("") } + $targets = @($Servers | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) + if ($targets.Count -eq 0) { + & $Log "Replication skipped: no target servers." + return + } foreach ($server in $targets) { $cmd = if ($Command -match "\{server\}") { $Command.Replace("{server}", $server) } else { $Command } + $cmd = $cmd.Trim() if ([string]::IsNullOrWhiteSpace($cmd)) { continue } & $Log "Replication: $cmd" & $env:ComSpec /c $cmd | ForEach-Object { & $Log $_ } @@ -221,9 +259,9 @@ function Invoke-Wacs { ) $args = @("--target", "manual") - foreach ($host in $HostFqdns) { - if (-not [string]::IsNullOrWhiteSpace($host)) { - $args += @("--host", $host) + foreach ($hostName in $HostFqdns) { + if (-not [string]::IsNullOrWhiteSpace($hostName)) { + $args += @("--host", $hostName) } } @@ -478,6 +516,10 @@ $zoneBox = Add-TextBox $xInput $y $inputWidth $rowHeight $false $zoneBox.Text = "record.domain.govt.nz" $y += $rowHeight + $gap +$replicationEnabledBox = Add-CheckBox "Enable DNS replication" $xInput $y 200 $rowHeight +$replicationEnabledBox.Checked = $true +$y += $rowHeight + $gap + Add-Label "Target IPv4 for A records" $xLabel $y $labelWidth $rowHeight $ipBox = Add-TextBox $xInput $y ($inputWidth - ($buttonWidth + $buttonGap)) $rowHeight $false $ipBox.Text = Get-LocalIpv4 @@ -536,7 +578,7 @@ $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" +$replicationCmdBox.Text = "repadmin /syncall {server} /A /e /P /d" $y += $rowHeight + ($gap * 2) Add-SectionHeader "ACME / Output" @@ -644,6 +686,7 @@ if ($loadedDefaults) { if ($loadedDefaults.DnsServer) { $dnsServerBox.Text = $loadedDefaults.DnsServer } if ($loadedDefaults.ReplicationTargets) { $replicationTargetsBox.Text = $loadedDefaults.ReplicationTargets } if ($loadedDefaults.ReplicationCommand) { $replicationCmdBox.Text = $loadedDefaults.ReplicationCommand } + if ($null -ne $loadedDefaults.ReplicationEnabled) { $replicationEnabledBox.Checked = [bool]$loadedDefaults.ReplicationEnabled } if ($loadedDefaults.WacsPath) { $wacsPathBox.Text = $loadedDefaults.WacsPath } if ($loadedDefaults.OutputPath) { $outputPathBox.Text = $loadedDefaults.OutputPath } if ($loadedDefaults.PfxPassword) { $pfxPasswordBox.Text = $loadedDefaults.PfxPassword } @@ -657,6 +700,7 @@ if ($loadedDefaults) { if ($loadedDefaults.OutputType) { $outputTypeBox.SelectedItem = $loadedDefaults.OutputType } if (-not $outputTypeBox.SelectedItem) { $outputTypeBox.SelectedIndex = 0 } Update-OutputTypeUI + Update-ReplicationUI & $logAction "Defaults loaded from $(Get-DefaultsPath)." } @@ -701,6 +745,15 @@ function Apply-Layout { $saveDefaultsBtn.Left = $clearBtn.Left + $clearBtn.Width + $buttonGap } +function Update-ReplicationUI { + $enabled = $replicationEnabledBox.Checked + $replicationTargetsBox.Enabled = $enabled + $replicationFromSelectedBtn.Enabled = $enabled + $primaryFromSelectedBtn.Enabled = $enabled + $replicationCmdBox.Enabled = $enabled + $dnsListBox.Enabled = $enabled +} + $browseBtn.Add_Click({ $dialog = New-Object System.Windows.Forms.OpenFileDialog $dialog.Filter = "Text/CSV files (*.txt;*.csv)|*.txt;*.csv|All files (*.*)|*.*" @@ -708,11 +761,29 @@ $browseBtn.Add_Click({ if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $fileBox.Text = $dialog.FileName $filePreviewBox.Text = Get-FilePreview -Path $dialog.FileName + $fileHosts = Get-Content -Path $dialog.FileName | ForEach-Object { $_.Trim() } | Where-Object { $_ } + $zoneGuess = Get-CommonZoneFromHosts -Hosts $fileHosts + if ($zoneGuess) { + $zoneBox.Text = $zoneGuess + & $logAction "Default DNS zone set to $zoneGuess (from file)." + } } }) +$replicationEnabledBox.Add_CheckedChanged({ + Update-ReplicationUI +}) + $filePreviewBtn.Add_Click({ $filePreviewBox.Text = Get-FilePreview -Path $fileBox.Text.Trim() + if (Test-Path -Path $fileBox.Text.Trim() -PathType Leaf) { + $fileHosts = Get-Content -Path $fileBox.Text.Trim() | ForEach-Object { $_.Trim() } | Where-Object { $_ } + $zoneGuess = Get-CommonZoneFromHosts -Hosts $fileHosts + if ($zoneGuess) { + $zoneBox.Text = $zoneGuess + & $logAction "Default DNS zone set to $zoneGuess (from file)." + } + } }) $csrBrowseBtn.Add_Click({ @@ -803,6 +874,7 @@ $saveDefaultsBtn.Add_Click({ DnsServer = $dnsServerBox.Text ReplicationTargets = $replicationTargetsBox.Text ReplicationCommand = $replicationCmdBox.Text + ReplicationEnabled = $replicationEnabledBox.Checked WacsPath = $wacsPathBox.Text OutputType = $outputTypeBox.SelectedItem.ToString() OutputPath = $outputPathBox.Text @@ -869,12 +941,16 @@ $runBtn.Add_Click({ Ensure-ARecord -Zone $zone -HostLabel $entry.HostLabel -TargetIp $targetIp -DnsServer $dnsServer -Log $logAction } - if ($selectedReplicationTargets.Count -gt 0) { - $replicationTargets = $selectedReplicationTargets + if ($replicationEnabledBox.Checked) { + if ($selectedReplicationTargets.Count -gt 0) { + $replicationTargets = $selectedReplicationTargets + } else { + $replicationTargets = Split-List $replicationTargetsBox.Text + } + Invoke-Replication -Servers $replicationTargets -Command $replicationCmdBox.Text -Log $logAction } else { - $replicationTargets = Split-List $replicationTargetsBox.Text + & $logAction "Replication disabled." } - Invoke-Replication -Servers $replicationTargets -Command $replicationCmdBox.Text -Log $logAction if ($runWacsBox.Checked) { $wacsPath = $wacsPathBox.Text.Trim()