Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate Hash Tabel entries #12

Closed
bvanbavel opened this issue Apr 20, 2018 · 6 comments
Closed

Duplicate Hash Tabel entries #12

bvanbavel opened this issue Apr 20, 2018 · 6 comments
Labels
enhancement Items that are on the todo list for incorporating into PrtgAPI in a future release

Comments

@bvanbavel
Copy link

When creating a raw sensor the hashtabel will not acces duplicate entries. This seems required when adding an snmptraffic sensor and you want to enable errors and discards. Fiddler shows the option Trafficmode_ is added three times:
&trafficmode_=standinfornoselection
&trafficmode_=errors
&trafficmode_=discards
This seems not possible with the API.

@lordmilko
Copy link
Owner

lordmilko commented Apr 20, 2018

Hi @bvanbavel,

This is a bit of a problem!

So there are multiple ways to create a set of raw sensor parameters in PrtgAPI:

  1. Importing a hashtable
  2. Modifying parameter properties
  3. Accessing the underlying parameter set

By accessing the underlying parameter set (demonstrated below) it is possible to achieve the functionality you desire. It is expected you cannot specify a trafficmode more than once in a hashtable, however the bigger issue is that when you interface with a NewSensorParameters object there is no simple method for accessing a parameter that has been specified multiple times.

The core issue is that the CustomParameter type does not allow specifying a list of items. The reason for this is that there is no way to know whether you wanted a list in the form name=val1,val2,val3 or name=val1&name=val2. As such, we say that if you want to have multiple instances of a parameter (as we do in this situation) you need to create multiple separate parameter objects

In C# this isn't too hard

