{"id":2597,"date":"2020-06-09T09:56:27","date_gmt":"2020-06-09T07:56:27","guid":{"rendered":"https:\/\/technet.cloud4you.biz\/?p=2597"},"modified":"2020-06-09T09:56:29","modified_gmt":"2020-06-09T07:56:29","slug":"zabbix-template-mit-userparameter-ps-script-bauen","status":"publish","type":"post","link":"https:\/\/technet.cloud4you.biz\/en\/zabbix-template-mit-userparameter-ps-script-bauen\/","title":{"rendered":"Zabbix Template mit Userparameter (PS-Script) bauen"},"content":{"rendered":"\n<h4 class=\"wp-block-heading\">Generelle Anspr\u00fcche an das Template<\/h4>\n\n\n\n<ul class=\"wp-block-list\"><li>PowerShell-Script erfasst auf Host-Seite die n\u00f6tigen Daten<\/li><li>Ansteuerung \u00fcber Zabbix-Server mit Parametern (also kein Zabbix Trapper)<\/li><li>Verwendung aktueller Best-Practices &#8211; sprich am Besten ein &#8220;Raw Item&#8221; aus dessen Inhalt die anderen Items berechnet werden, um den Datentransfer und die Kommunikation zw. Host und Zabbix-Server so klein wie nur irgendwie m\u00f6glich zu halten.<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Unser Szenario<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Im konkreten Beispiel wird ein Script den Inhalt eines Ordners \u00fcberwachen und uns alarmieren, wenn Inhalte im Ordner \u00e4lter sind, als eine definierte Zeitspanne. Zus\u00e4tzlich sollen gewisse Dateien innerhalb des Ordners ignoriert werden.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Schlussfolgerungen<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Pfad, Zeitspanne und zu ignorierende Dateien werden als Macros ins Template \u00fcbernommen und k\u00f6nnen somit auf Hostebene angepasst werden. Diese Macros werden dann in einem einzigen Item an den Host \u00fcbergeben, der auf seiner Seite ein Script ausf\u00fchrt und die ganzen ben\u00f6tigten Informationen &#8220;raw&#8221; zur\u00fcckgibt. Wir erstellen dann weitere &#8220;berechnete Items&#8221;, die den Inhalt des &#8220;Raw Items&#8221; auswerten und damit arbeiten.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 1: Das Script<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Im Installationsverzeichnis von Zabbix (bei uns C:\\ZABBIX) legen wir einen Ordner &#8220;userparameter&#8221; an. Hier wird das Script &#8220;Get-OldFilesInFolder.ps1&#8221; angelegt:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">param(\n[string]$sPath = \"\",\n[string]$sFoldersToIgnore = \"\")\n\n[bool]$bIgnoreSth = $false;\n\nif ($sFoldersToIgnore.Length -gt 0){\n    [String[]]$saFoldersToIgnore = $sFoldersToIgnore.Split(\",\");\n\n    foreach ($sFolder in $saFoldersToIgnore){\n        $sFolder = $sFolder.Trim();\n    }\n    $bIgnoreSth = $true;\n}\n\n[int]$iMaxAge = 0\n[string]$sOldestFileName = \"n\/a\";\n\n$oaSubFiles = Get-ChildItem -Path $sPath\n\nforeach ($oFile in $oaSubFiles){\n\n    if ($saFoldersToIgnore -match $oFile.Name){\n        # Do nothing\n    } else {\n        \n        [TimeSpan]$tsAge = New-TimeSpan -Start $oFile.CreationTime -End (Get-Date)\n\n        if ($tsAge.TotalMinutes -gt $iMaxAge){\n\n            $iMaxAge = $tsAge.TotalMinutes;\n            $sOldestFileName = $oFile.FullName.Replace(\"\\\", \"\\\\\");\n        }\n    }\n}\n\nWrite-Host \"{\"\"MaxAge\"\":\"\"$($iMaxAge)\"\",\"\"FileName\"\":\"\"$($sOldestFileName)\"\"}\";<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Entscheidend ist hier unsere letzte Zeile. Wir geben ein (zugegebenerma\u00dfen recht einfaches) Json-Objekt zur\u00fcck. Unser &#8220;Raw Item&#8221; wird somit nachher mit Json bef\u00fcllt sein &#8211; der wohl sinnvollsten M\u00f6glichkeit in Zabbix mit multiplen Daten zu arbeiten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Der zweite wichtige Punkt ist ganz oben im Script. Im &#8220;param()&#8221;-Block geben wir die Argumente an, die wir auf dem Zabbix-Host sp\u00e4ter \u00fcbergeben m\u00fcssen.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 2: Anpassung der zabbix_agentd.conf<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Die wichtigste Zeile, die wir hinzuf\u00fcgen m\u00fcssen, ist folgende:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">UserParameter=foldermonitoring.getstatus<span class=\"has-inline-color has-accent-color\">[*]<\/span>,powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"<span style=\"color:#21a300\" class=\"has-inline-color\">C:\\ZABBIX\\userparameter\\Get-OldFilesInFolder.ps1<\/span>\" \"<span style=\"color:#a38e00\" class=\"has-inline-color\">$1<\/span>\" \"<span style=\"color:#a38e00\" class=\"has-inline-color\">$2<\/span>\"<\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>Mit <span class=\"has-inline-color has-accent-color\">[*]<\/span> geben wir an, dass das Item Parameter unterst\u00fctzt.<\/li><li>Mit dem <span style=\"color:#21a300\" class=\"has-inline-color\">gr\u00fcn <\/span>geschriebenen geben wir den Pfad zum Script an<\/li><li>Und die <span style=\"color:#a38e00\" class=\"has-inline-color\">gelben <\/span>Elemente sind die \u00fcbergebenen Parameter, die auf keinen Fall weniger sein sollten, wie wir beim Item nachher \u00fcbergeben.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Die zweite Zeile die angepasst werden muss, ist leider folgende:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">UnsafeUserParameters=1<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Da wir hier sp\u00e4ter einen Ordnerpfad \u00fcbergeben, muss diese Option angepasst werden, da sonst die &#8220;Backslashes&#8221; nicht akzeptiert werden.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 3: Erstellung des Templates<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Um mit der etwas eigenwilligen Benennung von Templates seitens Zabbix compliant zu sein, habe ich das Template &#8220;Template Module Windows folder content by Zabbix agent&#8221; genannt und in die Gruppe &#8220;Templates\/Modules&#8221; abgelegt. Mehr gehe ich auf das Design des Templates aber gar nicht ein &#8211; viel wichtiger sind andere Dinge:<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Macros:<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Hier erstellen wir nun die drei besagten Macros:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Macro<\/th><th>Inhalt<\/th><th>Beschreibung<\/th><\/tr><\/thead><tbody><tr><td>{$FOLDERMONITORING.IGNORE}<\/td><td>Example,Template<\/td><td>Comma-separated list of ignored Files\/Folders<\/td><\/tr><tr><td>{$FOLDERMONITORING.PATH}<\/td><td>C:\\TEMP<\/td><td>Path to folder getting monitored<\/td><\/tr><tr><td>{$FOLDERMONITORING.THRESHOLD}<\/td><td>30<\/td><td>Threshold in seconds<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Ist denke ich recht verst\u00e4ndlich. Durch die einheitliche Benennung werden Sie sp\u00e4ter beim Host leichter zu finden sein.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Das Zabbix Raw Item<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Nun kommen wir zur Erstellung des &#8220;Raw Items&#8221; und somit zum Script-Trigger:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Name: Whatever floats your Boat<\/li><li>Type: Zabbix agent<\/li><li>Key: foldermonitoring.getstatus[&#8220;{$FOLDERMONITORING.PATH}&#8221;,&#8221;{$FOLDERMONITORING.IGNORE}&#8221;]<br><em>Hier referenzieren wir die Macros. Auch andere Parameter k\u00f6nnen aber selbstverst\u00e4ndlich angegeben werden.<\/em><\/li><li>Type of information: Text<\/li><li>Update interval: 1m (Zabbix Template Guideline)<\/li><li>History: 7d (Zabbix Template Guideline)<\/li><li>Applications: Zabbix raw items (Zabbix Template Guideline)<\/li><li>Description: <em>Hier kann man beschreiben, was Hostseitig in der Config angepasst werden muss, damit das Item funktioniert<\/em><\/li><li>Enabled: klar.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Damit ist das &#8220;Raw Item&#8221; schon fertig. Sollten Sie das Template nun an einen Host anbinden, auf dem das Script liegt und die Config entsprechend angepasst wurde, sollten Sie unter &#8220;Latest Data&#8221; bereits Ihr Json-Objekt sehen.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Die berechneten Items (Dependent item)<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Hier werden nun zwei Items erstellt &#8211; Bietet sich bei diesem Json-Objekt an:<\/p>\n\n\n\n<h6 class=\"wp-block-heading\">Dependent Item #1 (Numeric)<\/h6>\n\n\n\n<ul class=\"wp-block-list\"><li>Name: Whatever floats your boat<\/li><li>Type: Dependent item<\/li><li>Key: foldermonitoring.age<\/li><li>Master item: <em>Auswahl des Raw-Items<\/em><\/li><li>Type of information: Numeric (unsigned)<\/li><li>Units: s <em>(spezielle Unit f\u00fcr Zeitspannen)<\/em><\/li><li>History: 7d (Zabbix Template Guideline)<\/li><li>Trends: Do not keep trends<\/li><li>Show value: As is<\/li><li>Applications: File monitoring<\/li><li>Description: \u00af\\_(\u30c4)_\/\u00af<\/li><li>Enabled: ja.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Das war jedoch noch nicht alles, wir wechseln stattdessen auf den &#8220;Preprocessing&#8221;-Reiter, um dem Raw-Item auch den richtigen Wert zu entziehen:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Add -> JSONPath -> $[&#8220;MaxAge&#8221;]<br><em>Das ist die Json-Property, wie wir Sie im Script erstellten.<\/em><\/li><li>Add -> Custom multiplier -> 60<br><em>Hierdurch machen wir aus den Minuten Sekunden.<\/em><\/li><\/ol>\n\n\n\n<h6 class=\"wp-block-heading\">Dependent ITEM #2 (Text only)<\/h6>\n\n\n\n<ul class=\"wp-block-list\"><li>Name: Whatever floats your boat<\/li><li>Type: Dependent item<\/li><li>Key: foldermonitoring.name<\/li><li>Master item: <em>Auswahl des Raw-Items<\/em><\/li><li>Type of information: Text<\/li><li>History: 7d (Zabbix Template Guideline)<\/li><li>Applications: File monitoring<\/li><li>Description: \u00af\\_(\u30c4)_\/\u00af<\/li><li>Enabled: ja.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Auch hier dann wieder auf den &#8220;Preprocessing&#8221;-Reiter wechseln und folgendes konfigurieren:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Add -> JSONPath -> $[&#8220;FileName&#8221;]<br><em>Das ist die Json-Property, wie wir Sie im Script erstellten.<\/em><\/li><\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 4: Funktion pr\u00fcfen<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Falls nicht schon nach Erstellung des &#8220;Raw Items&#8221; passiert, k\u00f6nnen Sie nun das Script auf einem Host ablegen, die Config des Agents entsprechend anpassen und in Zabbix dem Host das Template zuordnen. Wenig sp\u00e4ter (falls die Default-Werte eingehalten wurden, eine Minute sp\u00e4ter) sollten dann die Werte abgerufen werden und unter &#8220;Latest Data&#8221; einsehbar sein. Die Macros m\u00fcssen nat\u00fcrlich angepasst werden.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 5: Trigger erstellen<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Nun k\u00f6nnen wir wieder auf das Template wechseln, um noch einen Trigger zu erstellen. Schlie\u00dflich wollen wir ja melden, falls eine Datei tats\u00e4chlich \u00e4lter ist als der im Macro hinterlegte Wert.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Auch hier werden wir wieder Best Practices anwenden &#8211; Somit kommen keine {ITEM.LASTVALUEX}-Attribute mehr in den Triggernamen, da diese seit Zabbix 4 (nicht komplett sicher) nicht mehr aktualisiert werden. Stattdessen kommen solche Infos in das Feld &#8220;Operational Data&#8221;. Gesagt, getan:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Name: File in &#8216;{$FOLDERMONITORING.PATH}&#8217; older than threshold ({$FOLDERMONITORING.THRESHOLD}m)<\/li><li>Operational Data: Age: {ITEM.LASTVALUE1}<br><em>Immer klein halten, da es in Dashboards zus\u00e4tzlich zum Triggernamen in der Zeile angezeigt wird<\/em><\/li><li>Serverity: Frei w\u00e4hlbar<\/li><li>Expression:<br>{Template Module Windows folder content by Zabbix agent:foldermonitoring.age.last()}>{$FOLDERMONITORING.THRESHOLD} and {Template Module Windows folder content by Zabbix agent:foldermonitoring.name.strlen()}>0<br><em>Wir pr\u00fcfen den Namen hier nur, um darauf zugreifen zu k\u00f6nnen<\/em><\/li><li>OK event generation: Expression<\/li><li>PROBLEM event generation mode: Single<\/li><li>OK event closes: All problems<\/li><li>Allow manual close: Nein.<\/li><li>URL: &#8211;<\/li><li>Description: Path of File: {ITEM.LASTVALUE2}<br><em>Hier greifen wir nun den Namen ab um ihn anzuzeigen.<\/em><\/li><li>Enabled: Ja.<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Abschluss<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Das war es nun &#8211; wir haben unser Template erstellt. Was die Komplexit\u00e4t betrifft, war das nat\u00fcrlich gar nichts. Jedoch haben wir hierdurch einen guten Einblick in alle nennenswerten Mechaniken bekommen. Funktionstechnisch kratzen wir hier sicher nur an der Oberfl\u00e4che.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Generelle Anspr\u00fcche an das Template PowerShell-Script erfasst auf Host-Seite die n\u00f6tigen Daten Ansteuerung \u00fcber Zabbix-Server mit Parametern (also kein Zabbix Trapper) Verwendung aktueller Best-Practices &#8211; sprich am Besten ein &#8220;Raw Item&#8221; aus dessen Inhalt die anderen Items berechnet werden, um den Datentransfer und die Kommunikation zw. Host und Zabbix-Server so klein wie nur irgendwie m\u00f6glich [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[147,17,57],"tags":[235,206,229,233],"class_list":["post-2597","post","type-post","status-publish","format-standard","hentry","category-scripts","category-windows","category-zabbix","tag-powershell","tag-zabbix","tag-zabbix-agent","tag-zabbix-agent-windows"],"translation":{"provider":"WPGlobus","version":"3.0.6","language":"en","enabled_languages":["de","en"],"languages":{"de":{"title":true,"content":true,"excerpt":false},"en":{"title":false,"content":false,"excerpt":false}}},"_links":{"self":[{"href":"https:\/\/technet.cloud4you.biz\/en\/wp-json\/wp\/v2\/posts\/2597","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/technet.cloud4you.biz\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/technet.cloud4you.biz\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/technet.cloud4you.biz\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/technet.cloud4you.biz\/en\/wp-json\/wp\/v2\/comments?post=2597"}],"version-history":[{"count":5,"href":"https:\/\/technet.cloud4you.biz\/en\/wp-json\/wp\/v2\/posts\/2597\/revisions"}],"predecessor-version":[{"id":2602,"href":"https:\/\/technet.cloud4you.biz\/en\/wp-json\/wp\/v2\/posts\/2597\/revisions\/2602"}],"wp:attachment":[{"href":"https:\/\/technet.cloud4you.biz\/en\/wp-json\/wp\/v2\/media?parent=2597"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/technet.cloud4you.biz\/en\/wp-json\/wp\/v2\/categories?post=2597"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/technet.cloud4you.biz\/en\/wp-json\/wp\/v2\/tags?post=2597"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}