SpookOz / zabbix-winupdates

A template for Zabbix that monitors and (optionally) applies Windows updates - for active agents
24 stars 16 forks source link

Script does not register servers #2

Open RobertoMarcelino opened 3 years ago

RobertoMarcelino commented 3 years ago

I tested the script on several operating systems and some worked, others didn't.

Systems tested: Windows Server 2008 R2 Standard = OK Windows Server 2008 R2 Enterprise = OK Windows Server 2012 Standard = OK Windows Server 2012 R2 Standard = OK Windows Server 2016 Standard = OK Windows Server 2016 Datacenter = OK Windows Server 2019 Standard = Not OK

Some are redundant: Standard, Enterprise, Datacenter. It is a way of showing that they were run on several servers with different operating systems.

On some servers it ran perfect. In others, I had to change the script.

On all Windows Server 2019 Standard, you presented the following error message:

PS C:\Users\Administrator> powershell.exe -NoProfile -ExecutionPolicy Bypass -file "C:\Users\zabbix\scripts\windows_updates.ps1"
At C:\Users\zabbix\scripts\windows_updates.ps1:216 char:80
+ ... ntent $ReportFile "`t Download status: FAILED With Error -- $Error()"
+                                                                        ~
An expression was expected after '('.
At C:\Users\zabbix\scripts\windows_updates.ps1:240 char:91
+ ... rtFile "`t Update installation status: FAILED With Error -- $Error()"
+                                                                        ~
An expression was expected after '('.
At C:\Users\zabbix\scripts\windows_updates.ps1:303 char:124
+ ... rg5 $Senderargupdating $Senderarg6 $Senderarg7 -s "$env:computername"
+                                                                         ~
The string is missing the terminator: ".
At C:\Users\zabbix\scripts\windows_updates.ps1:309 char:1
+
Missing closing ')' in expression.
At C:\Users\zabbix\scripts\windows_updates.ps1:309 char:1
+
Missing closing ')' after expression part of foreach loop.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ExpectedExpression

After removing the parentheses on lines 216 and 240, the script ran perfectly:

Response from "server-zabbix.com:10051": "processed: 1; failed: 0; total: 1; seconds spent: 0.000064"

I provide IT services to several companies in different locations and there are machines with the same name (Example: SVR-APP) but which are configured in the zabbix_agentd.conf file as Hostname = SVR-APP-01, Hostname = SVR-APP-02 .

They do not work, because the hostname is not found on Zabbix hosts.

So, I added just after the variable $ Senderarg8 = '1' the following code snippet:

$token="Hostname"
$extractedValue = Get-Content $Senderarg3
$hostname = (($extractedValue -split [System.Environment]::NewLine) | where {$_ -Like "$token*"}).Substring("$token=".Length);

I changed the $env:computername variables to $hostname.

It worked!

SpookOz commented 3 years ago

Hi Roberto. Thanks so much for this. It's very interesting and useful! I have a couple of questions you might be able to clarify:

  1. Are you using Zabbix agents, server and script v4.x or v5.x?
  2. Removing the parentheses: Do you know if this causes issues on the earlier versions of Windows? Most of mine are running on Windows 10, but I do have a few running on Win 2019 standard and they run fine (without modifying the parentheses). So strange that they are not working for you... I do find PowerShell frustrating in that way - different versions seem to have different syntax and cmdlets...
  3. Those variables you added are cool. Just thinking out loud - I wonder if they wouldn't fail for situations like mine where the hostname isn't specified in the config file. for example, my config file looks like this:

## Option: Hostname # Hostname= #Hostname=Windows host

I wonder if it would be possible to build an if / then into the script? It might be difficult, becahse my conf file still has "# Hostname". Hm something to think about...

RobertoMarcelino commented 3 years ago

I am using the agent version 5.2.5, frontend 5.2.5 as well and the script is version v5.x.

After removing the parentheses, it started to work on the Windows Server 2019 version. On the other tested systems, they worked with the parentheses.

Regarding variables, I am not a PowerShell expert. What I did was search Google for commands that would do what I needed.

Then I wondered if a question could not be added:

$token="Hostname"
$extractedValue = Get-Content $Senderarg3
$result = (($extractedValue -split [System.Environment]::NewLine) | where {$_ -Like "$token*"}).Substring("$token=".Length);

if $hostname = empty or nonexistent
  $hostname = $env:computername
else
  $hostname = $result
endif

Or something similar. You better than anyone else can evaluate and see if it is possible.

With this addition to the code, there will be no problem with your configuration file.

In my configuration file I use the following syntax:

HostMetadata=:osname=Windows:tipo=Workstation:

In Zabbix, I created an action to import and add to the Workstations group.

RobertoMarcelino commented 3 years ago
$file = Get-Content $Senderarg3
$file | foreach {
  $items = $_.split("=")
  if ($items[0] -eq "Hostname"){$result = $items[1]}
}

if (-not($result)){
    $hostname = $env:computername
} else {
    $hostname = $result.Trim()
}
RobertoMarcelino commented 3 years ago

I changed the location from where to download the .PS1 file, because when it comes from Github, it has different encoding and doesn't run.

I tried to change the command line but to no avail.

powershell.exe -NoProfile -ExecutionPolicy Bypass -command Invoke-WebRequest -Uri 'https://mysite/file.ps1' -OutFile 'C:\Users\zabbix\scripts\file.ps1' -UseBasicParsing

SpookOz commented 3 years ago

$token="Hostname" $extractedValue = Get-Content $Senderarg3 $result = (($extractedValue -split [System.Environment]::NewLine) | where {$_ -Like "$token*"}).Substring("$token=".Length);

if $hostname = empty or nonexistent $hostname = $env:computername else $hostname = $result endif

I'd have to test this. The problem is, the default config file actually has the hostname parameter, but it is hashed out. I'm not familiar enough with PS to know witout testing if your modification would still pick up hostname on the congif file...

SpookOz commented 3 years ago

I changed the location from where to download the .PS1 file, because when it comes from Github, it has different encoding and doesn't run.

I tried to change the command line but to no avail.

powershell.exe -NoProfile -ExecutionPolicy Bypass -command Invoke-WebRequest -Uri 'https://mysite/file.ps1' -OutFile 'C:\Users\zabbix\scripts\file.ps1' -UseBasicParsing

I'm reall ynot sure why it is not working for you... Mine all download the file from github and it runs fine. I'm a little stumped.