Agent Auto Updater
Aus znilwiki
Download: Media:AgentAutoUpdater.zip
Changelog / Versionsinformationen:
- 09.04.2014: Erste öffentliche Version V1.0.0.97
Vorwort
Ich baue fast ständig neue Sachen per UserParameter in den Zabbix-Agenten ein.
Natürlich ist dann blöd wenn ich dann auf 100 Kundenserver einzeln die Konfigurationsdatei des Agenten ändern und diesen dann neu starten müsste.
Das habe ich schon länger dadurch gelöst das ich es einfach im Installationsscript geändert habe und die neue Version dann einfach über die alte Installiert wurde.
Nun muss ich dann immer noch auf 100 Server um das Installationsskript anzustoßen wenn man keine Softwareverteilung hat.
Zudem hätte man die Updates natürlich gerne zeitnah.
Deshalb habe ich mir eine "AgentAutoUpdate.exe" geschrieben die das für mich macht.
Selbstverständlich gibt es auch ein Template dazu in welchem man sehen kann wann das letzte Update war.
Funktionsweise
- Bei der Installation wird die AgentAutoUpdate.exe in die Aufgabenplanung/geplante Task eingetragen und regelmäßig gestartet
- Die AgentAutoUpdate.exe bekommt dazu 2 Parameter
- 1. Eine Netzwerkfreigabe, ggf. mit Unterordner
- bei jedem Aufruf wird eine Liste aller Dateien(!)(nicht Ordner!) erstellt. Dabei werden auch alle Dateien in Unterverzeichnissen etc. gefunden
- Anschliessend wird jede Datei eingelesen und der MD5 Hash ermittelt
- Dann wird der Hash-Wert für jede Datei mit dem Wert von der letzten Prüfung verglichen - die Werte werden in der Registry gespeichert
- Weicht auch nur ein Wert ab oder wird nicht gefunden wird
- für jede Datei der neue Wert in der Registry gespeichert
- der Zabbix-Agent beendet (Wenn der Name des Dienstes "Zabbix Agent" ist, welches der Standardname ist)
- Danach für jede Datei im Verzeichnis geprüft ob es einen Prozess mit gleichen Namen gibt. Wenn ja wird dieser beendet. Sich selbst überspringt er aber
- Dann wird der 2. Parameter ausgeführt.
- Klappt die Ausführung:
- beendet er sich selbst
- Wenn nicht werden die Registrywerte wieder gelöscht damit es einen neuen Versuch gibt
- 1. Eine Netzwerkfreigabe, ggf. mit Unterordner
- Der 2. Parameter ist das Installationsprogramm oder Skript für die Installtion des Agenten
Der Updater besteht aus 2 Dateien:
- AgentAutoUpdate.exe
- AgentAutoUpdate64.exe
Beide sind identisch - außer das die zweite als 64Bit kompiliert wurde. Ihr nehmt IMMER die normale Version! Tragt diese in die Aufgabenplanung oder eure Skripte ein!
Die 64 Bit Version wird bei Bedarf von der normalen (32Bit) Version aufgerufen. Dies ist nötig beim Aufruf des Installationsskriptes / Programmes auf 64Bit Systemen ... sonst funktioniert z.B. in meinem Installationsskript die 32/64 Bit Erkennung nicht mehr etc.
Fertiges Paket
Ihr könnt euch das für eigene Installationsweisen von Hand zusammenbauen - oder ihr nehmt mein fertiges Skript in welchen der Updater auch schon eingebaut ist:
- Webseite: Zabbix Agent für Windows per Skript automatisch installieren Musterdatei
- Download: InstallZabbixAgent.zip
Parameter
Auf Updates prüfen und ggf. Installation starten:
AgentAutoUpdate.exe <Pfad-zum-Ordner> <Pfad-zum-Installationsprogramm>
Beispiele:
AgentAutoUpdate.exe \\server.domain.suffix\Freigabe \\server.domain.suffix\Freigabe\InstallZabbixAgent.bat AgentAutoUpdate.exe \\server.domain.suffix\Freigabe\Ordner\Unterordner \\server.domain.suffix\Freigabe\Ordner\Unterordner\InstallZabbixAgent.bat AgentAutoUpdate.exe \\10.11.12.13\Freigabe \\10.11.12.13\Freigabe\InstallZabbixAgent.bat
Datum und Uhrzeit des letzten Updates abfragen:
AgentAutoUpdate.exe lasttime
Beispielausgabe:
1395955579
Die Rückgabe ist ein UNIX-Timestamp - damit kann Zabbix prima umgehen
Datum und Uhrzeit des letzten Updates manuell auf jetzigen Zeitpunkt setzen
AgentAutoUpdate.exe settime
Ist dafür gedacht um es im Installationsskript mit aufzurufen. Der Wert ist dann der Zeitpunkt der Installation des Agents und Updaters.
Nur die Hashwerte setzen:
AgentAutoUpdate.exe NextTimeOnlyHashUpdate
Beim nächsten(!) Aufruf werden, falls Änderungen gefunden wurden, nur die Hash-Werte in der Registry aktualisert. Es wird NICHT das Installationsprogramm aufgerufen.
Achtung Geduld - also keine Änderungen vornehmen bevor nicht alle Server dies einmal durchgeführt haben. Dieser Parameter ist wiederum nur für das Installationsskript gedacht.
Installation
Die Freigabe
Es gibt 2 Möglichkeiten:
1. der geplante Task wird als ein (Domänen-)Benutzer eingetragen
Dieser muss:
- über lokale Administratoren-Rechte verfügt
- auf die Freigabe zugreifen dürfen
Vorteil: Ich kann die Freigabe mit Berechtigungen absichern in der die Installationsdateien liegen
Nachteil 1: Eventuell falle ich (gerade ebei Server 2012) beim Installationscript wegen der UAC-Kontrolle auf die Schnauze
Nachteil 2: Passwort und Benutzername müssen ins Installationskript
Ergo: TESTEN! TESTEN! ... oder Möglichkeit 2. nehmen.
2. der geplante Task wird als SYSTEM-Benutzer eingetragen
- dieser ist schon Gott auf dem Server, keine Probleme mit UAC-Kontrolle
- Dafür muss die Freigabe anonymen Zugriff erlauben
Vorteil: Keine Probleme mit Setup, keine Passwörter im Installationsskript
Nachteil: Offene Freigabe
Ich favorisiere ganz klar Möglichkeit 2.
In den Umgebungen setzte ich immer eine Zabbix-Proxy-Server ein. Auf diesen erstelle ich gemäß dieser Anleitung eine Fregabe für die Agenteninstallation:
und kopiere das Skript / die Daten hinein.
Nachteil: Freigabe auf die jeder Zugreifen kann
In eurer Installationsskript fügt ihr einfach eine Zeile wie folgt hinzu:
%WINDIR%\system32\schtasks.exe /create /SC MINUTE /MO 99 /F /TN ZabbixAgentAutoUpdater /RU SYSTEM /TR "\"%PROGRAMFILES%\Zabbix\AgentAutoUpdate.exe\" \"\\10.11.12.13\Freigabe\" \"\\10.11.12.13\Freigabe\InstallZabbixAgent.bat\""
Eintragen als geplanten Task
Als SYSTEM-Benutzer:
%WINDIR%\system32\schtasks.exe /create /SC MINUTE /MO 67 /F /TN ZabbixAgentAutoUpdater /RU SYSTEM /TR "\"%PROGRAMFILES%\Zabbix\AgentAutoUpdate.exe\" \"\\server\freigabe" \"\\server\freigabe\install.bat\""
Die Parameter im Detail:
%WINDIR%\system32\schtasks.exe Startet den Aufgabenplaner (alle BS von Xp nis 2012 R2) /create Neuen Aufgabe erstellen /SC MINUTE Einheit für Zeitplan ist Minuten /MO 67 Alle 67 Minuten /F Falls es die Aufgabe schon gibt überschreiben /TN ZabbixAgentAutoUpdater Name der Aufgabe ist "ZabbixAgentAutoUpdater" /RU SYSTEM Benutzer SYSTEM und das Programm was regelmäßig gestartet werden soll - die ganzen \ vor den " müssen sein damit die Parameter richtig übernommen werden /TR "\"%PROGRAMFILES%\Zabbix\AgentAutoUpdate.exe\" \"\\server\freigabe" \"\\server\freigabe\install.bat\""
Wenn Ihr das ganze als ein bestimmten Benutzer laufen lassen wollt so nehmen statt /RU SYSTEM
/RU Domäne\Benutzername /RP Passwort
Einschränkungen + Bonus
- Der Update bemerkt jede veränderte Datei (und sei es nur ein Byte)
- jede zusätzliche Datei
und nimmt dies als Grund das Installationsskript/-programm zu starten
Er bemerkt aber nicht wenn nur eine Datei gelöscht wird.
Falls Ihr den Updater auf der Kommandozeile von hand testet und imme rnichts passiert: UAC Modus! Öffnet eine Eingabeaufforderung expliziet als Administrator und versucht es noch einmal!
Bonus:
Naja, dem Updater ist egal was er prüft und was er startet - ihr könntet das also auch für jedes andere Programm etc. nehmen. Nur das Verzeichnis welches er überwacht sollte nicht zu groß werden, wenn es mehrere Gigabyte hat wäre das schlecht. Man könnte aber auch nur Verzeichnis A mit 2 Dateien überwachen lassen - und dann das Installationsskript aus Verzeichnis B starten. Sobald Ihr was in A ändert läuft das Update los.
Speicherort der Hash-Werte
Die MD5-hash-Werte werden in der Registry unter
HKEY_LOCAL_MACHINE\SOFTWARE\znil.net\Zabbix-Agent-Autoupdater
gespeichert.
Falls ihr mal von Hand ein Update auslösen wollt so löscht einfachen einen der Werte oder ändert diesen.
Er legt dort für jede Datei einen Schlüssel an. Der Name des Schlüssels ist der Pfad zur Datei:
Außerdem gibt es den Schlüssel
lasttime
Der Wert dort ist der UNIX-Timestamp der letzten Installation. Ein UNIX-Timestamp sind die Sekunden die vergangen sind seit dem 01.01.1970 00:00 Uhr
Dieses Format habe ich genommen weil Zabbix in Templates mit diesem Wert prima umgehen kann (siehe Abschnitt Template)
Template
Download: Media:AgentAutoUpdater.zip
Import das Template - es erscheint dann als
znil Template Zabbix Agent Auto Update Check ACTIVE AGENT
im Ordner
Templates znil.net
In der Agenten-Konfiguratiuonsdatei müsst ihr dafür folgendes einfügen:
UserParameter=znil.agentautoupdate[*],"%PROGRAMFILES%\Zabbix\AgentAutoUpdate.exe" $1
den Pfad müsst Ihr natürlich ggf. anpassen.
Wier im nachfolgenden Scrrenshot sehen könnt fügt das Template nur eine einzige Zeile dem Abschnitt Zabbix-Agent hinzu:
Im Template gibt es nur das Item
Letztes Update des Agenten (Agent Auto Update)
mit dem Parameter
znil.agentautoupdate[lasttime]
Quellcode
Hier der Quellcode im AutoIt-Format:
#NoTrayIcon
#RequireAdmin
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=Icon256-32.ico
#AutoIt3Wrapper_Outfile=AgentAutoUpdate.exe
#AutoIt3Wrapper_Outfile_x64=AgentAutoUpdate64.exe
#AutoIt3Wrapper_Compile_Both=y
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_Description=ZabbixAgent Auto Update
#AutoIt3Wrapper_Res_Fileversion=1.0.0.98
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_Res_LegalCopyright=2013 Bernhard Linz
#AutoIt3Wrapper_Res_SaveSource=y
#AutoIt3Wrapper_Res_Language=1031
#AutoIt3Wrapper_Res_Field=Website|http://znil.net
#AutoIt3Wrapper_Res_Field=Manual|
#AutoIt3Wrapper_Res_Field=See You|znil.net
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
Opt('MustDeclareVars', 1)
#Region ;************ Includes ************
#Include <Date.au3>
#Include <Crypt.au3>
;~ #Include <Array.au3>;~~~
;~ #include <Constants.au3>;~~~
;~ #include <Date.au3>;~~~
#EndRegion ;************ Includes ************
; ##########################################################################################################################
; ##########################################################################################################################
; # AgentAutoUpdate.exe #
; # 2014 Bernhard Linz / Bernhard@znil.de / http://znil.net #
; # Idea and Original at Zabbix Wiki #
; # #
; # Latest Version of this Program and Template in German: #
; # http://znil.net/index.php?title=Agent_Auto_Updater #
; # #
; # ________ .__ __. __ __ .__ __. _______ .___________. #
; # | / | \ | | | | | | | \ | | | ____|| | #
; # `---/ / | \| | | | | | | \| | | |__ `---| |----` #
; # / / | . ` | | | | | | . ` | | __| | | #
; # / /----.| |\ | | | | `----.__| |\ | | |____ | | #
; # /________||__| \__| |__| |_______(__)__| \__| |_______| |__| #
; # #
; ##########################################################################################################################
; ##########################################################################################################################
Dim $s_Networkshare = "\\192.168.1.253\Zabbix-Agent\autoupdate"
Dim $s_Attrib
Dim $s_RegistryKey = "HKEY_LOCAL_MACHINE\Software\znil.net\Zabbix-Agent-Autoupdater"
Dim $a_Files[1]
Dim $a_Checksum[1]
Dim $i
Dim $s_temp
Dim $b_Update = False
Dim $i_lasttime
; 10 20 30 40 50 60 70 80
; 12345678901234567890123456789012345678901234567890123456789012345678901234567890
Dim $s_Header = _
"+------------------------------------------------------------------------------" & @CRLF & _
"| ZabbixAgentAutoUpdate.exe - Version " & FileGetVersion(@ScriptName) & @CRLF & _
"+------------------------------------------------------------------------------" & @CRLF & _
"| 2014 von Bernhard Linz für http://znil.net - Kontakt: Bernhard@znil.net" & @CRLF & _
"+------------------------------------------------------------------------------" & @CRLF & _
@CRLF
; 10 20 30 40 50 60 70 80
; 12345678901234567890123456789012345678901234567890123456789012345678901234567890
Dim $s_HilfeText = _
"Hilfsprogramm für die Aktualisierung des Zabbix-Agenten" & @CRLF & _
"-------------------------------------------------------------------------------" & @CRLF & _
@CRLF & _
"Aufruf: " & @CRLF & _
@CRLF & _
@ScriptName & " lasttime" & @CRLF & _
"Gibt Datum und Uhrzeit des letzten Updates zurück. Format ist UNIXTIME, also" & @CRLF & _
"die Anzahl der Sekunden seit dem 01.01.1970. Für das Template muss die" & @CRLF & _
@ScriptName & " als UserParameter eingebunden sein" & @CRLF & _
@CRLF & _
@ScriptName & " settime" & @CRLF & _
"Speicher einmal Datum und Uhrzeit des Aufrufs als letzten Zeitpunkt eines Updates" & @CRLF & _
"in der Registry - gedacht für den Aufruf aus einem Installationsskript" & @CRLF & _
@CRLF & _
@ScriptName & " NextTimeOnlyHashUpdate" & @CRLF & _
"Setzt ein Flag in die Registry das bei der nächsten Prüfung nur die Hash-Werte" & @CRLF & _
"in die Registry geschrieben werden. Es wird dann NICHT im Anschluß das" & @CRLF & _
"Updateskript / Updateprogramm aufgerufen" & @CRLF & _
@CRLF & _
@ScriptName & " <Pfad zur Netzwerkfreigabe> <Pfad zur Installationsdatei>" & @CRLF & _
@CRLF & _
"Die Netzwerkfreigabe ist der UNC-Pfad inklusive Unterordner zu den Dateien" & @CRLF & _
"mit dem Zabbix Agenten und anderen Dateien inklusive des Installationsscripts" & @CRLF & _
"Als 2. Parameter der Name und Pfad zur Installationsdatei." & @CRLF & _
"Das angegebene Verzeichnis wird gescannt, es wird eine Prüfsumme (Hash) für jede Datei" & @CRLF & _
"gebildet und mit den gespeicherten Werten in der Registry verglichen." & @CRLF & _
"Gibt es eine Abweichung wird das im 2. Parameter angegebene Programm oder" & @CRLF & _
"Skript gestartet. Zudem werden die Hash-Werte in der Registry für den" & @CRLF & _
"nächsten Vergleich gespeichert." & @CRLF & _
@CRLF & _
"Beispiel:" & @CRLF & _
@ScriptName & " \\192.168.1.253\Zabbix-Agent\autoupdate \\192.168.1.253\Zabbix-Agent\autoupdate\InstallZabbixAgent.bat" & @CRLF & _
@CRLF & _
"+------------------------------------------------------------------------------" & @CRLF & _
"| ZabbixAgentAutoUpdate.exe ist FREEWARE!" & @CRLF & _
"| Kopieren, weitergeben ausdrücklich erlaubt!" & @CRLF & _
"| Die jeweils aktuelleste Version und Anleitungen findet Ihr unter:" & @CRLF & _
"| http://znil.net/index.php?title=Agent_Auto_Updater" & @CRLF & _
"+------------------------------------------------------------------------------" & @CRLF
; ##########################################################################################################################
; ##########################################################################################################################
; ########################################
; ######## ## ## ## ## ###### ######## #### ####### ## ## ###### ########################################
; ## ## ## ### ## ## ## ## ## ## ## ### ## ## ## ########################################
; ## ## ## #### ## ## ## ## ## ## #### ## ## ########################################
; ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ########################################
; ## ## ## ## #### ## ## ## ## ## ## #### ## ########################################
; ## ## ## ## ### ## ## ## ## ## ## ## ### ## ## ########################################
; ## ####### ## ## ###### ## #### ####### ## ## ###### ########################################
; ########################################
; ##########################################################################################################################
; ##########################################################################################################################
; ###################################################################################
; Soll ganz toll ganze Verzeichnisbäume abgrasen können
;==================================================================================================
; Function Name: _GetFilesFolder_Rekursiv($sPath [, $sExt='*' [, $iDir=-1 [, $iRetType=0 ,[$sDelim='0']]]])
; Description: Rekursive Auflistung von Dateien und/oder Ordnern
; Parameter(s): $sPath der Basispfad für die Auflistung ('.' -aktueller Pfad, '..' -Parentpfad)
; $sExt Erweiterung für Dateiauswahl '*' oder -1 für alle (Standard)
; $iDir -1 Dateien+Ordner(Standard), 0 nur Dateien, 1 nur Ordner
; optional: $iRetType 0 gibt Array, 1 gibt String zurück
; optional: $sDelim legt Trennzeichen für Stringrückgabe fest
; 0 -@CRLF (Standard) 1 -@CR 2 -@LF 3 -';' 4 -'|'
; Return Value(s): Array (Standard) od. String mit den gefundenen Pfaden der Dateien und/oder Ordner
; Array[0] enthält die Anzahl der gefundenen Dateien/Ordner
; Author(s): BugFix (bugfix@autoit.de)
;==================================================================================================
Func _GetFilesFolder_Rekursiv($sPath, $sExt='*', $iDir=-1, $iRetType=0, $sDelim='0')
Global $oFSO = ObjCreate('Scripting.FileSystemObject')
Global $strFiles = ''
Switch $sDelim
Case '1'
$sDelim = @CR
Case '2'
$sDelim = @LF
Case '3'
$sDelim = ';'
Case '4'
$sDelim = '|'
Case Else
$sDelim = @CRLF
EndSwitch
If ($iRetType < 0) Or ($iRetType > 1) Then $iRetType = 0
If $sExt = -1 Then $sExt = '*'
If ($iDir < -1) Or ($iDir > 1) Then $iDir = -1
_ShowSubFolders($oFSO.GetFolder($sPath),$sExt,$iDir,$sDelim)
If $iRetType = 0 Then
Local $aOut
$aOut = StringSplit(StringTrimRight($strFiles, StringLen($sDelim)), $sDelim, 1)
If $aOut[1] = '' Then
ReDim $aOut[1]
$aOut[0] = 0
EndIf
Return $aOut
Else
Return StringTrimRight($strFiles, StringLen($sDelim))
EndIf
EndFunc
Func _ShowSubFolders($Folder, $Ext='*', $Dir=-1, $Delim=@CRLF)
If Not IsDeclared("strFiles") Then Global $strFiles = ''
If ($Dir = -1) Or ($Dir = 0) Then
For $file In $Folder.Files
If $Ext <> '*' Then
If StringRight($file.Name, StringLen($Ext)) = $Ext Then _
$strFiles &= $file.Path & $Delim
Else
$strFiles &= $file.Path & $Delim
EndIf
Next
EndIf
For $Subfolder In $Folder.SubFolders
If ($Dir = -1) Or ($Dir = 1) Then $strFiles &= $Subfolder.Path & '\' & $Delim
_ShowSubFolders($Subfolder, $Ext, $Dir, $Delim)
Next
EndFunc
; ###################################################################################
; _ANSI2OEM löst das Problem mit dem Umlauten und anderen Sonderzeichen. Es wandelt Text so um das er korrekt in der DOS-Box dargestellt wird
; So können hier im Quellcode auch Umlaute verwendet werden (in den Textausgaben) und diese werden dann korrekt dargestellt
; Wir zudem für die Prüfung der Gruppenzugehörigkeit benötigt für Gruppen mit Umlauten, z.B. Domänen-Admins
; Dank an Xenobiologist von AutoIt.de für diese Lösung: http://www.autoit.de/index.php?page=Thread&threadID=9461&highlight=ANSI2OEM
Func _ANSI2OEM($text)
$text = DllCall('user32.dll', 'Int', 'CharToOem', 'str', $text, 'str', '')
Return $text[2]
;Return $text
EndFunc ;==>_ANSI2OEM
; ###################################################################################
; Hilfsroutine die den Hilfetext ausgibt
Func _HilfeAusgeben()
ConsoleWrite(_ANSI2OEM($s_Header))
ConsoleWrite(_ANSI2OEM($s_HilfeText))
EndFunc ;==>_HilfeAusgeben
; ##########################################################################################################################
; ##########################################################################################################################
; ####################################################################################
; ## ## ### #### ## ## ####################################################################################
; ### ### ## ## ## ### ## ####################################################################################
; #### #### ## ## ## #### ## ####################################################################################
; ## ### ## ## ## ## ## ## ## ####################################################################################
; ## ## ######### ## ## #### ####################################################################################
; ## ## ## ## ## ## ### ####################################################################################
; ## ## ## ## #### ## ## ####################################################################################
; ####################################################################################
; ##########################################################################################################################
; ##########################################################################################################################
If $CmdLine[0] = 0 Then
_HilfeAusgeben()
Exit 0
EndIf
If @OSArch <> "X86" Then
$s_RegistryKey = StringReplace($s_RegistryKey, "HKEY_LOCAL_MACHINE", "HKEY_LOCAL_MACHINE64")
EndIf
If $CmdLine[0] = 1 Then
If $CmdLine[1] = "lasttime" Then
$i_lasttime = RegRead($s_RegistryKey, "lasttime")
If $i_lasttime = "" Then
$i_lasttime = 0
EndIf
ConsoleWrite($i_lasttime & @CRLF)
Exit 0
EndIf
If $CmdLine[1] = "settime" Then
$i_lasttime = _DateDiff("s", "1970/01/01 00:00:00", @YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC)
If RegWrite($s_RegistryKey, "lasttime", "REG_SZ", $i_lasttime) = 0 Then
ConsoleWrite("Fehler - konnte letzte Startzeit nicht in Registry schreiben" & @CRLF)
Exit 1
Else
Exit 0
EndIf
EndIf
If $CmdLine[1] = "NextTimeOnlyHashUpdate" Then
If RegWrite($s_RegistryKey, "NextTimeOnlyHashUpdate", "REG_SZ", "1") = 0 Then
ConsoleWrite("Fehler - konnte letzte NextTimeOnlyHashUpdate nicht in Registry schreiben" & @CRLF)
Exit 1
Else
Exit 0
EndIf
EndIf
EndIf
If $CmdLine[0] = 1 Or $CmdLine[0] > 2 Then
ConsoleWrite("Fehlerhafte Anzahl von Parametern! Es werden genau 2 Parameter erwartet!" & @CRLF)
ConsoleWrite("Folgende Parameter wurden gefunden:" & @CRLF)
For $i = 1 To $CmdLine[0]
ConsoleWrite("Parameter " & $i & ": " & $CmdLine[$i] & @CRLF)
Next
ConsoleWrite(_ANSI2OEM("Für Hilfe Programm ohne Parameter aufrufen!") & @CRLF)
Exit 1
EndIf
$s_Networkshare = $CmdLine[1]
If FileExists($s_Networkshare) = 1 Then
$s_Attrib = FileGetAttrib($s_Networkshare)
If StringInStr($s_Attrib, "D") = 0 Then
ConsoleWrite("Parameter 1 ist kein Verzeichnis sondern eine Datei: " & $s_Networkshare & @CRLF)
Exit 1
EndIf
Else
ConsoleWrite("Verzeichnis existiert nicht oder kein Zugriff: " & $s_Networkshare & @CRLF)
Exit 1
EndIf
If FileExists($CmdLine[2]) = 1 Then
$s_Attrib = FileGetAttrib($CmdLine[2])
If StringInStr($s_Attrib, "D") > 0 Then
ConsoleWrite("Parameter 2 ist keine Datei sondern ein Verzeichnis: " & $CmdLine[2] & @CRLF)
Exit 1
EndIf
Else
ConsoleWrite("Datei existiert nicht oder kein Zugriff: " & $CmdLine[2] & @CRLF)
Exit 1
EndIf
If @OSArch <> "X86" And @ScriptName <> "AgentAutoUpdate64.exe" Then
ConsoleWrite("Ist ein 64 Bit System - starte die 64-Bit Variante dieses Programs" & @CRLF)
Sleep(3000)
Run(@ComSpec & ' /c start "Zabbix" /MIN /LOW "' & @ScriptDir & '\AgentAutoUpdate64.exe" ' & '"' & $CmdLine[1] & '" "' & $CmdLine[2] & '"', "", @SW_SHOW)
Exit 0
EndIf
ConsoleWrite(@CRLF)
ConsoleWrite("Zabbix-Agent Autoupdater" & @CRLF)
ConsoleWrite("------------------------" & @CRLF)
ConsoleWrite(@CRLF)
ConsoleWrite('Schritt 1: Ermittle vorhandene Dateien im Pfad ' & $s_Networkshare & @CRLF)
$a_Files = _GetFilesFolder_Rekursiv($s_Networkshare, -1, 0, 0)
ConsoleWrite("Folgende " & $a_Files[0] & " Dateien wurden ermittelt:" & @CRLF)
For $i = 1 To $a_Files[0]
ConsoleWrite($a_Files[$i] & @CRLF)
Next
ConsoleWrite(@CRLF)
ConsoleWrite(_ANSI2OEM("Sammle MD5-Hash für diese ") & $a_Files[0] & " Dateien ..." & @CRLF)
ReDim $a_Checksum[$a_Files[0] + 1]
$a_Checksum[0] = $a_Files[0]
_Crypt_Startup()
For $i = 1 To $a_Files[0]
$a_Checksum[$i] = _Crypt_HashFile($a_Files[$i], $CALG_MD5)
ConsoleWrite($a_Files[$i] & " ::: " & $a_Checksum[$i] & @CRLF)
Next
_Crypt_Shutdown()
ConsoleWrite(@CRLF)
ConsoleWrite("Vergleiche MD5-Werte mit denen aus der Registry ..." & @CRLF)
For $i = 1 To $a_Files[0]
If $a_Checksum[$i] = RegRead($s_RegistryKey, $a_Files[$i]) Then
ConsoleWrite(_ANSI2OEM("Datei " & $i & ": Übereinstimmung!") & @CRLF)
Else
ConsoleWrite("Datei " & $i & ": fehlt oder geaendert! --> " & $a_Files[$i] & @CRLF)
$b_Update = True
EndIf
Next
ConsoleWrite(@CRLF)
If $b_Update = False Then
ConsoleWrite(_ANSI2OEM("Keine Datei wurde verändert - beende mich ohne etwas zu tun") & @CRLF)
Exit 0
EndIf
; Ok, wenn wir hier sind hat sich mindestens eine Datei geändert - also tun wir was
ConsoleWrite("Schreibe neue Hash-Werte in Registry .")
For $i = 1 To $a_Files[0]
If RegWrite($s_RegistryKey, $a_Files[$i], "REG_SZ", $a_Checksum[$i]) = 1 Then
ConsoleWrite(".")
Else
ConsoleWrite("FEHLER - konnte nicht in Registry schreiben!" & @CRLF)
ConsoleWrite(_ANSI2OEM("Registry-Schlüssel: ") & $s_RegistryKey & @CRLF)
Exit 1
EndIf
Next
ConsoleWrite(@CRLF)
If RegRead($s_RegistryKey, "NextTimeOnlyHashUpdate") = "1" Then
ConsoleWrite("Flag NextTimeOnlyHashUpdate gefunden - starte Updateprogramm NICHT!" & @CRLF)
RegWrite($s_RegistryKey, "NextTimeOnlyHashUpdate", "REG_SZ", "0")
Exit 0
EndIf
ConsoleWrite(@CRLF)
ConsoleWrite(_ANSI2OEM("Beende Zabbix Agenten für Update ...") & @CRLF)
;RunWait(@ComSpec & ' /c net stop "zabbix agent"', @SW_SHOW)
RunWait(@ComSpec & " /c " & 'net stop "zabbix agent"', "", @SW_HIDE)
;ConsoleWrite("Warte 5 Sekunden ..." & @CRLF)
;Sleep(5000)
ConsoleWrite(_ANSI2OEM("Beende UserParameter-Programme für Update ..." & @CRLF))
For $i = 1 To $a_Files[0]
$a_Files[$i] = StringRegExpReplace($a_Files[$i], '^([a-z]:|\\\\[a-z0-9 %._-]+\\[a-z0-9 $%._-]+)?(\\?(?:[^\\/:*?"<>|\r\n]+\\)+)', "")
;ConsoleWrite($a_Files[$i] & @CRLF)
While ProcessExists($a_Files) > 0
ConsoleWrite("Beende Programm: " & $a_Files[$i] & @CRLF)
If $a_Files[$i] <> @ScriptName Then ; eigenen Prozess auslassen!
ProcessClose($a_Files)
EndIf
Sleep(1000)
WEnd
Next
ConsoleWrite(@CRLF)
ConsoleWrite("Starte Installationsdatei: " & $CmdLine[2] & @CRLF)
If Run(@ComSpec & ' /c start "Zabbix" /MIN /LOW ' & $CmdLine[2], "", @SW_SHOW) > 0 Then
ConsoleWrite("Wurde erfolgreich gestartet! Beende mich jetzt!" & @CRLF)
$i_lasttime = _DateDiff("s", "1970/01/01 00:00:00", @YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC)
If RegWrite($s_RegistryKey, "lasttime", "REG_SZ", $i_lasttime) = 0 Then
ConsoleWrite("Fehler - konnte letzte Startzeit nicht in Registry schreiben" & @CRLF)
EndIf
Else
ConsoleWrite(_ANSI2OEM("Konnte Programm nicht starten! Lösche Hash-Werte wieder aus Registry") & @CRLF)
For $i = 1 To $a_Files[0]
RegWrite($s_RegistryKey, $a_Files[$i], "REG_SZ", "Fehler beim Start der Datei: " & $CmdLine[2])
Next
ConsoleWrite(_ANSI2OEM("Dies ist das ENDE.") & @CRLF)
Exit 1
EndIf
Exit 0