I am not a scripting or any other language guy, unfortunately, but yet I have been tasked with a challenge - Create a custom sensor that will display the age of the system (windows install) and/or the age of the system (via BIOS). I have found two PS commands that accomplish this task:
Windows Install: ([WMI]'').ConvertToDateTime((Get-WmiObject Win32_OperatingSystem).InstallDate) BIOS Date: $bios = gwmi Win32_BIOS;($bios.ConvertToDateTime($bios.releasedate).ToShortDateString())
So I created a PS1 file for each of these and deposited them into the Custom Sensors/EXEXML folder on the probe. Added the EXE/Script Advanced sensor and selected one of the scripts. But then I got back and error XML: The returned xml does not match the expected schema. (code: PE233) -- JSON: The returned json does not match the expected structure (Invalid JSON.). (code: PE231).
So there are two problems I need to solve.
- 1. How do I rewrite the PS files to output a properly formatted answer for the sensor to display?
- 2. How can I then set up an alert of the system so that any date that is past 3 years of age triggers an alert?
If this isn't possible, that's fine, but I am still expected to try first. Already dumped a couple of hours into this, I don't mind a few more :).
Article Comments
Hello Dariusz, thank you for the reply. You have gotten me farther, but I'm still stuck. For now, I am going to stick with a single PS file until I can get it working to make things easier.
So I modified the PS file to convert to JSON.
$bios = gwmi Win32_BIOS;($bios.ConvertToDateTime($bios.releasedate).ToShortDateString()) | ConvertTo-Json
This is the output of the log file (Under Logs (Sensors)\) : "11/25/2012"
Below is the output of the log file.data (I X'd out identifying information).
Data['blockedsens'].asString := '';
Data['canlinux'].asString := '0';
Data['channelinfos'].asString := '{}';
Data['channelnames'].asString := '';
Data['environment'].asString := '';
Data['exefile'].asString := 'BIOS Age.ps1';
Data['exeparams'].asString := '';
Data['fastcount'].asString := '0';
Data['host'].asString := 'XXX';
Data['hostv6'].asString := '';
Data['inerror'].asString := '1';
Data['ipversion'].asString := '0';
Data['isexesensor'].asString := '1';
Data['lastmsg'].asString := '#Y2 @#O233 @#O231[Invalid JSON.]';
Data['lastuptime'].asString := '0';
Data['linuxlogindomain'].asString := '';
Data['linuxloginpassword'].asString := '***';
Data['monitorchange'].asString := '';
Data['mutexname'].asString := '';
Data['notonpod'].asString := '0';
Data['reboot'].asString := '42852.6577786921';
Data['reqmsginterval'].asString := '60';
Data['resultfile'].asString := 'Result of Sensor 54389.txt';
Data['sensorid'].asString := '54389';
Data['simulate'].asString := '0';
Data['timeout'].asString := '60';
Data['tlsexplicit_default'].asString := '';
Data['tlsexplicit_ftp'].asString := '';
Data['tlsexplicit_imap'].asString := '';
Data['tlsexplicit_pop3'].asString := '';
Data['tlsexplicit_port'].asString := '';
Data['tlsexplicit_smtp'].asString := '';
Data['uptimecount'].asString := '0';
Data['usednstime'].asString := '0';
Data['usewindowsauthentication'].asString := '0';
Data['windowslogindomain'].asString := 'XXXXX';
Data['windowsloginpassword'].asString := '***';
Data['windowsloginusername'].asString := 'XXXX';
Data['writeresult'].asString := '1';
Apr, 2017 - Permalink
The output needs to be like this:
<value>:<message>
So you can fiddle around and put the actual age in days as a value, based on the date:
$InstallDate = "11/25/2012" # Calculate the timespan $InstallDateObject = [datetime]::ParseExact($InstallDate,'MM/dd/yyyy',([Globalization.CultureInfo]::InvariantCulture)) $TimeSpan = New-TimeSpan -Start $InstallDateObject -End (Get-Date) Write-Host ([string]::Format("{0}:This system was installed {0} days ago",$TimeSpan.Days))
May, 2017 - Permalink
Sorry for the long delay, I was caught up in other projects.
This works kind of. The script you posted assumes we manually enter the server age in the script - but the problem is this is for multiple servers of different ages and we don't want to have multiple scripts (one for each server).
Is there a way to have the first script (as is or modified) run to give the install date, which then dumps said date into the script you have written? This way it is fully automated.
If not, well, we tried!
(and I again apologize for the my skills at this being weak, programming/scripts is not my strong point).
May, 2017 - Permalink
Hi there,
You could also "paramterize" it:
param($InstallDate = "11/25/2012") # Calculate the timespan $InstallDateObject = [datetime]::ParseExact($InstallDate,'MM/dd/yyyy',([Globalization.CultureInfo]::InvariantCulture)) $TimeSpan = New-TimeSpan -Start $InstallDateObject -End (Get-Date) Write-Host ([string]::Format("{0}:This system was installed {0} days ago",$TimeSpan.Days))
Now you can enter the date in the sensor's Parameter field (e.g. "11/25/2012") and
it will be calculated accordingly.
Kind regards,
Stephan Linke, Tech Support
May, 2017 - Permalink
Hi there,
You can find the documentation about the proper output for XML/JSON sensors (advanced sensors) in your PRTG webinterface under "Setup > PRTG API > Custom Sensors |> ADVANCED SCRIPT AND HTTP DATA SENSORS".
You can always debug the script and check what PRTG sees by enabling the "Write EXE result to disk" option in the sensor settings and checking the sensor logs under "C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Sensors)\".
I don't know how the exact output of the script looks like and in what unit the time is, but if it is in seconds, you can use the
Tag for the result/channel. This will display the value in PRTG in seconds. If you the unit is in hours, you can use "TimeHours" in the tag. Afterwards you are able to set your own thresholds/limits in the channel settings under "Limits".
Best regards.
Apr, 2017 - Permalink