## Das history goes here # Self-elevate the script if required if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) { if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) { $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine Exit } } # Needs TLS 1.2 now [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # Create and change directory New-Item -ItemType Directory -Force -Path $env:ProgramFiles\Zabbix Set-Location $env:ProgramFiles\Zabbix # Download and unpack Zabbix agent $DOWNLOADURL = "https://cdn.zabbix.com/zabbix/binaries/stable/5.0/5.0.11/zabbix_agent-5.0.11-windows-amd64-openssl.zip" $helper = New-Object System.Net.WebClient $helper.DownloadFile($DOWNLOADURL, "$env:ProgramFiles\Zabbix\agent.zip") Expand-Archive -LiteralPath "$env:ProgramFiles\Zabbix\agent.zip" -DestinationPath "$env:ProgramFiles\Zabbix\" # Q&A for setup Write-Host "" Write-Host "Please answer the following questions to install Zabbix Agent on Windows" Write-Host "" $HOSTNAME = Read-Host "Please enter the hostname of this system as configured in Zabbix UI [$env:computername]" if ([String]::IsNullOrWhiteSpace($HOSTNAME)) { $HOSTNAME = $env:computername } $PROXY_IP = Read-Host "Enter DNS name or IP of Zabbix Proxy or Server that will monitor this agent" $AUTO_AGENT_IP = (Get-NetIPAddress -AddressFamily IPv4 | where { $_.AddressState -eq "Preferred" -and $_.InterfaceAlias -notmatch "Loopback" -and $_.IPv4Address -notlike "169.*" }).IPv4Address $AGENT_IP = Read-Host "Enter local IP of THIS agent that the proxy/server will connect to [$AUTO_AGENT_IP]" if ([String]::IsNullOrWhiteSpace($AGENT_IP)) { $AGENT_IP = $AUTO_AGENT_IP } $ALLOW_REMOTE_COMMANDS = Read-Host "Allow remote commands? [Yn]" if ([String]::IsNullOrWhiteSpace($ALLOW_REMOTE_COMMANDS)) { $ALLOW_REMOTE_COMMANDS = "Y" } if ($ALLOW_REMOTE_COMMANDS -ilike "n*") { $ALLOW_REMOTE_COMMANDS = "0" } else { $ALLOW_REMOTE_COMMANDS = "1" } Write-Host "" $AUTO_CREATE_HOST = Read-Host "Automatically add this host to Zabbix? [Yn]" if ([String]::IsNullOrWhiteSpace($AUTO_CREATE_HOST)) { $AUTO_CREATE_HOST = "Y" } # If auto-add selected, do it if ($AUTO_CREATE_HOST -eq "Y" -or $AUTO_CREATE_HOST -eq "y") { # Get URL $AUTO_URL = Read-Host "Enter URL for Zabbix UI: [https://zabbix.futuresens.co.uk]" if ([String]::IsNullOrWhiteSpace($AUTO_URL)) { $AUTO_URL = "https://zabbix.futuresens.co.uk" } $AUTO_URL = $AUTO_URL.TrimEnd("/") + "/api_jsonrpc.php" Write-Host "Connecting to $AUTO_URL" # Get and check authentication while ($AUTH_KEY.result -eq $null) { Write-Host "" $AUTO_ZBX_USERNAME = Read-Host "Enter your Zabbix username" $AUTO_ZBX_PASSWORD = Read-Host -AsSecureString "Enter your Zabbix password" Write-Host "Checking authentication..." $AUTH_BODY = @{ "jsonrpc" = "2.0"; "method" = "user.login"; "params" = @{ "user" = $AUTO_ZBX_USERNAME "password" = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($AUTO_ZBX_PASSWORD)) }; "id" = "1"; } $AUTH_KEY = Invoke-RestMethod -Method Post -Uri $($AUTO_URL) -ContentType "application/json-rpc" -Body (ConvertTo-Json $AUTH_BODY) if ( $AUTH_KEY.error -ne $null ) {Write-Host "error: "$AUTH_KEY.error.message } } # Generate PSKID and PSK $AGENT_PSKID = ([guid]::NewGuid()).Guid.ToString() $AGENT_PSK = ([guid]::NewGuid()).Guid -replace '[-]','' Set-Content -Path "$env:ProgramFiles\Zabbix\conf\zabbixagent.psk" -Value $AGENT_PSK # Edit settings to match Q&A above $CONF_PATH = "$env:ProgramFiles\Zabbix\conf\zabbix_agentd.conf" (Get-Content -Path $CONF_PATH) -Replace "^Server=.*$","Server=zabbix.futuresens.co.uk" | Set-Content -Path $CONF_PATH (Get-Content -Path $CONF_PATH) -Replace "^ServerActive=.*$","ServerActive=zabbix.futuresens.co.uk" | Set-Content -Path $CONF_PATH (Get-Content -Path $CONF_PATH) -Replace "^Hostname=.*$","Hostname=$HOSTNAME" | Set-Content -Path $CONF_PATH (Get-Content -Path $CONF_PATH) -Replace "^# EnableRemoteCommands=.*","EnableRemoteCommands=$ALLOW_REMOTE_COMMANDS" | Set-Content -Path $CONF_PATH (Get-Content -Path $CONF_PATH) -Replace "^# LogRemoteCommands=.*","LogRemoteCommands=$ALLOW_REMOTE_COMMANDS" | Set-Content -Path $CONF_PATH (Get-Content -Path $CONF_PATH) -Replace "^# TLSConnect=.*","TLSConnect=unencrypted" | Set-Content -Path $CONF_PATH (Get-Content -Path $CONF_PATH) -Replace "^# TLSAccept=.*","TLSAccept=unencrypted" | Set-Content -Path $CONF_PATH (Get-Content -Path $CONF_PATH) -Replace "^# TLSPSKIdentity=.*","TLSPSKIdentity=$AGENT_PSKID" | Set-Content -Path $CONF_PATH (Get-Content -Path $CONF_PATH) -Replace "^# TLSPSKFile=.*","TLSPSKFile=$env:ProgramFiles\Zabbix\conf\zabbixagent.psk" | Set-Content -Path $CONF_PATH (Get-Content -Path $CONF_PATH) -Replace "^# Timeout=.*","Timeout=30" | Set-Content -Path $CONF_PATH # Check in to zabbix server # Get Group ID for group "AutoRegistration/Windows Hosts". $REQ_BODY = @{ "jsonrpc" = "2.0"; "method" = "hostgroup.get"; "params" = @{ "filter" = @{ "name" = @( "AutoRegistration/Windows Hosts" ) } } "id" = "5"; "auth" = $AUTH_KEY.result } $REQ_BODY = (ConvertTo-Json -Depth 8 $REQ_BODY).ToString() $AUTOREG_GROUP_ID = Invoke-RestMethod -Method Post -Uri $($AUTO_URL) -ContentType "application/json-rpc" -Body ($REQ_BODY) # Create the group if it doesn't exist. if ($AUTOREG_GROUP_ID.result.Length -eq 0) { $REQ_BODY = @{ "jsonrpc" = "2.0"; "method" = "hostgroup.create"; "params" = @{ "name" = "AutoRegistration/Windows Hosts" } "id" = "6"; "auth" = $AUTH_KEY.result } $REQ_BODY = (ConvertTo-Json -Depth 8 $REQ_BODY).ToString() $AUTOREG_GROUP_ID = Invoke-RestMethod -Method Post -Uri $($AUTO_URL) -ContentType "application/json-rpc" -Body ($REQ_BODY) $AUTOREG_GROUP_ID = $AUTOREG_GROUP_ID.result[0].groupids[0] } else { $AUTOREG_GROUP_ID = $AUTOREG_GROUP_ID.result[0].groupid } # Create the agent in Zabbix $REQ_BODY = @{ "jsonrpc" = "2.0"; "method" = "host.create"; "params" = @{ "host" = $HOSTNAME; "interfaces" = @( @{ "type" = 1; "main" = 1; "useip" = 1; "ip" = "$AGENT_IP"; "dns" = ""; "port" = "10050"; } ) "groups" = @( @{ "groupid" = $AUTOREG_GROUP_ID } ) "tls_accept" = 2; "tls_connect" = 2; "tls_psk_identity" = $AGENT_PSKID; "tls_psk" = $AGENT_PSK; } "id" = "8"; "auth" = $AUTH_KEY.result } $REQ_BODY = (ConvertTo-Json -Depth 8 $REQ_BODY).ToString() $CREATED_AGENT_ID = Invoke-RestMethod -Method Post -Uri $($AUTO_URL) -ContentType "application/json-rpc" -Body ($REQ_BODY) Write-Host "" if ($CREATED_AGENT_ID.error.code -eq -32602) # Host already exists { Write-Host "The agent $HOSTNAME already exists in Zabbix" Write-Host "You will need to manually update the existing agent $HOSTNAME in Zabbix to use the PSKID: $AGENT_PSKID and PSK: $AGENT_PSK" } elseif ($CREATED_AGENT_ID.error.code -eq -32500) # No permission { Write-Host "You do not have permission to create hosts in Zabbix. You must be Zabbix Admin to do this." Write-Host "You will need to ask an Admin to manually add the host $HOSTNAME to Zabbix using the PSKID: $AGENT_PSKID and PSK: $AGENT_PSK" } # Install and run Zabbix service & "$env:ProgramFiles\Zabbix\bin\zabbix_agentd.exe" -i -c "$env:ProgramFiles\Zabbix\conf\zabbix_agentd.conf" Write-Host "Restarting Zabbix Agent for changes to take effect" Restart-Service "Zabbix Agent" # Log out of Zabbix and clear password $AUTH_BODY = @{ "jsonrpc" = "2.0"; "method" = "user.logout"; "params" = @(); "id" = "99"; "auth" = $AUTH_KEY.result } $AUTH_KEY = Invoke-RestMethod -Method Post -Uri $($AUTO_URL) -ContentType "application/json-rpc" -Body (ConvertTo-Json $AUTH_BODY) $AUTH_KEY = "" $AUTO_ZBX_PASSWORD = "" Write-Host "" Write-Host "Zabbix Agent has been successfully installed on $HOSTNAME." Write-Host "The following PSK values were used - PSKID: $AGENT_PSKID and PSK: $AGENT_PSK" Write-Host "You must now log in to Zabbix and do the following:" Write-Host " 1) Move $HOSTNAME from 'AutoRegistration/Windows Hosts' to the appropriate group(s)" Write-Host " 2) Add items and triggers (usually via a template)" Write-Host " 3) Set $HOSTNAME to be monitored by the appropriate proxy (if required)" Write-Host "" Read-Host "Press return to quit." }