-
-
Notifications
You must be signed in to change notification settings - Fork 38
Migration
Using PrtgAPI's infrastructure as code model, PRTG nodes can easily be instantiated and configured across a variety of PRTG servers. This is all very well and good if you've configured configured your entire PRTG system via infrastructure as code from scratch, but what if you have an existing system with tens of thousands of existing sensors and devices?
In this article, we will explore how PrtgAPI can be used to export your entire PRTG object tree to a PowerShell config file, and then apply that tree to a completely different PRTG server.
At a high level, there are four steps must be required in order to migrate your PRTG objects between two servers
- Export your tree
- Develop any required parameter transformers
- Construct a plan for applying your tree on the target server
- Apply the tree. Fingers crossed!
Depending on the number and types of different sensors in your tree, this may or may not prove to be a fairly trivial matter. The most challenging part for you will most likely be developing your parameter transformers. The complexity of this will simply be based on the number of different sensor types you have; you could have 100,000 different sensors in your PRTG installation, but if they're all SNMP Traffic sensors, this shouldn't be too hard at all.
When you manually define a SensorNode
using PrtgAPI's infrastruture as code model, you can define all the parameters that should be used to configure the DynamicSensorParameters
object
SensorNode *exchange* {
WhenNewNode @{
rt = "wmiservice"
Target = "*exchange*"
restart = 1
}
}
When you export an existing tree from PRTG using the Export-PrtgTree
cmdlet however, this isn't exactly possible. While PrtgAPI can export a dump of all the raw object properties defined on the existing sensor, not all of these may neatly line up with the parameters that must be specified when an object is originally created in the first place. For example, consider the output of Get-ObjectProperty -Raw
on a WMI Service sensor
...
monitorchange : 1
monitorextended : 0
service : PRTGCoreService
...
Now compare that to the parameters that must be defined when you do New-SensorParameters -RawType wmiservice
monitorchange : 1
monitorextended : 0
service : 1
service__check : PRTG Core Server Service
There is a huge difference between the properties emitted by these two commands
Property | Raw Parameters | DynamicSensorParameters | Difference |
---|---|---|---|
monitorchange | Numeric Bool | Numeric Bool | None |
monitorextended | Numeric Bool | Numeric Bool | None |
service | string (Service Name) | Numeric Bool | Type |
service__check | N/A | SensorTarget |
Missing! |
When it comes to the monitorchange
and monitorextended
properties, both of these exist with the same names in both data sources. When it comes to the service
and service__check
properties however, we have a big problem. When creating a sensor, the service
property needs to be set to 1
. If we simply tried to overwrite the parameters of the DynamicSensorParameters
object with the raw properties we got from the object, not only would we corrupt the parameters (setting the service
to anything other than 1
on the creation parameters is illegal) but we wouldn't even set the desired service to use properly (we never said what value to use for the service__check
parameter)!
What really needs to happen, in this scenario, is for the service__check
parameter on the DynamicSensorParameters
object to be set to the service contained in the service
property of the original object we're now trying to recreate.
This is where parameter transformers come in. A parameter transformer is a custom PowerShell class you can define that describes the custom bindings that need to be done between a DynamicSensorParameters
object and the original raw object properties that were contained on the original sensor.
class Transformer
{
[void]wmiservice($config)
{
$config.Parameters["service"] = 1
$config.Parameters["service__check"] = $config.GetTargetFromProperty("service")
}
}
Each parameter transformer contains one or more methods corresponding to the sensor types they know how to handle. The actions a parameter transformer method performs should pertain to the entire sensor type, rather than a particular instance of a given sensor you want to create. Once you (or someone else) has written a parameter transformer method supporting a given type, barring any changes within PRTG, you never have to re-write that method ever again - you've already figured out what the mapping is between the various creation parameters and raw object properties.
Prior to invoking your parameter transformer method, PrtgAPI automatically binds any raw object properties from the source sensor to the DynamicSensorParameters
object. As such, properties like monitorchange
and monitorextended
on WMI Service sensors will have already been set to the same values they had on the original sensor. You're only really going to have an issue with sensors where a SensorTarget
needs to be defined, or there's a mismatch between what the parameters are called during object creation vs after the fact.
In the event PrtgAPI's automatic parameter binding has totally corrupted your DynamicSensorParameters
object, you can reset all parameters on the object back to their default values using the Reset
method
$config.Parameters.Reset()
This can be useful in showing you what the default values of each parameter was, and thus help you to figure out whether or not PrtgAPI inadvertently corrupted the parameters. In the example above, since the only property that was corrupted on the WMI Service sensor was the service
property, we simply opted to correct that property manually, rather than having to ensure we manually rebind all of the other WMI Service properties ourselves
Many sensor types are quite simple, and do not require the use of parameter transformers. PrtgAPI also has inbuilt support for a few different sensor types, so you don't have to worry about defining your own transformers:
- WMI Service
If you find PrtgAPI's default parameter transformer handlers don't handle things properly however, you can simply define your own in your own parameter transformer and PrtgAPI will use your custom one instead