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
Article Comments
Thanks for helping out, Flo :)
PRTG Scheduler |
PRTGapi |
Feature Requests |
WMI Issues |
SNMP Issues
Kind regards,
Stephan Linke, Tech Support Team
Jan, 2019 - Permalink
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
Jan, 2019 - Permalink
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
Jan, 2019 - Permalink
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
Jan, 2019 - Permalink
Tried to follow you through and came up with this script:
There is something that bugged me right away - you show a one-liner:
This alone is an issue - cause when you try:
PowerShell will write this output:
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:
In your complete line it would look like this:
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
Can you test this and let us know if it worked?
Regards
Florian Rossmark
www.it-admins.com
Jan, 2019 - Permalink