|
| 1 | + |
| 2 | +function Get-PrtgTableData { |
| 3 | + <# |
| 4 | + .SYNOPSIS |
| 5 | + Returns a PowerShell object containing data from the specified object in PRTG. |
| 6 | + |
| 7 | + .DESCRIPTION |
| 8 | + The Get-PrtgTableData cmdlet can return data of various different content types using the specified parent object, as well as specify the return columns or filtering options. The input formats generally coincide with the Live Data demo from the PRTG API documentation, but there are some content types that the cmdlet does not yet support, such as "sensortree". |
| 9 | + |
| 10 | + .PARAMETER Content |
| 11 | + The type of data to return about the specified object. Valid values are "devices", "groups", "sensors", "todos", "messages", "values", "channels", and "history". Note that all content types are not valid for all object types; for example, a device object can contain no groups or channels. |
| 12 | + |
| 13 | + .PARAMETER ObjectId |
| 14 | + An object ID from PRTG. Objects include probes, groups, devices, and sensors, as well as reports, maps, and todos. |
| 15 | + |
| 16 | + .PARAMETER Columns |
| 17 | + A string array of named column values to return. In general the default return values for a given content type will return all of the available columns; this parameter can be used to change the order of columns or specify which columns to include or ignore. |
| 18 | + |
| 19 | + .PARAMETER FilterTags |
| 20 | + A string array of sensor tags. This parameter only has any effect if the content type is "sensor". Output will only include sensors with the specified tags. Note that specifying multiple tags performs a logical OR of tags. |
| 21 | + |
| 22 | + .PARAMETER Count |
| 23 | + Number of records to return. PRTG's internal default for this is 500. Valid values are 1-50000. |
| 24 | + |
| 25 | + .PARAMETER Raw |
| 26 | + If this switch is set, the cmdlet will return the raw XML data rather than a PowerShell object. |
| 27 | + |
| 28 | + .EXAMPLE |
| 29 | + Get-PrtgTableData groups 1 |
| 30 | + |
| 31 | + Returns the groups under the object ID 1, which is typically the Core Server's Local Probe. |
| 32 | + |
| 33 | + .EXAMPLE |
| 34 | + Get-PrtgTableData sensors -FilterTags corestatesensor,probesensor |
| 35 | + |
| 36 | + Returns a filtered list of sensors tagged with "corestatesensor" or "probesensor". |
| 37 | + |
| 38 | + .EXAMPLE |
| 39 | + Get-PrtgTableData messages 1002 |
| 40 | + |
| 41 | + Returns the messages log for device 1002. |
| 42 | + #> |
| 43 | + |
| 44 | + Param ( |
| 45 | + [Parameter(Mandatory=$True,Position=0)] |
| 46 | + [ValidateSet("probes","groups","devices","sensors","todos","messages","values","channels","history")] |
| 47 | + [string]$Content, |
| 48 | + |
| 49 | + [Parameter(Mandatory=$false,Position=1)] |
| 50 | + [int]$ObjectId = 0, |
| 51 | + |
| 52 | + [Parameter(Mandatory=$False)] |
| 53 | + [string[]]$Columns, |
| 54 | + |
| 55 | + [Parameter(Mandatory=$False)] |
| 56 | + [string[]]$FilterTags, |
| 57 | + |
| 58 | + [Parameter(Mandatory=$False)] |
| 59 | + #[ValidateSet("Unknown","Collecting","Up","Warning","Down","NoProbe","PausedbyUser","PausedbyDependency","PausedbySchedule","Unusual","PausedbyLicense","PausedUntil","DownAcknowledged","DownPartial")] |
| 60 | + [string[]]$FilterStatus, |
| 61 | + |
| 62 | + [Parameter(Mandatory=$False)] |
| 63 | + [int]$Count, |
| 64 | + |
| 65 | + [Parameter(Mandatory=$False)] |
| 66 | + [switch]$Raw |
| 67 | + ) |
| 68 | + |
| 69 | + <# things to add |
| 70 | + |
| 71 | + filter_drel (content = messages only) today, yesterday, 7days, 30days, 12months, 6months - filters messages by timespan |
| 72 | + filter_status (content = sensors only) Unknown=1, Collecting=2, Up=3, Warning=4, Down=5, NoProbe=6, PausedbyUser=7, PausedbyDependency=8, PausedbySchedule=9, Unusual=10, PausedbyLicense=11, PausedUntil=12, DownAcknowledged=13, DownPartial=14 - filters messages by status |
| 73 | + sortby = sorts on named column, ascending (or decending with a leading "-") |
| 74 | + filter_xyz - fulltext filtering. this is a feature in its own right |
| 75 | + |
| 76 | + #> |
| 77 | + |
| 78 | + BEGIN { |
| 79 | + $PRTG = $Global:PrtgServerObject |
| 80 | + if ($PRTG.Protocol -eq "https") { $PRTG.OverrideValidation() } |
| 81 | + |
| 82 | + |
| 83 | + $CountProperty = @{} |
| 84 | + $FilterProperty = @{} |
| 85 | + |
| 86 | + if ($Count) { |
| 87 | + $CountProperty = @{ "count" = $Count } |
| 88 | + } |
| 89 | + |
| 90 | + |
| 91 | + if ($FilterTags -and (!($Content -eq "sensors"))) { |
| 92 | + throw "Get-PrtgTableData: Parameter FilterTags requires content type sensors" |
| 93 | + } elseif ($Content -eq "sensors" -and $FilterTags) { |
| 94 | + $FilterProperty += @{ "filter_tags" = $FilterTags } |
| 95 | + } |
| 96 | + |
| 97 | + if ($FilterStatus -and (!($Content -eq "sensors"))) { |
| 98 | + throw "Get-PrtgTableData: Parameter FilterStatus requires content type sensors" |
| 99 | + } elseif ($Content -eq "sensors" -and $FilterStatus) { |
| 100 | + $FilterProperty += @{ "filter_status" = $FilterStatus } |
| 101 | + } |
| 102 | + |
| 103 | + if (!$Columns) { |
| 104 | + # this function currently doesn't work with "sensortree" or "maps" |
| 105 | + |
| 106 | + $TableLookups = @{ |
| 107 | + "probes" = @("objid","type","name","tags","active","probe","notifiesx","intervalx","access","dependency","probegroupdevice","status","message","priority","upsens","downsens","downacksens","partialdownsens","warnsens","pausedsens","unusualsens","undefinedsens","totalsens","favorite","schedule","comments","condition","basetype","baselink","parentid","fold","groupnum","devicenum") |
| 108 | + |
| 109 | + "groups" = @("objid","type","name","tags","active","group","probe","notifiesx","intervalx","access","dependency","probegroupdevice","status","message","priority","upsens","downsens","downacksens","partialdownsens","warnsens","pausedsens","unusualsens","undefinedsens","totalsens","favorite","schedule","comments","condition","basetype","baselink","parentid","location","fold","groupnum","devicenum") |
| 110 | + |
| 111 | + "devices" = @("objid","type","name","tags","active","device","group","probe","grpdev","notifiesx","intervalx","access","dependency","probegroupdevice","status","message","priority","upsens","downsens","downacksens","partialdownsens","warnsens","pausedsens","unusualsens","undefinedsens","totalsens","favorite","schedule","deviceicon","comments","host","basetype","baselink","icon","parentid","location") |
| 112 | + |
| 113 | + "sensors" = @("objid","type","name","tags","active","downtime","downtimetime","downtimesince","uptime","uptimetime","uptimesince","knowntime","cumsince","sensor","interval","lastcheck","lastup","lastdown","device","group","probe","grpdev","notifiesx","intervalx","access","dependency","probegroupdevice","status","message","priority","lastvalue","lastvalue_raw","upsens","downsens","downacksens","partialdownsens","warnsens","pausedsens","unusualsens","undefinedsens","totalsens","favorite","schedule","minigraph","comments","basetype","baselink","parentid") |
| 114 | + |
| 115 | + "channels" = @("objid","name","lastvalue","lastvalue_raw") |
| 116 | + |
| 117 | + "todos" = @("objid","datetime","name","status","priority","message","active") |
| 118 | + |
| 119 | + "messages" = @("objid","datetime","parent","type","name","status","message") |
| 120 | + |
| 121 | + "values" = @("datetime","value_","coverage") |
| 122 | + |
| 123 | + "history" = @("datetime","dateonly","timeonly","user","message") |
| 124 | + |
| 125 | + "storedreports" = @("objid","name","datetime","size") |
| 126 | + |
| 127 | + "reports" = @("objid","name","template","period","schedule","email","lastrun","nextrun") |
| 128 | + } |
| 129 | + |
| 130 | + $SelectedColumns = $TableLookups.$Content |
| 131 | + } else { |
| 132 | + $SelectedColumns = $Columns |
| 133 | + } |
| 134 | + |
| 135 | + $SelectedColumnsString = $SelectedColumns -join "," |
| 136 | + |
| 137 | + $HTMLColumns = @("downsens","partialdownsens","downacksens","upsens","warnsens","pausedsens","unusualsens","undefinedsens","message","favorite") |
| 138 | + } |
| 139 | + |
| 140 | + PROCESS { |
| 141 | + |
| 142 | + $Parameters = @{ |
| 143 | + "content" = $Content |
| 144 | + "columns" = $SelectedColumnsString |
| 145 | + "id" = $ObjectId |
| 146 | + } ################################################# needs to handle filters! |
| 147 | + |
| 148 | + $Parameters += $CountProperty |
| 149 | + $Parameters += $FilterProperty |
| 150 | + |
| 151 | + $url = $PrtgServerObject.UrlBuilder("api/table.xml",$Parameters) |
| 152 | + |
| 153 | + ##### data returned; do! |
| 154 | + |
| 155 | + if ($Raw) { |
| 156 | + $QueryObject = HelperHTTPQuery $url |
| 157 | + return $QueryObject.Data |
| 158 | + } |
| 159 | + |
| 160 | + $QueryObject = HelperHTTPQuery $url -AsXML |
| 161 | + $Data = $QueryObject.Data |
| 162 | + |
| 163 | + $ReturnData = @() |
| 164 | + |
| 165 | + <# |
| 166 | + |
| 167 | + HOW THIS WILL LIKELY NEED TO WORK |
| 168 | + --- |
| 169 | + |
| 170 | + build a switch statement that uses $Content to determine which types of objects we're going to create |
| 171 | + foreach item, assign all properties to the object |
| 172 | + attach the object to $ReturnData |
| 173 | + |
| 174 | + #> |
| 175 | + |
| 176 | + $PrtgObjectType = switch ($Content) { |
| 177 | + "probes" { "PrtgShell.PrtgProbe" } |
| 178 | + "groups" { "PrtgShell.PrtgGroup" } |
| 179 | + "devices" { "PrtgShell.PrtgDevice" } |
| 180 | + "sensors" { "PrtgShell.PrtgSensor" } |
| 181 | + "todos" { "PrtgShell.PrtgTodo" } |
| 182 | + "messages" { "PrtgShell.PrtgMessage" } |
| 183 | + "values" { "PrtgShell.PrtgValue" } |
| 184 | + "channels" { "PrtgShell.PrtgChannel" } |
| 185 | + "history" { "PrtgShell.PrtgHistory" } |
| 186 | + } |
| 187 | + |
| 188 | + if ($Data.$Content.item.childnodes.count) { # this will return zero if there's an empty set |
| 189 | + foreach ($item in $Data.$Content.item) { |
| 190 | + $ThisObject = New-Object $PrtgObjectType |
| 191 | + #$ThisRow = "" | Select-Object $SelectedColumns |
| 192 | + foreach ($Prop in $SelectedColumns) { |
| 193 | + if ($Content -eq "channels" -and $Prop -eq "lastvalue_raw") { |
| 194 | + # fix a bizarre formatting bug |
| 195 | + #$ThisObject.$Prop = HelperFormatHandler $item.$Prop |
| 196 | + $ThisObject.$Prop = $item.$Prop |
| 197 | + } elseif ($HTMLColumns -contains $Prop) { |
| 198 | + # strip HTML, leave bare text |
| 199 | + $ThisObject.$Prop = $item.$Prop -replace "<[^>]*?>|<[^>]*>", "" |
| 200 | + } else { |
| 201 | + $ThisObject.$Prop = $item.$Prop |
| 202 | + } |
| 203 | + } |
| 204 | + $ReturnData += $ThisObject |
| 205 | + } |
| 206 | + } else { |
| 207 | + $ErrorString = "Object" + $ObjectId + " contains no objects of type" + $Content |
| 208 | + if ($FilterProperty.Count) { |
| 209 | + $ErrorString += " matching specified filter parameters" |
| 210 | + } |
| 211 | + |
| 212 | + Write-Host $ErrorString |
| 213 | + } |
| 214 | + |
| 215 | + <# |
| 216 | + # this section needs to be revisited |
| 217 | + # if the filter ends up returning an empty set, we need to say so, or return said empty said |
| 218 | + # and we also need to make the "get-prtgobjecttype" cmdlet that this depends on |
| 219 | + |
| 220 | + if ($ReturnData.name -eq "Item" -or (!($ReturnData.ToString()))) { |
| 221 | + $DeterminedObjectType = Get-PrtgObjectType $ObjectId |
| 222 | +
|
| 223 | + $ValidQueriesTable = @{ |
| 224 | + group=@("devices","groups","sensors","todos","messages","values","history") |
| 225 | + probenode=@("devices","groups","sensors","todos","messages","values","history") |
| 226 | + device=@("sensors","todos","messages","values","history") |
| 227 | + sensor=@("messages","values","channels","history") |
| 228 | + report=@("Currently unsupported") |
| 229 | + map=@("Currently unsupported") |
| 230 | + storedreport=@("Currently unsupported") |
| 231 | + } |
| 232 | +
|
| 233 | + Write-Host "No $Content; Object $ObjectId is type $DeterminedObjectType" |
| 234 | + Write-Host (" Valid query types: " + ($ValidQueriesTable.$DeterminedObjectType -join ", ")) |
| 235 | + } else { |
| 236 | + return $ReturnData |
| 237 | + } |
| 238 | + |
| 239 | + #> |
| 240 | + |
| 241 | + return $ReturnData |
| 242 | + } |
| 243 | +} |
0 commit comments