What is this?

This knowledgebase contains questions and answers about PRTG Network Monitor and network monitoring in general.

Learn more

PRTG Network Monitor

Intuitive to Use. Easy to manage.
More than 500,000 users rely on Paessler PRTG every day. Find out how you can reduce cost, increase QoS and ease planning, as well.

Free Download

Top Tags


View all Tags

Custom EXE sensor returns EXIT 2 no matter what.

Votes:

0

Hi

I have a script that works in powershell but when i run it in a custom exe sensor it fails


# Parameter "-computername" for the remote hosts address
param(
    $ProMarkServer = "mark-promark02"
    )

# Get processes of the remote machne that are like the provided dynamic process name
$Processes = (WmiObject -ComputerName $ProMarkServer  Win32_Process -Filter "name = 'prowin32.exe'" | Select-Object CommandLine | findstr /i "job.pf" | findstr /i "PROBI")

# Check if the process is found or not, report it back to PRTG.

if([string]::IsNullOrEmpty($Processes)) {
   Write-Host "2:DOWN"
   exit 2
   } else   { 
   Write-Host "0:OK"
   exit 0
   }


no matter if the process exists or not it returns 2:DOWN and EXIT 2

if i change exit 2 to exit 0 prtg accepts and goes into ok and change it back to 2 it goes into error. Problem is that it doesent return whats in the else no matter what.

thank you

custom exe-script-sensor prtg wmi-custom-sensor

Created on Jan 23, 2019 12:26:09 PM

Last change on Jan 25, 2019 2:16:15 PM by  Stephan Linke [Paessler Support]



5 Replies

Votes:

0

Tried to follow you through and came up with this script:

$ProMarkServer = "mark-promark02"
Get processes of the remote machne that are like the provided dynamic process name $Processes = (WmiObject -ComputerName $ProMarkServer Win32_Process -Filter "name = 'prowin32.exe'" | Select-Object CommandLine | findstr /i "job.pf" | findstr /i "PROBI")
if([string]::IsNullOrEmpty($Processes)) { 
    Write-Host "2:DOWN" exit 2 
} else { 
    Write-Host "0:OK" exit 0 
}

There is something that bugged me right away - you show a one-liner:

if([string]::IsNullOrEmpty($Processes)) { Write-Host "2:DOWN" exit 2 } else { Write-Host "0:OK" exit 0 }

This alone is an issue - cause when you try:

Write-Host "2:DOWN" exit 2

PowerShell will write this output:

2:DOWN exit 2

It interprets the whole statement as one and as text...

To overcome this - you would need to either put line-breaks or a command end symbol ; (semicolon) like this:

Write-Host "2:DOWN"; exit 2;

In your complete line it would look like this:

if([string]::IsNullOrEmpty($Processes)) { Write-Host "2:DOWN"; exit 2; } else { Write-Host "0:OK"; exit 0; }

Having said all of this - I am not certain that you need the EXIT command after all. Exit is a) used to terminate a PowerShell script at any code line - while also reporting back a exit code to whom ever started it and is listening. But PRTG depends a bit more on the 2:DOWN or 0:UP information that you wrote - so you likely could break it down to the following code line

if([string]::IsNullOrEmpty($Processes)) { Write-Host "2:DOWN" } else { Write-Host "0:OK" }

Can you test this and let us know if it worked?

Regards

Florian Rossmark

www.it-admins.com

Created on Jan 23, 2019 2:51:44 PM



Votes:

0

Thanks for helping out, Flo :)


PRTG Scheduler | PRTGapi | Feature Requests | WMI Issues | SNMP Issues

Kind regards,
Stephan Linke, Tech Support Team

Created on Jan 24, 2019 8:44:44 AM by  Stephan Linke [Paessler Support]



Votes:

0

Hi

Have tried to add credentials to the script.. i have used my own credentials (alterd in the script) and im domain admin

$secpasswd = ConvertTo-SecureString "xxxxxxxx" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("test\hest", $secpasswd)

# Get processes of the remote machne that are like the provided dynamic process name
$Processes = (WmiObject -ComputerName mark-promark02 -Credential $mycreds Win32_Process -Filter "name = 'prowin32.exe'" | Select-Object CommandLine | findstr /i "job.pf" | findstr /i "probi")

# Check if the process is found or not, report it back to PRTG.

if([string]::IsNullOrEmpty($Processes)) 
    { 
     Write-Host "2:DOWN" 
     EXIT 2} 
     else 
     { Write-Host "0:OK" 
     EXIT 0}

still only returns

     Write-Host "2:DOWN" 
     EXIT 2} 

but if i change EXIT 2 to EXIT 0 it goes green in prtg..

please test it yourself

Created on Jan 25, 2019 1:05:45 PM

Last change on Jan 25, 2019 1:53:22 PM by  Stephan Linke [Paessler Support]



