lordmilko / PrtgAPI

C#/PowerShell interface for PRTG Network Monitor
MIT License
305 stars 38 forks source link

PRTG API and set-channelprotperty -lowererrorlimit #291

Open carsten0407 opened 2 years ago

carsten0407 commented 2 years ago

What's going on?

Hi Comunity,

at one PRTG-Server we have the problem, when we configure the thressholds through PRTG-API with

get-probe -name customer | get-sensor -id 5358 | Get-Channel -id 0 | Set-ChannelProperty -LowerErrorLimit 50000

The result looks like

05-07-_2022_10-07-58

Must be a problem on that PRTG-Server. On the other 4 PRTG-Server the problem not exist!

Any Idea?

Due Dilligance

lordmilko commented 2 years ago

Can you please provide the output of Get-PrtgClient -Diagnostic

carsten0407 commented 2 years ago

PSVersion : 5.1.19041.1682 PSEdition : Desktop OS : Microsoft Windows 10 Enterprise PrtgAPIVersion : 0.9.17 Culture : de-DE CLRVersion : 528372 PrtgVersion : 22.1.75.1588 PrtgLanguage : english.lng

lordmilko commented 2 years ago

Can you do Set-PrtgClient -LogLevel All and then provide the output of

get-probe -name customer | get-sensor -id 5358 | Get-Channel -id 0 -Verbose | Set-ChannelProperty -LowerErrorLimit 50000 -Verbose

Please omit the servername, username and passhash from the response

carsten0407 commented 2 years ago

Hi Lord,hope this is enoung

AUSFÜHRLICH: Get-Channel: Synchronously executing request 
https://monitoring.secret.de/api/table.xml?content=channels&columns=objid,name,lastvalue&count=*&showhide=1&id=5358&username=secret_user-PowershellUser&passhash=2493938352
AUSFÜHRLICH: Get-Channel: <?xml version="1.0" encoding="UTF-8"?>
  <channels totalcount="0" listend="1">
   <prtg-version>22.1.75.1588</prtg-version>
   <item>
    <objid>0</objid>
    <objid_raw>0000000000</objid_raw>
    <name>Free Bytes</name>
    <lastvalue>41,095 MB</lastvalue>
    <lastvalue_raw>43091300352.0000</lastvalue_raw>
   </item>
   <item>
    <objid>-4</objid>
    <objid_raw>*000000004</objid_raw>
    <name>Downtime</name>
   </item>
   <item>
    <objid>1</objid>
    <objid_raw>0000000001</objid_raw>
    <name>Free Space</name>
    <lastvalue>67 %</lastvalue>
    <lastvalue_raw>67.0000</lastvalue_raw>
   </item>
  </channels>
AUSFÜHRLICH: Get-Channel: Synchronously executing request 
https://monitoring.konicasecret.de/controls/channeledit.htm?id=5358&channel=0&username=secret_user-PowershellUser&passhash=2493938352
AUSFÜHRLICH: Get-Channel: <div>
  <div class="pseudoform prtg-form prtg-plugin" data-plugin="channels" data-template="channels.htm" data-singleedit="true" 
data-channelid="0" data-objectid="5358" data-container=".channelsloadingform">
    <h1 style="display: none">
      Edit Channel
    </h1>
    <select name="channel" id="channelsdropdown" style="width: 100%">
      <option value="-4" data-channel-kind="5">Downtime (ID -4)</option><option value="0" data-channel-kind="3">Free Bytes (ID
0)</option><option value="1" data-channel-kind="5">Free Space (ID 1)</option>
    </select>
    <div class="channelsloadingform">

<form id="channelsform" action="/editsettings" method="post" class="prtg-form prtg-plugin" data-ajaxsubmit="true" data-redirect="false" 
 data-plugin="multiedit">
 <fieldset>
  <legend class="prtg-header inline-hidden">Edit Channel &quot;Free Bytes&quot;</legend>
  <div class="control-group">
   <div class="checkboxbuttonset"><label class="control-label has_help " for="name_0">Name</label>