var parameters = RawSensorParameters("Traffic", "snmptraffic");
parameters.Parameters.Add(new CustomParameter("trafficmode_", "errors");
parameters.Parameters.Add(new CustomParameter("trafficmode_", "discards");

But in PowerShell it is a lot more tedious

C:\> $params = New-SensorParameters -Empty
C:\> $params.Name = "Traffic"
C:\> $params.SensorType = "snmptraffic"
C:\> $params.Parameters.Add((New-Object PrtgAPI.Parameters.CustomParameter "trafficmode_","errors"))
C:\> $params.Parameters.Add((New-Object PrtgAPI.Parameters.CustomParameter "trafficmode_","discards"))

C:\> $params.Parameters

Name         Value
----         -----
name_        Traffic
trafficmode_ errors
trafficmode_ discards

Of course, if you just wrap the addition of raw custom parameters up in a function there's almost no issue!

function AddParam($params, $name, $val)
{
    $params.Parameters.Add((New-Object PrtgAPI.Parameters.CustomParameter $name,$val))
}

AddParam $params "trafficmode_" "errors"
AddParam $params "trafficmode_" "discards"

A potential solution to this could potentially be to create a new type, CustomListParameter. All RawSensorParameter parameters could then use this type instead of CustomParameter. This would allow you to create multiple instances of a parameter simply by assigning a list to the property. In the event you wanted something in the form name=val1,val2,val3 you can simply assign the literal string val1,val2,val3 as you would have been expected to do previously. You would then also be able to use a hashtable again; simply specify @{ "trafficmode_" = "errors","discards" }

I will have a think about this and try and implement a solution within the next few days

Note: depending on your use case you may want to consider using dynamic sensor parameters instead of constructing parameters manually (however for now you will still have the duplicate trafficmode issue)

Regards,
lordmilko

@bvanbavel
Copy link
Author

Dear Lordmilko,
Thanks for the quick reply and the great work on the repository! Much appreciated!

I created the following code, but unfortunatly is does not add the variable for me:
$params = New-SensorParameters -Empty
$params.Name = "$($interface.name)"
$params.SensorType = "snmptraffic"
$params.Parameters.Add((New-Object PrtgAPI.Parameters.CustomParameter "interfacenumber_","1"))
$params.Parameters.Add((New-Object PrtgAPI.Parameters.CustomParameter "interfacenumber__check","$($interface.properties -join '|')"))
$params.Parameters.Add((New-Object PrtgAPI.Parameters.CustomParameter "trafficmode_","standinfornoselection"))
$params.Parameters.Add((New-Object PrtgAPI.Parameters.CustomParameter "trafficmode_","errors"))
$params.Parameters.Add((New-Object PrtgAPI.Parameters.CustomParameter "trafficmode_","discards"))
$params.Parameters.Add((New-Object PrtgAPI.Parameters.CustomParameter "monitorstate_","1"))

Result:
PS C:\Users\User> $params
SensorType : snmptraffic
Priority :
InheritTriggers :
InheritInterval :
Interval :
IntervalErrorMode :
Name : (10150) ### Port-Channel1 Link B ### Traffic

Kind regards, Bart

@lordmilko
Copy link
Owner

lordmilko commented Apr 21, 2018

Hi @bvanbavel,

There was a typo in my original response; if you type $params.Parameters you will see the specified parameters have been added

Name                   Value
----                   -----
name_
interfacenumber_       1
interfacenumber__check
trafficmode_           standinfornoselection
trafficmode_           errors
trafficmode_           discards
monitorstate_          1

Note that you don't have to create a new CustomParameter object for every parameter, so your code can be simplified to

$params = New-SensorParameters -Empty
$params.Name = "$($interface.name)"
$params.SensorType = "snmptraffic"
$params["interfacenumber_"] = 1
$params["interfacenumber__check"] = "$($interface.properties -join '|')"
$params["monitorstate_"] = 1
"standinfornoselection","errors","discards" | foreach { $params.Parameters.Add((New-Object PrtgAPI.Parameters.CustomParameter "trafficmode_",$_)) }

Note you might have some issues with your interfacenumber__check value, as I have a feeling It'll need to be in the form |<value>|<name>||

Regards,
lordmilko

@bvanbavel
Copy link
Author

You're right, it worked! Powershell ISE autocomplete didn't help as it tried to correct $params.Parameters into $params.getparameter(). Script is ready to be used for my customer migration this week.
Thanks again and have a great weekend!

lordmilko added a commit that referenced this issue Apr 23, 2018
…meter

-Raw/Dynamic custom parameters now use ParameterType.MultiParameter by default
-Implemented support for modifying multi parameter properties with Set-ObjectProperty
-Raw parameters now show all selected checkbox values when a field contain
multiple values. If no checkboxes are selected, an empty string is displayed

For #12
@lordmilko
Copy link
Owner

Hi @bvanbavel,

PrtgAPI 0.8.4 has now been released. CustomParameter objects now support specifying a ParameterType indicating whether they contain a

  • single value: name=val
  • multi value: name=val1,val2, or
  • multi parameter: name=val1&name=val2

All CustomParameter objects created by RawSensorParameters / DynamicSensorParameters now operate in MultiParameter mode by default

As such, it is now possible to create raw SNMP Traffic parameters as follows

$params = New-SensorParameters -Empty
$params.Name = "$($interface.name)"
$params.SensorType = "snmptraffic"
$params["interfacenumber_"] = 1
$params["interfacenumber__check"] = "$($interface.properties -join '|')"
$params["monitorstate_"] = 1
$params["trafficmode_"] = "standinfornoselection","errors","discards"

or, via a hashtable

$table = @{
    name_ = "Base Sensor"
    sensortype = "snmptraffic"
    interfacenumber_ = 1
    interfacenumber__check = ("$($interface.properties -join '|')") + "|"
    monitorstate_ = 1
    trafficmode_ = "standinfornoselection","errors","discards"
}

$params = New-SensorParameters $table

I have also fixed a bug wherein it was not possible to enumerate all enabled trafficmode values on existing SNMP Traffic sensor via Get-ObjectProperty -Raw.

You can update PrtgAPI by running Update-Module PrtgAPI and then re-opening your current PowerShell prompt.

Please see the release notes to be aware of any breaking changes

Given your existing script appears to have been tested and working however, it may be worth holding off upgrading until after your migration has completed

Regards,
lordmilko

@bvanbavel
Copy link
Author

Great,

Thanks again for the great help! The workaround also worked perfectly. We had a smooth migration last week!

Regards, Bart

@lordmilko lordmilko added the enhancement Items that are on the todo list for incorporating into PrtgAPI in a future release label Jun 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Items that are on the todo list for incorporating into PrtgAPI in a future release
Projects
None yet
Development

No branches or pull requests

2 participants