-
-
Notifications
You must be signed in to change notification settings - Fork 38
Sensor Factories
PrtgAPI can assist in the creation of complex sensor factories via the New-SensorFactoryDefinition
cmdlet.
New-SensorFactoryDefinition
can be used to automatically create channel definition records for a collection of PRTG Sensors. As a shorthand, the New-SensorFactoryDefinition
cmdlet can be invoked via the fdef
alias.
At a minimum New-SensorFactoryDefinition
requires one argument: a script block for determining the channel name
# Create a sensor factory for all CPU Load sensors using the "Total" channel (ID: 0)
C:\> Get-Sensor -Tags wmicpuloadsensor | fdef { $_.Device }
#1:dc1
channel(1001,0)
#2:exch1
channel(2003,0)
#3:dc2
channel(1004,0)
...
If no -ChannelId
is specified, Channel ID 0 will be used by default.
You can also inject your definition straight into an existing sensor using Set-ObjectProperty
# Get the sensor factory sensor
$factory = Get-Sensor -Id 3045
# Create the sensor factory definition. If you need to execute New-SensorFactoryDefinition
# multiple times (see below), you can accumulate the results in an array
$definition = Get-Sensor -Tags wmicpuloadsensor | fdef { $_.Device } 0
# Update the channel definition
$factory | Set-ObjectProperty ChannelDefinition $definition
If you wish to update your definition manually, you can copy your definitions straight onto the clipboard by piping your output to clip
, making it a lot easier to insert your definition into the PRTG web interface.
Get-Sensor -Tags wmicpuloadsensor | fdef { $_.Device } 0 | clip
When creating your sensor factory it is often ideal to sort your sensors before creating your definitions. When using the sensor's Device as the channel name, this can be done quite easily by piping into |sort Device
Get-Sensor -Tags wmicpuloadsensor | sort Device | fdef ...
If you wish to start at a channel record ID higher than 1 (for example if you have an aggregation channel definition you'll want to insert above) you can specify the -StartId
parameter.
C:\> Get-Sensor -Tags wmicpuloadsensor | fdef { $_.Device} 0 -StartId 2
#2:dc1
channel(1001,0)
#3:exch1
channel(2001,0)
...
If you wish to specify a custom unit for each channel you can include this in the channel name
Get-Sensor -Tags wmicpu* | fdef { "$($_.Device) [bananas]" } 0
Horizontal lines can be generated by specifying the -Value
the line should appear at and including the channel unit the line should apply to
C:\> fdef "Line at 40.2 [msec]" -Value 40.2 -StartId 3
#3:Line at 40.2 [msec]
40.2
For scenarios in which you may wish to change the the formula used by each channel definition (for example transforming a "percent remaining" value into "percent used") you can specify a custom -Expression
# Create a sensor factory displaying the amount of "used" memory
# by inverting the "Percent Available Memory" channel (ID: 0)
C:\> $sensors = Get-Sensor -Tags wmimemorysensor
C:\> $sensors | fdef { $_.Device } -Expression { "100 - $expr" }
#1:dc1
100 - channel(1001,0)
#2:exch1
100 - channel(2003,0)
#3:dc2(1004,0)
...
When specifying a custom expression, New-SensorFactoryDefinition
defines two automatic variables that can be accessed inside of your script block
-
$_
- the current sensor in the pipeline -
$expr
- the default channel definition/expression
By default, PrtgAPI creates channel definitions in the format channel(<sensorId>, <channelID>). If you wish to create a sensor factory using sensors requiring different channel IDs (such as if your factory includes sensors of a different type, or the IDs of the channels in your sensors cannot be guaranteed) you can implement custom logic in the -Expression
script block to determine the channel ID to use.
# Create a sensor factory for monitoring the CPU Ready of several VMware Virtual Machine (SOAP) sensors under the
# vCenter server "vcenter-1". Typically the CPU ready channel should be ID 10, but sometimes it is not!
$sensors = Get-Sensor -Type vcenterserverextern -Device vcenter-1 | where Message -notlike "*powered off*"|sort name
$sensors | fdef {$_.Name} -expr {"channel($($_.Id),$(($_ | Get-Channel "CPU ready (Percent)").Id))"} -ChannelId 10
To create a channel definition that involves performing mathematical operations across multiple sensor channels the -Aggregator
parameter can be specified.
# Determine the total number of Active Sessions across all terminal servers
C:\> $sensors = Get-Sensor -Tags wmiterminalservice*
C:\> $sensors | fdef "Active Sessions" -Aggregator { "$acc + $expr" } 1
#1:Active Sessions
channel(1001,1) + channel(2002,1) + channel(3001,1) ...
# Determine the highest CPU Load of all CPU Load sensors
C:\> $sensors = Get-Sensor -Tags wmicpuloadsensor
C:\> $sensors | fdef "Highest CPU Load" -Aggregator { "max($expr,$acc)" }
#1:Highest CPU Load
max(channel(1001,0),max(channel(2001,0),max(channel(3001,0),channel(4001,0))))
When specifying an -Aggregator
, either a custom ScriptBlock
expression or well known aggregation function (Sum
, Min
, Max
, Average
) can be used.
$sensors | fdef "Highest CPU Load" -Aggregator Max
When specifying a custom aggregator, New-SensorFactoryDefinition
defines three automatic variables that can be accessed inside of your script block
-
$_
- the current sensor in the pipeline -
$expr
- the default channel definition/expression of the current sensor -
$acc
- the accumulator, containing the entire channel definition so far.
When operating in aggregation mode, PrtgAPI will only create a single channel definition for all sensors piped into the cmdlet. To create an aggregation definition as well as definitions for each individual sensor, you can re-run New-SensorFactoryDefinition
specifying the StartId
parameter, or alternatively specify a collection of hashtable objects specifying the parameters of both New-SensorFactoryDefinition
invocations as properties on each separate hashtable.
C:\> $sensors = Get-Sensor -Tags wmiterminalservice*
C:\> $sensors | fdef { $_.Device } 1 -StartId 2
#2:ts1
channel(1001,1)
#3:ts2
channel(2002,1)
...
As specifying a custom -Expression
allows you to override the channel ID for individual sensors, it should be generally unnecessary to refer to the raw pipeline input ($_
) in the aggregation function. If you wish to redefine the expression used in the aggregation, please note that PrtgAPI automatically sets $acc
to the first sensor's expression. As such, you will not be able to modify its channel ID without an amount of manual checking and intervention.
If you do wish to perform a second level expression modification (beyond the initial modifications in the -Expression
function) you may wish to ensure that the -ChannelID
passed to New-SensorFactoryDefinition
is the right value for the first sensor you pipe in, allowing you to redefine the expression for all subsequent sensors without issue.
If you are trying to generate a sensor factory definition consisting of aggregation channels as well as the individual channels each aggregation consists of, this can be achieved either via multiple varying invocations of the New-SensorFactoryDefinition
cmdlet or by specifying a collection of hashtables. For the most common case however of a leading aggregation channel followed by its constituents, this can be done in a single invocation via the Summary parameter set.
For scenarios requiring post processing actions be performed on accumulated results the -Finalizer
parameter can be used. -Finalizer
makes it possible to perform slightly more complex calculations, such as calculating an average
C:\> $sensors = Get-Sensor -Tags wmicpuloadsensor
C:\> $sensors | fdef "Average CPU Load" -Aggregator { "$expr + $acc" } -Finalizer { "($acc)/$($sensors.Count)" } 0
#1:Average CPU Load
(channel(1001,0) + channel(2001,0) + channel(3001,0) + channel(4001,0))/4
A -Finalizer
can only be applied when -Aggregator
is a ScriptBlock
. If a well known aggregation function is specified in conjunction with a -Finalizer
, an exception will be raised.
While it is possible to generate aggregated channels in addition to individual channels via multiple invocations of New-SensorFactoryDefinition
or by specifying a collection of hashtables, this can be somewhat tedious for the common case of desiring a leading aggregation channel followed by its constituents.
To assist with this scenario, PrtgAPI allows specifying an optional -SummaryName
/ -SummaryExpression
.
C:\> Get-Sensor -Tags wmicpu* | fdef { $_.Device } -SummaryName "Highest CPU Load" -SummaryExpression max
#1:Highest CPU Load
max(max(channel(2020,0), channel(2047,0)), channel(2059,0))
#2:dc-1
channel(2020,0)
#3:prtg-1
channel(2047,0)
#4:fs-1
channel(2059,0)
-SummaryExpression
functions identically to the -Aggregator parameter. Either a well known aggregation function or a ScriptBlock
can be specified to the -SummaryExpression
. If a custom ScriptBlock
expression is specified, an optional -SummaryFinalizer can be specified too.
For convenience, all summary parameters can be referred to via the following aliases
-
-SummaryName
:-sn
-
-SummaryExpression
:-se
-
-SummaryFinalizer
:-sf
Get-Sensor -Tags wmicpu* | fdef { $_.Device } -sn "Highest CPU Load" -se max
When trying to generate sensor factory definitions showing multiple channels of a given sensor, this can typically require multiple invocations of New-SensorFactoryDefinition
to be performed, requiring you to keep track of what the -StartId
should be for each successive invocation. This isn't very user friendly, can potentially require you to have to split your command up over multiple lines, or even have to open the PowerShell ISE to lay it all out in front of you.
The -HashTable
parameter solves this problem, by allowing you to specify an array of hashtables, each containing the unique parameters that would be specified to an individual invocation of New-SensorFactoryDefinition
. New-SensorFactoryDefinition
will then iterate over these tables, storing the running channel record ID internally, spitting out all of the requested channel definitions as it goes
C:\> Get-Sensor -Tags wmimem* | fdef @{name={$_.Device}},@{name="Line at 40.2 [msec]";value=40.2}
#1:dc-1
channel(1001,0)
#2:dc-2
channel(1002,0)
#3:Line at 40.2 [msec]
40.2
PrtgAPI uses the PowerShell Engine to resolve the parameter names specified to the hashtables to the parameter names normally defined on the outer cmdlet; as such, you can treat the hashtables the same as you would if you were specifying parameters to the outer cmdlet normally.
By default, channels will begin incrementing the channel record ID from 1, which can be changed by specifying a value to the -StartId
parameter on the outer cmdlet. If a StartId
is specified as a value to an inner hashtable, this will effectively override the running count.
C:\> Get-Sensor | fdef @{name={$_.Device}; startid=3} -StartId 2
#3:dc-1
channel(1001,0)
#4:dc-2
channel(1002,0)
Brand new sensor factories can be created using New-SensorFactoryDefinition
style syntax and immediately added to a specified device using the New-Sensor
cmdlet
# Create a sensor factory called "CPU Overview" on the device with ID 1001
Get-Sensor -Tags wmicpu* | New-Sensor -Factory "CPU Overview" { $_.Device } -DestinationId 1001
The first three parameters to New-Sensor
when creating a new sensor factory are always as follows
-
-Factory
SwitchParameter
indicating we are creating a sensor factory -
-Name
parameter specifying the name of the sensor to create, not the name to use in the sensor factory definition -
-ChannelName
parameter specifying the normal name you would specify when invokingNew-SensorFactoryDefinition
manually
If you forget to specify parameter #2 and jump straight to specifying a ScriptBlock
for the -ChannelName
, you will get a ParameterBindingException
and be very confused as to why it's not working.
# WRONG
Get-Sensor -Tags wmimem* | New-Sensor -Factory { $_.Device } -DestinationId 1001 -WhatIf
All of the techniques that apply to New-SensorFactoryDefinition
can be used in conjunction with the New-Sensor
cmdlet. Properties of the new sensor factory sensor itself can also be specified
# Create a CPU Overview sensor factory that includes a summary channel and
# displays a warning if any of the factory's channels enters an error state
$sensors | New-Sensor -Factory "CPU Overview" { $_.Device } -sn "Average Usage" -se Average -FactoryErrorMode WarnOnError -DestinationId 1001
To preview your sensor factory definition without actually creating your sensor, you can specify the -WhatIf
parameter
C:\> Get-Sensor -Tags wmicpu* | New-Sensor -Factory "CPU Overview" { $_.Device } -sn "Average CPU" -se Average -DestinationId 1001 -WhatIf
What if: Performing the operation "New-Sensor: Name = 'CPU Overview', ChannelDefinition =
#1:Average CPU
avg(channel(2020,0), channel(2047,0), channel(2059,0))
#2:dc-1
channel(2020,0)
#3:prtg-1
channel(2047,0)
#4:fs-1
channel(2059,0)
" on target "Device ID: 1001".
If you want to create your sensor factory definition yourself (or utilize the output of an existing New-SensorFactoryDefinition
invocation) this can be done using the -ChannelDefinition
parameter of the appropriate parameter set. For more information on the available parameter sets, see Get-Help New-Sensor
.
Create a sensor factory for displaying the total number of sessions on all servers in a terminal services cluster. Factory will contain four channel types
- Total Sessions - displays total number of sessions across all servers
- TSxx Total Sessions - displays total number of sessions on each server
- Total Active Sessions - displays total number of active sessions across all servers
- TSxx Active Sessions - displays number of active sessions on each server
WMI Terminal Services (Win2008+) sensor on each terminal server
Servers are named in the format <client>-ts-xx
# Get all the sensors
$sensors = Get-Device contoso-ts* | sort Device | Get-Sensor -Tags wmiterm*
# Create the "Total Sessions" channels
$sensors | fdef { "TS$($_.Device -replace "(.+)(\d\d)",'$2') Total Sessions" } 0 -sn "Total Sessions" -se Sum
# Create the "Active Sessions" channels
$sensors | fdef { "TS$($_.Device -replace "(.+)(\d\d)",'$2') Active Sessions" } 1 -sn "Active Sessions" -se Sum -Start ($sensors.Count + 2)
Alternatively, you could create the whole thing in a one-liner. By specifying a collection of hashtables, New-SensorFactoryDefinition
keeps track of the running -StartId
for you, so you don't need to worry about this, as you would in the example above. For readability, you may wish to split each individual hashtable up into a separate variable. Most of the complexity in this example is the logic of formatting the channel display name.
Get-Device contoso-ts* | sort Device | Get-Sensor -Tags wmiterm* |
fdef @{name={"TS$($_.Device -replace "(.+)(\d\d)",'$2') Total Sessions"}; sn="Total Sessions"; se="Sum"},
@{name={"TS$($_.Device -replace "(.+)(\d\d)",'$2') Active Sessions"}; channelid=1; sn="Active Sessions"; se="Sum"}
#1:Total Sessions
channel(1001,0)+channel(1002,0)+channel(1003,0)
#2:TS02 Total Sessions
channel(1001,0)
#3:TS01 Total Sessions
channel(1002,0)
#4:TS03 Total Sessions
channel(1003,0)
#5:Total Active Sessions
channel(1001,1)+channel(1002,1)+channel(1003,1)
#6:TS02 Total Sessions
channel(1001,1)
#7:TS01 Total Sessions
channel(1002,1)
#8:TS03 Total Sessions
channel(1003,1)
The sensors and channels that comprise a sensor factory can be retrieved using the Get-SensorFactorySource
cmdlet.
C:\> Get-Sensor -Type "sensorfactory" -Count 1 | Get-SensorFactorySource
Name Id Device Group Probe Status
---- -- ------ ----- ----- ------
Memory 2010 dc-1 Servers Local Probe Up
Memory 2011 sql-1 Servers Local Probe Down
Memory 2012 exch-1 Servers Remote Probe DownAcknowledged
If a sensor that is not a sensor factory is passed to Get-SensorFactorySource
, an exception will be thrown.
By default Get-SensorFactorySource
will retrieve the sensors that comprise a sensor factory. To retrieve the source channels instead, the -Channels
parameter can be specified
C:\> Get-Sensor -Type "sensorfactory" -Count 1 | Get-SensorFactorySource -Channels
Name SensorId Id LastValue LimitsEnabled UpperErrorLimit LowerErrorLimit ErrorLimitMessage
---- -------- -- --------- ------------- --------------- --------------- -----------------
Available Memory 2010 0 100 MByte True 95 PANIC!! PANIC!!!
Available Memory 2011 0 235 MByte False
Available Memory 2012 0 312 MByte False