<div class="controls " data-placement="top" data-helptext="Enter a meaningful name for the channel to identify it in data graphs and    
tables.">
<input class="text"  data-rule-required="true" type="text" name="name_0" id="name_0" autocomplete="off" value="Free Bytes" ></div>      

<label class="control-label has_help " for="id_0">ID</label>
<div class="controls " data-placement="top" data-helptext="Shows the ID of this channel. You cannot edit this ID. It is shown for your  
information only.">
<div class="readonlyproperty" >0</div></div>

<label class="control-label has_help " for="limitmode_0">Limits</label>
<div class="controls " data-placement="top" data-helptext="Define if you want to use thresholds for the channel. With limits, you can   
set a sensor in the <b>Warning</b> or the <b>Down</b> status depending on the current value of a channel.">
<div class="radio-control">
<input type="radio" class="hidden radio  GroupShowHide" name="limitmode_0" value="0" id="limitmode0" >

<label for="limitmode0" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Disable limits
</label>
<input type="radio" class="hidden radio  GroupShowHide" name="limitmode_0" value="1" checked  id="limitmode1" >

<label for="limitmode1" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Enable alerting based on limits
</label>
</div>
</div>

<label class="control-label has_help  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement" for="limitmaxerror_0">Upper 
 Error Limit (MB)</label>
<div class="controls  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement" data-placement="top" data-helptext="Specify 
 an upper limit. Values above this limit set the sensor to the <b>Down</b> status.<br><br> <b>Note:</b> The value that you enter here   
must match the type of value that the device returns, either an integer or a float. For example, if the device returns float values,    
then you must enter a float value.">
<input type="text" class="text"  data-rule-number="true" autocomplete="off" name="limitmaxerror_0" id="limitmaxerror_0" value=""        
data-rule-validgroup="limitsalert"><input type="hidden" name="limitmaxerror_0_factor" id="limitmaxerror_0_factor"
value="9.5367431640625E-7" data-rule-validgroup="limitsalert"></div>

<label class="control-label has_help  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement"
for="limitmaxwarning_0">Upper Warning Limit (MB)</label>
<div class="controls  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement" data-placement="top" data-helptext="Specify 
 an upper limit. Values above this limit set the sensor to the <b>Warning</b> status.<br><br> <b>Note:</b> The value that you enter     
here must match the type of value that the device returns, either an integer or a float. For example, if the device returns float       
values, then you must enter a float value.">
<input type="text" class="text"  data-rule-number="true" autocomplete="off" name="limitmaxwarning_0" id="limitmaxwarning_0" value=""    
data-rule-validgroup="limitsalert"><input type="hidden" name="limitmaxwarning_0_factor" id="limitmaxwarning_0_factor"
value="9.5367431640625E-7" data-rule-validgroup="limitsalert"></div>

<label class="control-label has_help  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement"
for="limitminwarning_0">Lower Warning Limit (MB)</label>
<div class="controls  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement" data-placement="top" data-helptext="Specify 
 a lower limit. Values below this limit set the sensor to the <b>Warning</b> status.<br><br> <b>Note:</b> The value that you enter here 
 must match the type of value that the device returns, either an integer or a float. For example, if the device returns float values,   
then you must enter a float value.">
<input type="text" class="text"  data-rule-number="true" autocomplete="off" name="limitminwarning_0" id="limitminwarning_0"
value="10000" data-rule-validgroup="limitsalert"><input type="hidden" name="limitminwarning_0_factor" id="limitminwarning_0_factor"     
value="9.5367431640625E-7" data-rule-validgroup="limitsalert"></div>

<label class="control-label has_help  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement" for="limitminerror_0">Lower 
 Error Limit (MB)</label>
