Once I established a way to perform an Azure Function call from a PRTG REST sensor, I wanted to programmatically deploy this sensor for consistency across multiple environments.
To do so I made use of the excellent PrtgAPI project from lordmilko. This wraps the PRTG REST API into easy to use and understand PowerShell, which is very effective for my team’s ability to use and re-use things written with it.
What follows is an extremely bare-bones method of deploying a PRTG custom REST sensor using PrtgAPI with PowerShell. What it does not contain are appropriate tests or error-handling, parameter change handling, or removal. Thus warned, use at your own risk.
This example is specifically built for an Azure Function which monitors an Application Gateway health probe, and the parameters are tailored as such.
First I start by defining the parameters to be used, aligned with the Application Gateway http setting I want to monitor – as in my previous post I wanted a separate sensor for each http setting associated with a listener.
# Input Variables - update accordingly $ClientCode = "abc" $resourcegroupname = "$($clientcode)-srv-rg" # resource group where the Application Gateway is located $appgwname = "$clientcode AppGw" # name of the application gateway $httpsettingname = @("Test","Prod") $probename = "Probe1" $subscriptionid = "549d4d62" # Client Azure subscription $appsvcname = "AppGw Monitor" $appsvcFQDN = "prod-appsvc.azurewebsites.net" $functionName = "Get-AppGw-Health" $functionKey = "secret function key for PRTG" $tenantid = "f5f7b07a" # Azure tenant id |
Then I use the PrtgAPI module – install if not already, and connect to a PRTG Core:
# PrtgAPI is being used: https://github.com/lordmilko/PrtgAPI #Check if module is installed, and install it if not $moduleinstalled = get-module prtgapi -listavailable if ($moduleinstalled) { Write-Host "Pre-requisite Module is installed, will continue" } else { Install-Package PrtgAPI -Source PSGallery -Force Write-Host "Installing PrtgApi from the PSGallery" } # Check and see if we're already connected to PRTG Core $prtgconnection = Get-PrtgClient if (!$prtgconnection) { # If not, make the connection Write-Host "You will now be prompted for your PRTG credentials" Connect-PrtgServer prtgserver.domain.com } Write-Host "Connected to PRTG. Proceeding with setup." |
Next I test for existence of a device, which will be used to branch whether I am creating a sensor under the device, or need to create the device and the sensor together:
# Using our defined group structure, check for the device existence $device = Get-Probe $probename | Get-Group "Services" | Get-Group "Application Gateways" | Get-Device $appsvcname |
Because I have one Application Gateway with multple http settings serving multiple back-end pools, I need to do a foreach loop around each object in the httpsetting array. Inside that loop, I build the JSON body that will be passed in the POST request to the Azure Function:
$Body = @" { "httpsettingname": "$setting", "resourcegroupname": "$resourcegroupname", "appgwname": "$appgwname", "subscriptionid": "$subscriptionid", "tenantid": "$tenantid" } "@ |
Now I check for the device and sensor (fairly self-explanatory) and finally get to the meat and potatoes of the sensor creation.
Up first is defining the parameters for the sensor that will be created. The wiki for PrtgAPI recommends the use of Dynamic Parameters and to start by constructing a set of DynamicSensorParameters from the raw sensor type identifier.
Once I have that in a PowerShell object, I begin to apply my own values for various parameter attributes:
# Gather a default set of parameters for the type of sensor that we want to create $params = Get-Device $device | New-SensorParameters -RawType restcustom | Select-object -First 1 # selecting first because PrtgApi seems to find multiple devices with same name # For some reason, above command creates two objects in Params, so we only target the first one by getting -First 1 # Populate the sensor parameters with our desired values $params.query = "/api/$($functionName)?code=$functionKey" $params.jsonfile = "azureappgwhealth.template" # use the standard template that was built $params.protocol = 1 # sets as HTTPS $params.requestbody = $body $params.Interval = "00:5:00" # 5 minute interval, deviates from the default $params.requesttype = 1 # this makes it a POST instead of GET if ($setting -like "*prod*") { # Set some Tags on the sensor $params.Tags = @("restcustomsensor", "restsensor", "Tier2", "$($ClientCode.toUpper())", "ApplicationGateway", "PRTGMaintenance", "Production") } else { # Assume Test if not prod, set a different set of Tags $params.Tags = @("restcustomsensor", "restsensor", "Tier2", "$($ClientCode.toUpper())", "ApplicationGateway", "PRTGMaintenance", "NonProduction") } $params.Name = "$($appgwname) $($setting)" |
Finally, I can create the sensor by using this one line:
$sensor = $device | Add-Sensor $params # Create the sensor |
That’s pretty much it! For each of the different http settings and health probe back-ends I modify the variables at the top of this script, and then run it again; obviously there are much better ways to make this reproducible, however I haven’t been able to commit that time.