385 lines
9.5 KiB
PowerShell
385 lines
9.5 KiB
PowerShell
function Install-ZabbixAgent2 {
|
|
<#
|
|
.Synopsis
|
|
Install Zabbix Agent 2
|
|
.DESCRIPTION
|
|
Download and install Zabbix Agent 2 with autoconfiguration for Active Directory domains.
|
|
Configuration and log files are moved to $env:APPDATA as it is a preffered place to store application
|
|
data and also avoids access to them for unpriviliged users
|
|
.EXAMPLE
|
|
Install-ZabbixAgent2 -ForceRemove -ProxyFQDN mycoolproxy.contoso.local -EnableAllowKeySystemRun
|
|
Remove any installed Agent, explicitly configure proxy name
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param (
|
|
|
|
# FQDN of Zabbix proxy (or Server)
|
|
$ProxyFQDN,
|
|
|
|
# Prefix for domain name to use, include the dot at the end plz
|
|
$ProxyPrefix = 'proxy01.zabbix.',
|
|
|
|
# Remove any installed Agent on the machine (otherwise execution will be aborted)
|
|
[switch]
|
|
$ForceRemove,
|
|
|
|
# URI of Agent installer, if not set the hardcoded path set in Get-ZabbixAgentInstaller would be used
|
|
$PackageSourceURI,
|
|
|
|
# Force download the installer even if there is a local one found
|
|
[switch]
|
|
$ForceDownload,
|
|
|
|
# Enable AllowKey=system.run[*] in the configuration of the Agent
|
|
[switch]
|
|
$EnableAllowKeySystemRun,
|
|
|
|
# Installer name
|
|
$InstallerName = 'ZabbixAgent2.zip'
|
|
|
|
)
|
|
$VerbosePreference=2
|
|
#region preinit
|
|
|
|
#Start-Transcript -Append -Path C:\ProgramData\Zabbix\installer\Install-ZabbixAgent2.AllInOne.ps1.txt
|
|
$Transcript = Start-Transcript
|
|
|
|
$flagShouldRunRemoveAgent = $false
|
|
$flagShouldDownloadInstaller = $false
|
|
|
|
#endregion
|
|
|
|
|
|
#region preinstall
|
|
|
|
# check parameters
|
|
|
|
if ($ProxyFQDN) {
|
|
# Proxy FQDN is set
|
|
}
|
|
else {
|
|
$cdm = Get-ComputerDomainMembership
|
|
if ($cdm.IsDomainMember) {
|
|
$ProxyFQDN = '{0}{1}' -f $ProxyPrefix, $cdm.Domain
|
|
}
|
|
else {
|
|
$msg = 'No Proxy FQDN defined and computer is not a domain member! Aborting, transcript path: {0}' -f $Transcript.Path
|
|
Stop-Transcript
|
|
throw $msg
|
|
|
|
}
|
|
}
|
|
|
|
# check if Agent is already installed
|
|
|
|
if ($ForceRemove -eq $true) {
|
|
# flag what the removal should be called
|
|
$flagShouldRunRemoveAgent = $true
|
|
|
|
}
|
|
|
|
elseif ($checkService = Get-Service -name 'Zabbix*' -ErrorAction SilentlyContinue | ? Name -match 'Zabbix\s+Agent.+?') {
|
|
|
|
if ($ForceRemove -eq $true) {
|
|
|
|
# flag what the removal should be called
|
|
$flagShouldRunRemoveAgent = $true
|
|
Write-Verbose 'Installed agent detected, would be removed per ForceRemove parameter'
|
|
|
|
}
|
|
else {
|
|
|
|
$msg = 'There is an installed Agent, but ForceRemove is not set. Aborting, transcript path: {0}' -f $Transcript.Path
|
|
Stop-Transcript
|
|
throw $msg
|
|
|
|
}
|
|
|
|
} #end if checkservice
|
|
|
|
|
|
#endregion
|
|
|
|
#region folders
|
|
|
|
<#
|
|
FolderStructure:
|
|
$env:ProgramData
|
|
$orgName
|
|
installer
|
|
$productName
|
|
conf
|
|
conf/zabbix_agent2.d
|
|
tls
|
|
log
|
|
#>
|
|
|
|
$nameOrg = 'Zabbix'
|
|
$nameProduct = 'Agent2'
|
|
|
|
$fOrg = Join-Path $env:ProgramData $nameOrg
|
|
$fProduct = Join-Path $fOrg $nameProduct
|
|
$fInstaller = Join-Path $fOrg installer
|
|
|
|
$folder = [ordered]@{
|
|
Org = $fOrg
|
|
Installer = $fInstaller
|
|
Product = $fProduct
|
|
Bin = Join-Path $fProduct 'bin'
|
|
Conf = Join-Path $fProduct 'conf'
|
|
ConfD = Join-Path (Join-Path $fProduct 'conf') 'zabbix_agent2.d'
|
|
Tls = Join-Path $fProduct 'tls'
|
|
Log = Join-Path $fProduct 'log'
|
|
}
|
|
|
|
|
|
try {
|
|
|
|
foreach ($thisFolder in $folder.Values) {
|
|
|
|
if (Test-Path $thisFolder) {
|
|
|
|
Write-Verbose ('Path {0} already exists' -f $thisFolder)
|
|
|
|
}
|
|
else {
|
|
|
|
New-Item -Path $thisFolder -ItemType Directory -ErrorAction Stop
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
catch {
|
|
$msg = "Can't create folder {0}. Aborting, transcript path: {1}" -f $thisFolder, $Transcript.Path
|
|
Stop-Transcript
|
|
throw $msg
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region download
|
|
|
|
$splat = @{
|
|
FileName = $InstallerName
|
|
}
|
|
|
|
if ($PackageSourceURI) {
|
|
$splat.add('SourceURI',$PackageSourceURI)
|
|
}
|
|
|
|
$installerPath = Join-Path $folder['installer'] $InstallerName
|
|
|
|
if (Test-Path $installerPath) {
|
|
Write-Verbose ('Checking installer at {0}' -f $installerPath)
|
|
if ($ForceDownload) {
|
|
Write-Verbose ("Local installer found at {0}, but ForceDownload is set" -f $installerPath)
|
|
$flagShouldDownloadInstaller = $true
|
|
}
|
|
else {
|
|
Write-Verbose ("Local installer found at {0}" -f $installerPath)
|
|
$installer = Get-Item $installerPath
|
|
}
|
|
|
|
}
|
|
else {
|
|
$flagShouldDownloadInstaller = $true
|
|
}
|
|
|
|
if ($flagShouldDownloadInstaller) {
|
|
if ($VerbosePreference -eq 'Continue') {
|
|
Write-Verbose 'splat for get package:'
|
|
$splat
|
|
|
|
}
|
|
try {
|
|
$installer = Get-ZabbixAgentPackage @splat -ErrorAction Stop
|
|
$installer = Move-Item -LiteralPath $installer.FullName -Destination $folder['installer'] -PassThru -Force
|
|
}
|
|
|
|
catch {
|
|
$msg = 'Downloading Agent installer failed. Aborting, transcript path: {0}' -f $Transcript.Path
|
|
Stop-Transcript
|
|
throw $msg
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region unpack
|
|
|
|
try {
|
|
$Unpacked = Expand-ZabbixAgentPackage $installer.FullName
|
|
Gci -Filter *.exe -Path $Unpacked.fullname -Recurse -Verbose | % {
|
|
Move-Item -Path $_.FullName -Destination $folder['bin'] -Verbose
|
|
}
|
|
|
|
}
|
|
|
|
catch {
|
|
$msg = 'Failed to unpack the package. Aborting, transcript path: {0}' -f $Transcript.Path
|
|
Stop-Transcript
|
|
throw $msg
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region remove installed
|
|
|
|
if ($flagShouldRunRemoveAgent) {
|
|
Write-Verbose 'Removing the installed Agent'
|
|
Remove-ZabbixAgent
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region generate config
|
|
|
|
$mainConfigPath = (Join-Path $folder['conf'] zabbix_agent2.conf)
|
|
|
|
$mainConfigPathContent = 'Include={0}' -f ((Join-Path $folder['confd'] '*.conf'))
|
|
|
|
# write out the default configuration file
|
|
|
|
Set-Content -Value $mainConfigPathContent -Path $mainConfigPath
|
|
|
|
# shorthand to write the configuration settings to a separate files
|
|
|
|
filter WriteConf {
|
|
param (
|
|
$filename
|
|
)
|
|
|
|
if ($filename -notmatch '\.conf') {
|
|
$filename = $filename + '.conf'
|
|
}
|
|
|
|
$_ | Set-Content (Join-Path $folder['confd'] $filename)
|
|
}
|
|
|
|
function ConfigFileParameter {
|
|
[CmdletBinding()]
|
|
[Alias('ap')]
|
|
[OutputType([string])]
|
|
Param (
|
|
[string]
|
|
$Name,
|
|
[string]
|
|
$Value
|
|
)
|
|
|
|
'{0}={1}' -f $Name, $Value
|
|
|
|
}
|
|
|
|
|
|
$ZabbixAgentHostname = Generate-ZabbixAgentHostname
|
|
|
|
ap Hostname $ZabbixAgentHostname | WriteConf 10-hostname
|
|
|
|
ap Server $ProxyFQDN | WriteConf 11-server
|
|
ap ServerActive $ProxyFQDN | WriteConf 12-serveractive
|
|
|
|
|
|
$logFilePath = Join-Path $folder['log'] zabbix_agent2.log
|
|
|
|
ap LogFile $logFilePath | WriteConf 21-logfile
|
|
ap LogFileSize 32 | WriteConf 22-logfilesize
|
|
|
|
ap ForceActiveChecksOnStart 1 | WriteConf 31-forceactivechecksonstart
|
|
|
|
if ($EnableAllowKeySystemRun) {
|
|
'AllowKey=system.run[*]' | WriteConf 69-allowkeysystemrun
|
|
}
|
|
|
|
# default built-in
|
|
'ControlSocket=\\.\pipe\agent.sock' | WriteConf 99-controlsocket
|
|
|
|
# configure tls
|
|
|
|
'Include={0}' -f ((Join-Path $folder['tls'] '*.conf')) | WriteConf 99-tls
|
|
|
|
ap TLSAccept 'unencrypted,psk' | Set-Content (Join-Path $folder['tls'] 70-tlsaccept.conf)
|
|
ap TLSConnect unencrypted | Set-Content (Join-Path $folder['tls'] 71-tlsconnect.conf)
|
|
ap TLSPSKIdentity $ZabbixAgentHostname | Set-Content (Join-Path $folder['tls'] 72-tlspskidentity.conf)
|
|
ap TLSPSKFile (Join-Path $folder['tls'] psk.key) | Set-Content (Join-Path $folder['tls'] 73-tlspskfile.conf)
|
|
|
|
# simple psk key
|
|
(new-guid) -replace '\W' | Set-Content (Join-Path $folder['tls'] psk.key)
|
|
|
|
|
|
#endregion
|
|
|
|
Write-Verbose "Adding firewall rules"
|
|
|
|
Add-ZabbixFirewallRules -FilePath (Join-Path $folder['bin'] zabbix_agent2.exe)
|
|
|
|
#region installstartservice
|
|
|
|
|
|
|
|
try {
|
|
Write-Verbose 'Registering Service'
|
|
$AgentExecutable = Join-Path $folder['bin'] zabbix_agent2.exe
|
|
|
|
$AgentArguments = '-i', '-c', $mainConfigPath
|
|
|
|
Start-Process -Wait -FilePath $AgentExecutable -ArgumentList $AgentArguments
|
|
}
|
|
catch {
|
|
$msg = 'Tried to install the service with binary {0} and arguments {1}' -f $AgentExecutable, $AgentArguments
|
|
Stop-Transcript
|
|
throw $msg
|
|
|
|
}
|
|
|
|
try {
|
|
$Service = Get-Service -Name 'Zabbix Agent 2'
|
|
|
|
Set-ServiceRecoveryAction 'Zabbix Agent 2'
|
|
|
|
Start-Service -Name $service.Name
|
|
|
|
}
|
|
catch {
|
|
$msg = "Couldn't start the service"
|
|
Stop-Transcript
|
|
throw $msg
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region security
|
|
|
|
try {
|
|
Write-Verbose "Setting the security permissions"
|
|
|
|
$admins = Translate-SidToNTAccount S-1-5-32-544
|
|
$users = Translate-SidToNTAccount S-1-5-32-545
|
|
$system = Translate-SidToNTAccount S-1-5-18
|
|
|
|
Set-FileSystemPermission -Path $fOrg -Identity $system -Permission FullControl
|
|
Set-FileSystemPermission -Path $fOrg -Identity $users -Permission ReadAndExecute -Inheritance ContainerInherit
|
|
Set-FileSystemPermission -Path ($folder['bin']) -Identity $users -Permission ReadAndExecute
|
|
Set-FileSystemPermission -Path $fOrg -Identity $admins -Permission FullControl -BreakInheritance
|
|
|
|
}
|
|
catch {
|
|
$_
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
Write-Verbose "Finished succesfully"
|
|
|
|
Stop-Transcript
|
|
|
|
Move-Item $Transcript.Path -Destination (Join-Path $folder['log'] $MyInvocation.MyCommand) -Force -PassThru
|
|
}
|