<div class="controls  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement" data-placement="top" data-helptext="Specify 
 a lower limit. Values below this limit set the sensor to the <b>Down</b> status.<br><br> <b>Note:</b> The value that you enter here    
must match the type of value that the device returns, either an integer or a float. For example, if the device returns float values,    
then you must enter a float value.">
<input type="text" class="text"  data-rule-number="true" autocomplete="off" name="limitminerror_0" id="limitminerror_0"
value="0.0476837158" data-rule-validgroup="limitsalert"><input type="hidden" name="limitminerror_0_factor" id="limitminerror_0_factor"  
value="9.5367431640625E-7" data-rule-validgroup="limitsalert"></div>

<label class="control-label has_help  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement" for="limiterrormsg_0">Error 
 Limit Message</label>
<div class="controls  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement" data-placement="top" data-helptext="Enter a 
 message that you want to add to the sensor message when the sensor is in the <b>Down</b> status.">
<input class="text"  type="text" name="limiterrormsg_0" id="limiterrormsg_0" autocomplete="off" value="" ></div>

<label class="control-label has_help  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement"
for="limitwarningmsg_0">Warning Limit Message</label>
<div class="controls  Showlimitmode1  Hidelimitmode0  Hidelimitmode2  groupshowhideelement" data-placement="top" data-helptext="Enter a 
 message that you want to add to the sensor message when the sensor is in the <b>Warning</b> status.">
<input class="text"  type="text" name="limitwarningmsg_0" id="limitwarningmsg_0" autocomplete="off" value="" ></div>

<label class="control-label has_help " for="showchart_0">Graph Rendering</label>
<div class="controls " data-placement="top" data-helptext="Define if you want to show this channel in data graphs.">
<div class="radio-control">
<input type="radio" class="hidden radio " name="showchart_0" value="1" checked  id="showchart1" >

<label for="showchart1" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Show in graphs
</label>
<input type="radio" class="hidden radio " name="showchart_0" value="0" id="showchart0" >

<label for="showchart0" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Hide from graphs
</label>
</div>
</div>

<label class="control-label has_help " for="show_0">Table Rendering</label>
<div class="controls " data-placement="top" data-helptext="Define if you want to show this channel in data tables.
<br/><br/><b>Important:</b> Only if you show this channel in data tables, PRTG uses it for the calculation of the <b>Total</b> channel  
of this sensor. Channels that you only show in graphs and not in tables do not contribute to the <b>Total</b> channel of this
sensor.">
<div class="radio-control">
<input type="radio" class="hidden radio " name="show_0" value="1" checked  id="show1" >

<label for="show1" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Show in tables
</label>
<input type="radio" class="hidden radio " name="show_0" value="0" id="show0" >

<label for="show0" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Hide from tables
</label>
</div>
</div>

<label class="control-label has_help " for="colmode_0">Line Color</label>
<div class="controls " data-placement="top" data-helptext="Choose if you want an automatic line color for this channel in graphs or     
define the color manually.">
<div class="radio-control">
<input type="radio" class="hidden radio  GroupShowHide" name="colmode_0" value="0" checked  id="colmode0" >

<label for="colmode0" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Automatic
</label>
<input type="radio" class="hidden radio  GroupShowHide" name="colmode_0" value="1" id="colmode1" >

<label for="colmode1" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Manual
</label>
</div>
</div>

