0

I have a VM running Windows Server 2008 R2 with the Zabbix Agent installed. I want to run a specific block of code if it's running. I started the service manually. When I log in to VM, open a PowerShell Prompt and type in the following snippet, it works perfectly:

$ZABBIX_INSTALLED = Get-Service "Zabbix Agent"
If ($ZABBIX_INSTALLED) {
   Write-Host "It's running"
}
else {
   Write-Host "Zabbix Agent is not running"
}

The problem is when I try call this as a script, it never returns true even when the process is running normally (I checked it in Task Manager).

Any suggestion on what it's happening with the code? I appreciate any help.

PS: I'm passing this script via Azure Runbook by running Invoke-AzRunCommand and passing the script as parameter.

Steven
  • 6,817
  • 1
  • 14
  • 14
  • The code you're showing doesn't _return_ anything; if you want to output a Boolean indicating whether the service is running, use `[bool] $ZABBIX_INSTALLED` – mklement0 Feb 22 '21 at 23:21
  • @mklement0, Wouldn't `If ($ZABBIX_INSTALLED)` return true if there was an object or value? I use `if ($variable)` all the time like this. – Daniel Feb 22 '21 at 23:24
  • It doesn't return true. It may evaluate to be a true condition. If you want to return true then do `if($variable){$true}else{$false}` – Doug Maurer Feb 22 '21 at 23:30
  • @Daniel: yes, in the context of a conditional implicit coercion to `[bool]` happens, but the question suggests that the entire piece of code is a script that should return (output) something. – mklement0 Feb 22 '21 at 23:33
  • 1
    I feel like a Boolean evaluation isn't the best choice here. The existing if statement will fire if the service exists even if it isn't running. It may be more comfortable like: `If ($ZABBIX_INSTALLED.Status -eq 'Running' ) { Write-Host "It's running" }` – Steven Feb 22 '21 at 23:33
  • 2
    I think OP meant that `Write-Host "It's running"`is never executed. Sounds like to me that no service is being found with "Zabbix Agent" as the name. – Daniel Feb 22 '21 at 23:56
  • Good point, @Steven: `Get-Service` merely returns an object describing the specified service, _if installed_, irrespective of whether it's running or not. That said, the point about the code snippet not _returning_ (outputting) anything stands (it only prints information to the _host_). – mklement0 Feb 22 '21 at 23:59
  • W2k8R2 is way out of support. Any chance this is running an older version of PowerShell? Maybe it doesn't behave as expected when run remotely... can you check `$PSVersionTable` and post results back to the question? – Steven Feb 23 '21 at 00:38
  • @mklement0 Both the ways (with and without bool) end up with the same result. Complementing the question, when I run the code snippet shown above directly within the PS prompt in Azure VM, the result of the condition is true, but when I pass the same code snippet as a ps1 file to Invoke-AzRunCommand cmdlet to be run in the same VM, the condition result is always false no matter what. – Bruno Silva Feb 23 '21 at 03:37
  • @Daniel Using the same cmdlet directly within the PS prompt in VM, ```Get-Service -name "Zabbix Agent"``` returns true, showing the running status of the Zabbix Agent. I tried with the ```Get-Process -Name "zabbix_agentd"``` and the result was the same. The problem is when I run the same commands as a script passed to Invoke-AzRunCommand, which always return false. – Bruno Silva Feb 23 '21 at 03:42
  • @Steven I tried the same with Windows Server 2019 and 2016 and the problem persists. Because of that, I think that's not a Powershell version related issue. – Bruno Silva Feb 23 '21 at 03:45
  • Perhaps this post can help. Mentions something about permissions as well. https://stackoverflow.com/a/55466037/11954025 – Daniel Feb 23 '21 at 06:04

4 Answers4

1

Bruno,

This code will cover all 3 possible situations (Not Installed, Not Running, Running).

Try {

  $ZABBIX_INSTALLED = (Get-Service "Zabbix Agent" -EA Stop).Status
  
  If ($ZABBIX_INSTALLED -eq "Running") {
     "Zabbix Agent: It's running"
  }
  else {
     "Zabbix Agent: is not running"
  }

} 

Catch {
  "Zabbix Agent: Not Installed!"
}

HTH

RetiredGeek
  • 2,980
  • 1
  • 7
  • 21
  • Hi @RetiredGeek, appreciate your answer. I tried it but the result was the same. The result was the catch message when I ran the code through the azure runbook, but when I ran the same code snippet directly within the VM (in PS prompt), the result was that Zabbix Agent is running. – Bruno Silva Feb 23 '21 at 03:02
0

Heres a good use of the if/elseif/else statement/condition:


$serv = Get-Service -Name "Zabbix Agent" -ErrorAction SilentlyContinue
    if($serv.Status -eq "Stopped")
        { Write-Host -Object "Service is Stopped!" -ForegroundColor Yellow } 
         elseif($serv.Status -eq "Running")
            { Write-Host -Object "Service is running!" -ForegroundColor Green }
            else { Write-Host -Object "No service by that name found!" -ForegroundColor Red }

If the status on the service is stopped, say its stopped. If its running, say its running, and if theres no service by that name, say it.

Abraham Zinala
  • 4,267
  • 3
  • 9
  • 24
0

You can also to this in a swith-statement:

try
{
    $srvName = "Zabbix Agent"
    switch  ( ( Get-Service $srvName -ea Stop).Status )
    {
        "Stopped" { "Zabbix Agent: Is not running" }
        "Running"{ "Zabbix Agent: Is running" }
    }
}
catch [Microsoft.PowerShell.Commands.ServiceCommandException]
{
    "Zabbix Agent: Not installed"
}
catch
{
    $_.Exception.Message
}
Smorkster
  • 322
  • 3
  • 10
0

Folks, I managed to figure out and solve the issue.

The idea is just after the Zabbix Agent installation, call a PS script (based on code snippet I wrote in the question) to update the config files in config directory.

So when I called the update script the Get-Service didn't find the service because for some reason it wasn't available yet.

Then I added a Start-Sleep 5 before call the update script and it worked.