Votes:

0

How about the following if condition:

if($Processes.Count -eq 0) 
{ Write-Host "1:DOWN"; EXIT 2; } 
else 
{ Write-Host "0:OK"; EXIT 0}

This will cause the sensor to go into a down state, if there are no processes found. I'm not sure if the approach you used is the correct use for a process object array.


PRTG Scheduler | PRTGapi | Feature Requests | WMI Issues | SNMP Issues

Kind regards,
Stephan Linke, Tech Support Team

Created on Jan 25, 2019 2:18:49 PM by  Stephan Linke [Paessler Support]

Last change on Jan 25, 2019 2:18:54 PM by  Stephan Linke [Paessler Support]



Votes:

1

Okay - now - if you execute the script in a PowerShell - you see the correct WRITE-HOST output. But the EXIT CODE is not directly visible. To read the EXIT CODE you use a special command right after you executed the script:

$LASTEXITCODE

This will show you the last exit code.

Now - I tested your script and it works just fine... telling me that your issue is not the script itself.

I still think you could work WITHOUT the two EXIT statements after all. But well that's a different story.

Did you ever enable logging in PRTG and see what the logfiles tell you for this sensor? I am not convinced that PRTG is interpreting the script wrong.

Cause I don't want to let you down - look at the following script - note that this is an ADVANCED EXE script and needs to be placed in the according directory.

param(
    $Computer, 
    $ProcessName,
    $ProcessCommandLineFilter1, #optional
    $ProcessCommandLineFilter2  #optional - but fill 1 first
)

#function to convert a string to proper XML and write it as output/screen
Function WriteXmlToScreen ([xml]$xml) #just to make it clean XML code...
{
    $StringWriter = New-Object System.IO.StringWriter;
    $XmlWriter = New-Object System.Xml.XmlTextWriter $StringWriter;
    $XmlWriter.Formatting = "indented";
    $xml.WriteTo($XmlWriter);
    $XmlWriter.Flush();
    $StringWriter.Flush();
    Write-Output $StringWriter.ToString();
}

If ($ProcessCommandLineFilter1.Length > 0) {
    If ($ProcessCommandLineFilter2.Length > 0) {
        $Processes = (WmiObject -ComputerName $Computer Win32_Process -Filter "name = '$ProcessName'" | Select-Object CommandLine | findstr /i "$ProcessCommandLineFilter1" | findstr /i "$ProcessCommandLineFilter2");
    } Else {
        $Processes = (WmiObject -ComputerName $Computer Win32_Process -Filter "name = '$ProcessName'" | Select-Object CommandLine | findstr /i "$ProcessCommandLineFilter1");
    }
} Else {
    $Processes = (WmiObject -ComputerName $Computer Win32_Process -Filter "name = '$ProcessName'");
}

If([string]::IsNullOrEmpty($Processes)) { 
    $XML = "<prtg>
        <result>
	        <channel>ProcessId</channel>
            <value>-1</value>
            <LimitMode>1</LimitMode>
            <LimitMinError>1</LimitMinError>
            <LimitErrorMsg>Process not found</LimitErrorMsg>
	    </result>
        <result>
	        <channel>Handles</channel>
            <value>0</value>
	    </result>
        <text>Process not found</text>
        </prtg>";  
} Else {
    $XML = "<prtg>
        <result>
	        <channel>ProcessId</channel>
            <value>" + $Processes.ProcessId + "</value>
            <LimitMode>1</LimitMode>
            <LimitMinError>1</LimitMinError>
            <LimitErrorMsg>Process not found</LimitErrorMsg>
	    </result>
        <result>
	        <channel>Handles</channel>
            <value>" + $Processes.Handles + "</value>
	    </result>
        <text>command line: " + $Processes.CommandLine + " - creation date: " + $Processes.CreationDate + "</text>
        </prtg>";
        
}

WriteXmlToScreen $XML;

You could modify the result/channel configuration and report back anything numeric... I just did go with HANDLES as an example..

The script will report back a PROCESS ID (PID) if your process was found - if not it will report back -1 and automatically raise an error. The sensor status text will go to process not found.

If the process is found, the PID and HANDLES are available, the sensor text will hold the whole command line information and the CreationDate what is the start date / time of the process. In theory you could even monitor that, but that's another story..

This script will expect that you set parameters... in your case:

mark-promark02 prowin32.exe "job.pf" "probi"

In theory this could work as parameter as well:

%host prowin32.exe "job.pf" "probi"

Hope this helps you...

Regards

Florian

Created on Jan 25, 2019 2:52:45 PM




Disclaimer: The information in the Paessler Knowledge Base comes without warranty of any kind. Use at your own risk. Before applying any instructions please exercise proper system administrator housekeeping. You must make sure that a proper backup of all your data is available.