Update Deploy-ZabbixAgent2.ps1

Update SMB/HTTPS Failover
This commit is contained in:
2026-09-10 14:59:32 +10:00
parent 809e5d7e6b
commit b1bd830b0c

View File

@@ -1,149 +1,193 @@
<# <#
.SYNOPSIS .SYNOPSIS
Standardized Zabbix Agent 2 Enterprise Deployer (V2 Fleet Reconciliation) Standardized Zabbix Agent 2 Enterprise Deployer (V2 Fleet Reconciliation)
#> #>
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
# --- 1. Versioned Idempotency Check --- # --- 1. Versioned Idempotency Check ---
$markerDir = "C:\ProgramData\Zabbix" $markerDir = "C:\ProgramData\Zabbix"
$marker = "$markerDir\installed_v2.flag" $marker = "$markerDir\installed_v2.flag"
$service = Get-Service -Name "Zabbix Agent 2" -ErrorAction SilentlyContinue $service = Get-Service -Name "Zabbix Agent 2" -ErrorAction SilentlyContinue
if ((Test-Path $marker) -and ($service -and $service.Status -eq "Running")) { if ((Test-Path $marker) -and ($service -and $service.Status -eq "Running")) {
exit 0 exit 0
} }
if (-not (Test-Path $markerDir)) { if (-not (Test-Path $markerDir)) {
New-Item -ItemType Directory -Path $markerDir -Force | Out-Null New-Item -ItemType Directory -Path $markerDir -Force | Out-Null
} }
# --- 2. Complete Network Subnet Resolution --- # --- 2. Complete Network Subnet Resolution ---
$localIPs = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notmatch '^(127\.|169\.254\.)' }).IPAddress $localIPs = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notmatch '^(127\.|169\.254\.)' }).IPAddress
# Node 1: 192.168.100.0/24 through 192.168.105.255 # Node 1: 192.168.100.0/24 through 192.168.105.255
if ($localIPs -match '^192\.168\.(10[0-5])\.') { if ($localIPs -match '^192\.168\.(10[0-5])\.') {
$Location = "Node1" $Location = "Node1"
$ZabbixServer = "192.168.101.30" $ZabbixServer = "192.168.101.30"
$ShareSource = "\\EHI-DC4\Zabbix" $ShareSource = "\\EHI-DC4\Zabbix"
} }
# Node 2: 192.168.130.0-135.255 AND 192.168.141.0-145.255 # Node 2: 192.168.130.0-135.255 AND 192.168.141.0-145.255
elseif ($localIPs -match '^192\.168\.(13[0-5]|14[1-5])\.') { elseif ($localIPs -match '^192\.168\.(13[0-5]|14[1-5])\.') {
$Location = "Node2" $Location = "Node2"
$ZabbixServer = "192.168.130.80" $ZabbixServer = "192.168.130.80"
$ShareSource = "\\E2HI-DC5\Zabbix" $ShareSource = "\\E2HI-DC5\Zabbix"
} }
# Brisbane: 192.168.3.0/24 AND 192.168.200.0/24 # Brisbane: 192.168.3.0/24 AND 192.168.200.0/24
elseif ($localIPs -match '^192\.168\.(3|200)\.') { elseif ($localIPs -match '^192\.168\.(3|200)\.') {
$Location = "Brisbane" $Location = "Brisbane"
$ZabbixServer = "192.168.3.43" $ZabbixServer = "192.168.3.43"
$ShareSource = "\\BI-DC1\Zabbix" $ShareSource = "\\BI-DC1\Zabbix"
} }
# Fallback Default to Node 1 # Fallback Default to Node 1
else { else {
$Location = "Node1" $Location = "Node1"
$ZabbixServer = "192.168.101.30" $ZabbixServer = "192.168.101.30"
$ShareSource = "\\EHI-DC4\Zabbix" $ShareSource = "\\EHI-DC4\Zabbix"
} }
# --- 3. Dynamic Hardware and Role Detection --- # --- 3. Dynamic Hardware and Role Detection ---
$osInfo = Get-CimInstance -ClassName Win32_OperatingSystem $osInfo = Get-CimInstance -ClassName Win32_OperatingSystem
$Hostname = $env:COMPUTERNAME $Hostname = $env:COMPUTERNAME
# Workstations # Workstations
if ($osInfo.ProductType -eq 1) { if ($osInfo.ProductType -eq 1) {
$Role = "Workstation" $Role = "Workstation"
} }
# Primary: Hostname matches SQL naming convention (e.g., EHTS-SS01, BI-SS02) # Primary: Hostname matches SQL naming convention (e.g., EHTS-SS01, BI-SS02)
elseif ($Hostname -match '-ss\d*') { elseif ($Hostname -match '-ss\d*') {
$Role = "SQL" $Role = "SQL"
} }
# Primary: Hostname matches Application naming convention (e.g., EHTS-APP38) # Primary: Hostname matches Application naming convention (e.g., EHTS-APP38)
elseif ($Hostname -match '-app\d*') { elseif ($Hostname -match '-app\d*') {
$Role = "Application" $Role = "Application"
} }
# Secondary Fallback: Active MSSQLSERVER service on unstandardized server names # Secondary Fallback: Active MSSQLSERVER service on unstandardized server names
elseif (Get-Service -Name "MSSQLSERVER" -ErrorAction SilentlyContinue | Where-Object { $_.Status -eq "Running" }) { elseif (Get-Service -Name "MSSQLSERVER" -ErrorAction SilentlyContinue | Where-Object { $_.Status -eq "Running" }) {
$Role = "SQL" $Role = "SQL"
} }
# Default fallback for DCs, utilities, and general servers # Default fallback for DCs, utilities, and general servers
else { else {
$Role = "Application" $Role = "Application"
} }
$HardwareType = if ((Get-CimInstance -ClassName Win32_ComputerSystem).Model -match "Virtual|VMware|KVM|Hyper-V") { $HardwareType = if ((Get-CimInstance -ClassName Win32_ComputerSystem).Model -match "Virtual|VMware|KVM|Hyper-V") {
"VM" "VM"
} else { } else {
"Physical" "Physical"
} }
$MetadataVal = "Windows:$($HardwareType):$($Location):$($Role)" $MetadataVal = "Windows:$($HardwareType):$($Location):$($Role)"
# --- 4. File Pull from Local DC Share --- # --- 4. File Acquisition with Multi-Tier Fallback (SMB -> Git -> CDN) ---
$SourceZip = "$ShareSource\zabbix_agent2.zip" $SourceZip = "$ShareSource\zabbix_agent2.zip"
$InstallDir = "C:\Program Files\Zabbix Agent 2" $GitZipUrl = "https://git.mkau.au/DistractADD/zabbix/raw/branch/main/zabbix_agent2.zip"
$TempZip = "C:\Temp\zabbix_agent2.zip" $CdnZipUrl = "https://cdn.zabbix.com/zabbix/binaries/stable/7.4/7.4.11/zabbix_agent2-7.4.11-windows-amd64-openssl-static.zip"[cite: 1, 3, 4, 5]
$InstallDir = "C:\Program Files\Zabbix Agent 2"[cite: 1, 3, 4, 5]
if (-not (Test-Path "C:\Temp")) { New-Item -ItemType Directory -Path "C:\Temp" -Force | Out-Null } $TempZip = "C:\Temp\zabbix_agent2.zip"[cite: 1, 3, 4, 5]
# Stop running instances safely before touching binaries if (-not (Test-Path "C:\Temp")) { New-Item -ItemType Directory -Path "C:\Temp" -Force | Out-Null }[cite: 1, 3, 4, 5]
Get-Service "Zabbix Agent*" -ErrorAction SilentlyContinue | Stop-Service -Force -ErrorAction SilentlyContinue
Get-Process "zabbix_agent*" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue # Stop running instances safely before replacing binaries
Get-Service "Zabbix Agent*" -ErrorAction SilentlyContinue | Stop-Service -Force -ErrorAction SilentlyContinue[cite: 1, 3, 4, 5]
Copy-Item -Path $SourceZip -Destination $TempZip -Force Get-Process "zabbix_agent*" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue[cite: 1, 3, 4, 5]
if (Test-Path $InstallDir) { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12[cite: 1, 3, 4, 5]
Remove-Item $InstallDir -Recurse -Force -ErrorAction SilentlyContinue $acquired = $false
}
New-Item -Path $InstallDir -ItemType Directory -Force | Out-Null # Attempt 1: Local DC SMB Share
try {
Expand-Archive -Path $TempZip -DestinationPath $InstallDir -Force if (Test-Path $SourceZip -ErrorAction Stop) {
Copy-Item -Path $SourceZip -Destination $TempZip -Force -ErrorAction Stop
$BinDir = Get-ChildItem -Path $InstallDir -Recurse | Where-Object { $_.Name -eq "zabbix_agent2.exe" } | Select-Object -ExpandProperty DirectoryName if ((Test-Path $TempZip) -and ((Get-Item $TempZip).Length -gt 1000000)) {
if ($BinDir -ne $InstallDir) { $acquired = $true
Copy-Item -Path "$BinDir\*" -Destination $InstallDir -Recurse -Force }
} }
}
# --- 5. Generate Standardized Configuration --- catch {
$ConfigContent = @" # SMB failed or blocked
LogType=file }
LogFile=$InstallDir\zabbix_agent2.log
Server=$ZabbixServer # Attempt 2: Internal Git Server (Ideal for firewalled/isolated subnets)
ServerActive=$ZabbixServer if (-not $acquired) {
Hostname=$Hostname try {
HostMetadata=$MetadataVal Write-Host "SMB inaccessible. Downloading agent archive from internal Git..." -ForegroundColor Yellow
AllowKey=system.run[*] Invoke-WebRequest -Uri $GitZipUrl -OutFile $TempZip -UseBasicParsing -TimeoutSec 30 -ErrorAction Stop
Timeout=30 if ((Test-Path $TempZip) -and ((Get-Item $TempZip).Length -gt 1000000)) {
ControlSocket=\\.\pipe\agent.sock $acquired = $true
"@ }
Set-Content -Path "$InstallDir\zabbix_agent2.conf" -Value $ConfigContent }
catch {
# --- 6. Service Installation & Startup --- # Git raw zip not present or timed out
$ExePath = "$InstallDir\zabbix_agent2.exe" }
$ConfPath = "$InstallDir\zabbix_agent2.conf" }
$existingService = Get-Service -Name "Zabbix Agent 2" -ErrorAction SilentlyContinue # Attempt 3: Official Zabbix CDN Fallback
if (-not $acquired) {
if (-not $existingService) { try {
# Remove orphan Event Log key if left behind by prior uninstalls or sc delete Write-Host "Git archive download failed. Falling back to official Zabbix CDN..." -ForegroundColor Yellow
Remove-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Application\Zabbix Agent 2" -Recurse -Force -ErrorAction SilentlyContinue Invoke-WebRequest -Uri $CdnZipUrl -OutFile $TempZip -UseBasicParsing -TimeoutSec 60 -ErrorAction Stop[cite: 1, 3, 4, 5]
if ((Test-Path $TempZip) -and ((Get-Item $TempZip).Length -gt 1000000)) {
# Register the service for the first time $acquired = $true
& $ExePath --config "$ConfPath" --install }
Start-Sleep -Seconds 2 }
} catch {
throw "Critical: Failed to acquire Zabbix Agent archive via SMB, internal Git, or external CDN."
# Ensure service is started and set to automatic }
Start-Service "Zabbix Agent 2" -ErrorAction SilentlyContinue }
Set-Service -Name "Zabbix Agent 2" -StartupType Automatic
if (Test-Path $InstallDir) {
# --- 7. Firewall Rules --- Remove-Item $InstallDir -Recurse -Force -ErrorAction SilentlyContinue[cite: 1, 3, 4, 5]
if (-not (Get-NetFirewallRule -DisplayName "Zabbix Agent Inbound" -ErrorAction SilentlyContinue)) { }
New-NetFirewallRule -DisplayName "Zabbix Agent Inbound" -Direction Inbound -LocalPort 10050 -Protocol TCP -Action Allow -Profile Any | Out-Null New-Item -Path $InstallDir -ItemType Directory -Force | Out-Null[cite: 1, 3, 4, 5]
}
if (-not (Get-NetFirewallRule -DisplayName "Zabbix Agent Outbound" -ErrorAction SilentlyContinue)) { Expand-Archive -Path $TempZip -DestinationPath $InstallDir -Force[cite: 1, 3, 4, 5]
New-NetFirewallRule -DisplayName "Zabbix Agent Outbound" -Direction Outbound -RemotePort 10051 -Protocol TCP -Action Allow -Profile Any | Out-Null
} $BinDir = Get-ChildItem -Path $InstallDir -Recurse | Where-Object { $_.Name -eq "zabbix_agent2.exe" } | Select-Object -ExpandProperty DirectoryName[cite: 1, 3, 4, 5]
if ($BinDir -ne $InstallDir) {
# --- 8. Finalize V2 State --- Copy-Item -Path "$BinDir\*" -Destination $InstallDir -Recurse -Force[cite: 1, 3, 4, 5]
New-Item -ItemType File -Path $marker -Force | Out-Null }
# --- 5. Generate Standardized Configuration ---
$ConfigContent = @"
LogType=file
LogFile=$InstallDir\zabbix_agent2.log
Server=$ZabbixServer
ServerActive=$ZabbixServer
Hostname=$Hostname
HostMetadata=$MetadataVal
AllowKey=system.run[*]
Timeout=30
ControlSocket=\\.\pipe\agent.sock
"@
Set-Content -Path "$InstallDir\zabbix_agent2.conf" -Value $ConfigContent
# --- 6. Service Installation & Startup ---
$ExePath = "$InstallDir\zabbix_agent2.exe"
$ConfPath = "$InstallDir\zabbix_agent2.conf"
$existingService = Get-Service -Name "Zabbix Agent 2" -ErrorAction SilentlyContinue
if (-not $existingService) {
# Remove orphan Event Log key if left behind by prior uninstalls or sc delete
Remove-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Application\Zabbix Agent 2" -Recurse -Force -ErrorAction SilentlyContinue
# Register the service for the first time
& $ExePath --config "$ConfPath" --install
Start-Sleep -Seconds 2
}
# Ensure service is started and set to automatic
Start-Service "Zabbix Agent 2" -ErrorAction SilentlyContinue
Set-Service -Name "Zabbix Agent 2" -StartupType Automatic
# --- 7. Firewall Rules ---
if (-not (Get-NetFirewallRule -DisplayName "Zabbix Agent Inbound" -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -DisplayName "Zabbix Agent Inbound" -Direction Inbound -LocalPort 10050 -Protocol TCP -Action Allow -Profile Any | Out-Null
}
if (-not (Get-NetFirewallRule -DisplayName "Zabbix Agent Outbound" -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -DisplayName "Zabbix Agent Outbound" -Direction Outbound -RemotePort 10051 -Protocol TCP -Action Allow -Profile Any | Out-Null
}
# --- 8. Finalize V2 State ---
New-Item -ItemType File -Path $marker -Force | Out-Null
Remove-Item -Path $TempZip -Force -ErrorAction SilentlyContinue Remove-Item -Path $TempZip -Force -ErrorAction SilentlyContinue