<label class="control-label has_help  Showcolmode1  Hidecolmode0  InitialDisplayNone  groupshowhideelement" for="color_0">Color
(#rrggbb)</label>
<div class="controls  Showcolmode1  Hidecolmode0  InitialDisplayNone  groupshowhideelement" data-placement="top" data-helptext="Enter   
the color in hexadecimal RGB notation with a leading # (as in HTML/CSS, for example, <i>#ff0000</i> for red, <i>#0000ff</i> for blue)   
or directly choose a color.">
<input class="text colorselector"  data-rule-required="true" data-rule-hexcolor="true" autocomplete="off" type="text" name="color_0"    
id="color_0" value="" ></div>

<label class="control-label has_help " for="linewidth_0">Line Width</label>
<div class="controls " data-placement="top" data-helptext="Enter the line width for large graphs.">
<input class="text"  data-rule-number="true" data-rule-max="25" data-rule-required="true" type="text" name="linewidth_0"
id="linewidth_0" autocomplete="off" value="1" ></div>

<label class="control-label has_help " for="percent_0">Data</label>
<div class="controls " data-placement="top" data-helptext="Choose if you want to show actual values with the given unit or to calculate 
 and show a percentage based on the maximum value as defined below.">
<div class="radio-control">
<input type="radio" class="hidden radio  GroupShowHide" name="percent_0" value="0" checked  id="percent0" >

<label for="percent0" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Display actual values in MB
</label>
<input type="radio" class="hidden radio  GroupShowHide" name="percent_0" value="1" id="percent1" >

<label for="percent1" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Display in percent of maximum
</label>
</div>
</div>

<label class="control-label has_help  Showpercent1  Hidepercent0  InitialDisplayNone  groupshowhideelement"
for="ref100percent_0">Maximum (MB)</label>
<div class="controls  Showpercent1  Hidepercent0  InitialDisplayNone  groupshowhideelement" data-placement="top" data-helptext="Enter a 
 maximum value on which the percentage calculation is based.">
<input type="text" class="text"  data-rule-number="true" data-rule-required="true" autocomplete="off" name="ref100percent_0"
id="ref100percent_0" value="" ><input type="hidden" name="ref100percent_0_factor" id="ref100percent_0_factor"
value="9.5367431640625E-7" ></div>

<label class="control-label has_help " for="avgmode_0">Value Mode</label>
<div class="controls " data-placement="top" data-helptext="Choose the value that you want to use to display as historic data for this   
channel. Instead of averages, you can show the maximum or the minimum values of a time span.">
<div class="radio-control">
<input type="radio" class="hidden radio " name="avgmode_0" value="0" checked  id="avgmode0" >

<label for="avgmode0" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Average
</label>
<input type="radio" class="hidden radio " name="avgmode_0" value="1" id="avgmode1" >

<label for="avgmode1" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Minimum
</label>
<input type="radio" class="hidden radio " name="avgmode_0" value="2" id="avgmode2" >

<label for="avgmode2" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Maximum
</label>
</div>
</div>

<label class="control-label has_help " for="decimalmode_0">Decimal Places</label>
<div class="controls " data-placement="top" data-helptext="Define the number of decimal places you want to display in this channel. You 
 can enter a custom number below.">
<div class="radio-control">
<input type="radio" class="hidden radio  GroupShowHide" name="decimalmode_0" value="0" checked  id="decimalmode0" >

<label for="decimalmode0" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Automatic
</label>
<input type="radio" class="hidden radio  GroupShowHide" name="decimalmode_0" value="1" id="decimalmode1" >

<label for="decimalmode1" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
All
</label>
<input type="radio" class="hidden radio  GroupShowHide" name="decimalmode_0" value="2" id="decimalmode2" >

<label for="decimalmode2" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Custom
</label>
</div>
</div>

<label class="control-label no_help  Showdecimalmode2  Hidedecimalmode0  InitialDisplayNone  Hidedecimalmode1  groupshowhideelement"    
for="decimaldigits_0"></label>
<div class="controls  Showdecimalmode2  Hidedecimalmode0  InitialDisplayNone  Hidedecimalmode1  groupshowhideelement"
data-placement="top" >
<input class="text"  data-rule-number="true" data-rule-required="true" data-rule-min="0" data-rule-max="15" type="text"
name="decimaldigits_0" id="decimaldigits_0" autocomplete="off" value="2" ></div>

<label class="control-label has_help " for="spikemode_0">Spike Filter</label>
<div class="controls " data-placement="top" data-helptext="Choose if you want to filter out incorrect values from data graphs and       
tables that are too high or too low. The filter applies to existing data. This can take a few minutes.">
<div class="radio-control">
<input type="radio" class="hidden radio  GroupShowHide" name="spikemode_0" value="0" checked  id="spikemode0" >

<label for="spikemode0" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Disable filtering
</label>
<input type="radio" class="hidden radio  GroupShowHide" name="spikemode_0" value="1" id="spikemode1" >

<label for="spikemode1" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Enable filtering
</label>
</div>
</div>

<label class="control-label has_help  Showspikemode1  Hidespikemode0  InitialDisplayNone  groupshowhideelement" for="spikemax_0">Spike  
Filter Max. Value (MB)</label>
<div class="controls  Showspikemode1  Hidespikemode0  InitialDisplayNone  groupshowhideelement" data-placement="top"
data-helptext="Define the upper spike filter. PRTG disregards all data above this value.">
<input type="text" class="text"  data-rule-number="true" autocomplete="off" name="spikemax_0" id="spikemax_0" value="" ><input
type="hidden" name="spikemax_0_factor" id="spikemax_0_factor" value="9.5367431640625E-7" ></div>

<label class="control-label has_help  Showspikemode1  Hidespikemode0  InitialDisplayNone  groupshowhideelement" for="spikemin_0">Spike  
Filter Min. Value (MB)</label>
<div class="controls  Showspikemode1  Hidespikemode0  InitialDisplayNone  groupshowhideelement" data-placement="top" 
data-helptext="Define the lower spike filter. PRTG disregards all data below this value.">
<input type="text" class="text"  data-rule-number="true" autocomplete="off" name="spikemin_0" id="spikemin_0" value="" ><input
type="hidden" name="spikemin_0_factor" id="spikemin_0_factor" value="9.5367431640625E-7" ></div>

<label class="control-label has_help " for="axismode_0">Vertical Axis Scaling</label>
<div class="controls " data-placement="top" data-helptext="Define the vertical axis scaling of graphs for this channel. Choose if you   
want to automatically set the vertical axis scaling or to manually set the minimum and maximum for the vertical axis.
<br/><br/><b>Note:</b> PRTG ignores this setting if you set the <b>Graph Type</b> to <b>Stack channels on top of each other</b> in the  
sensor settings.">
<div class="radio-control">
<input type="radio" class="hidden radio  GroupShowHide" name="axismode_0" value="0" checked  id="axismode0" >

<label for="axismode0" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Automatic scaling
</label>
<input type="radio" class="hidden radio  GroupShowHide" name="axismode_0" value="1" id="axismode1" >

<label for="axismode1" class="radio-control-label">
<i class="icon-gray icon-radio-on"></i>
Manual scaling
</label>
</div>
</div>

<label class="control-label no_help  Showaxismode1  Hideaxismode0  InitialDisplayNone  groupshowhideelement" for="axismax_0">Vertical   
Axis Maximum (MB)</label>
<div class="controls  Showaxismode1  Hideaxismode0  InitialDisplayNone  groupshowhideelement" data-placement="top" >
<input type="text" class="text"  data-rule-number="true" data-rule-required="true" autocomplete="off" name="axismax_0" id="axismax_0"   
value="" ><input type="hidden" name="axismax_0_factor" id="axismax_0_factor" value="9.5367431640625E-7" ></div>

<label class="control-label no_help  Showaxismode1  Hideaxismode0  InitialDisplayNone  groupshowhideelement" for="axismin_0">Vertical   
Axis Minimum (MB)</label>
<div class="controls  Showaxismode1  Hideaxismode0  InitialDisplayNone  groupshowhideelement" data-placement="top" >
<input type="text" class="text"  data-rule-number="true" data-rule-required="true" autocomplete="off" name="axismin_0" id="axismin_0"   
value="" ><input type="hidden" name="axismin_0_factor" id="axismin_0_factor" value="9.5367431640625E-7" ></div>

</div>
   <input type="hidden" name="id" value="5358">
   <input type="hidden" name="anti-csrf-token"
value="ZjE3ZjUzZThjZDAyMjkwY2FmMmU1NWEwYjVlN2NkZjUyNjAzZjg5YjIzNzhiZWJlZDU3NDJhY2YzYmZkM2UxOA==">
   <!-- <input type="hidden" name="targeturl" value="/sensor.htm?id=5358&tabid=11"> -->
  </div>
 </fieldset>
 <div class="submitbuttonboxanchor">
  <div class="submitbuttonbox">
   <input style="" id="mysubmit" class="submit button btngrey" type="submit" value="Save">
   <input style="" onclick="history.back();return(false)" class="cancel btngrey button hideinwingui" type="reset" value="Cancel">       
  </div>
 </div>
</form>

    </div>
  </div>
</div>
carsten0407 commented 2 years ago

too much output here, how can I redirect in a file?

lordmilko commented 2 years ago

This is the output of Get-Channel with -Verbose, however I do not see the output of Set-ChannelProperty with -Verbose here

carsten0407 commented 2 years ago

I have the dump, it's big but unfortunately with a lot of customer information.

carsten0407 commented 2 years ago

can I share it to you with privacy

lordmilko commented 2 years ago

From Set-ChannelProperty I just need the API URLs that were executed

If you do Set-PrtgClient -LogLevel Request and do Set-ChannelProperty with -Verbose again this will just give you the API calls that were executed. There shouldn't be any sensitive customer information in these

lordmilko commented 2 years ago

get-probe -name customer | get-sensor -id 5358 | Get-Channel -id 0 | Set-ChannelProperty -LowerErrorLimit 50000 -Verbose

Black-Pawn-C7 commented 2 years ago

This is not a Problem with PrtgAPI but rather a conversion error. You are setting the LowerErrorLimit to 50000 Byte not to 50000 MB. To be more specific 50000 Byte = 0.04768372 MiB which is exactly the value being displayed. Use 52428800000 instead of 50000 and your script will work

lordmilko commented 2 years ago

When you tell PRTG to display figures in megabytes, or any other unit, it is possible to say "50000" in the user interface, which will correctly be interpreted as 50,000 megabytes, not 50,000 bytes

The way this works is that a unit "factor" is submitted along with the API request that tells it how to correctly process the number you submitted

The following shows the API request that is made when setting a channel on a WMI Free Disk Space sensor on my system

C:\> get-device ci*|get-sensor "*disk free*"|get-channel total|Set-ChannelProperty -UpperErrorLimit 1000 -verbose

http://prtg.example.com/editsettings?id=2061&limitmaxerror_-1=1000&limitmode_-1=1&limitmaxerror_-1_factor=9.5367431640625E-07&username=prtgadmin&passhash=****

The limitmaxerror_-1_factor field tells PRTG that the value I submitted - 1000, is a value in megabytes, not bytes. When I check the web UI, I confirm I get the value 1000 as expected

image

If this is not working as expected, this implies there is an issue with how PrtgAPI selects the factor to include in the request (there are actual several factors returned, and I simply assume they're all always the same). Hence I need to see both the full requests and responses that are made when this is not working

carsten0407 commented 10 months ago

0.04768372

Okay, this makes sense and has also worked in our environment. However, it is still inexplicable. When we execute the command on a German server with a German OS, the output works without any issues; it enters the 5000MB. On an English OS, we get 0.04768372. Conversely, this happens with a server with an English ISE, and it works seamlessly on all English servers but not on the German one. It's complex and difficult to explain, I know. In summary, it must be a language-related issue, but which one? Everything was working fine until last week.

lordmilko commented 10 months ago

It's possible this has to do with how some regions use a period for denoting a decimal place, while others use a comma. What PrtgAPI will send in some circumstances can depend on your client operating system region settings, and what PRTG may require in some circumstances may depend on the PRTG server's operating system region settings