brshUPTrends - Manage Uptrends monitors via API calls
Note: Compatible with PowerShell 5.1 and PowerShell Core 6.x
Uptrends (www.uptrends.com) provides site monitoring/alerting, plus some misc other features that are nice to have (plus some that could use some improvements <cough>maintenance period setting, mobile app</cough>).
This module is intended to set/unset Maintenance Periods (MPs) on monitors and monitor groups. MPs are set on monitors to disable monitoring and/or alerting during specific times. Very handy things to have when you're .. um .. performing maintenance. You can set MPs en masse via the web interface via a template, but it's never felt quite right ... and it's sooooo much easier just to turn off the monitors/alerts at the Monitors (where there's a handy Turn 'em All Off button!).
And besides, it's the future: we script everything nowadays.
Access
Credentials
You do need API access (well, Uptrends access and then API access) to use these functions. I recommend heading over to https://www.uptrends.com/support/kb/api/v4 and scrolling to the Authentication section (ok, here's a direct link to the Swagger UI that might work for ya: https://api.uptrends.com/v4/swagger/index.html?url=/v4/swagger/v1/swagger.json#/Register). I thought about adding a function to create the API account ... but you only need it once... why not just use their interface?
Once you have creds, you'll need them for each access to the API - so cache 'em somehow: either
using $cred = Get-Credential
or via this module's Set-uptStoredCredential
function. The
Set-uptStoredCredential
can (by default, but doesn't have to) cache the cred info in the
module's mem space so you don't need to specify it for each call. It can also utilize my
(shameless plug) SecureTokens module to use local
encrypted tokens, cuz I find that to be simple.
Syntax
Syntax
Set-uptStoredCredential [-UserName <String>] [-Password <String>] [-DoNotStoreCred]
Set-uptStoredCredential [-UserName <String>] [-PasswordSecure <SecureString>] [-DoNotStoreCred]
Set-uptStoredCredential [-SecureTokenUserName <String>] [-SecureTokenPasswordName <String>] [-DoNotStoreCred]
If you don't supply anything, the function will ask you for your creds - this keeps it off the command line, which is nice. You can also pass in SecureString that you establish beforehand if that's your pref.
If you use the -DoNotStoreCred
switch - the function will return a cred that you can save
in your own variable. Otherwise, the cred is saved in the module's memory and used automatically
with each API call.
Read from the API
The main piece of information needed to do almost anything with the API is a GUID: whether for MonitorGroups or Monitors themselves (although there's a bit of inconsistency what can be done with one versus the other). The only time you need something other than a GUID is if you're working with MPs ... then you need the ID.
Request Monitor Groups
The module's first function is the Request-uptGroup
- this pulls a list of ... monitor
groups from the API, including the ever useful GUID.
Syntax
Request-uptGroup [[-Credential] <PSCredential>] [-Filter <String[]>] [-DoNotStoreGroups]
Nothing much to see here. Provide a cred (if not cached), filter by name (regex), and weird switch....
Yeah, so originally I planned to cache the results so you wouldn't have to do multiple calls to the API ... which can be expensive if you have lots of results. And, yeah, I still do cache the results - enabling autocomplete in places where it's nice to have autocomplete. But, 1) it's not that expensive, and 2) this will really serve more as a module you will script against, I don't expect to get as much mileage out of caching the results. Whatevs. If you don't want to cache, you don't have to (and, in fact, I use that switch a lot in other parts of the code cuz I don't want to overwrite what you cache).
Anyway, running that command will return something akin to:
PS C:\>Request-uptGroup
GroupGUID Description
--------- -----------
6dc636cf-2696-4377-8052-731d3878fd05 All Monitors
0ee92a05-7979-4e18-a620-2346eeabde9a Prod Group
91528d7f-1bf0-481d-829b-7f67b3d99558 Stage Group
01cc7795-9d68-46dc-ae48-25c122d25318 Dev Stuff
Or you can filter with a string ('Group'
), string array ('Prod', 'Stage'
), or regex ('(up|ff)$'
).
Note, they're all really regex... so be careful with those strings.
Request Monitors
Ok, you've got the groups - now what? Well, one thing you can do, is pull the list of Monitors within those groups. Again, this is handy for doing stuff ... cuz you get those handy GUIDs.
Syntax
Request-uptGroupMember [-Credential <PSCredential>] [-Filter <String[]>] [-DoNotStoreMembers ]
Request-uptGroupMember [-GroupGUID] <Guid[]> [-Credential <PSCredential>] [-Filter <String[]>] [-DoNotStoreMembers]
Request-uptGroupMember [-MonitorGroupName] <String[]> [-Credential <PSCredential>] [-Filter <String[]>] [-DoNotStoreMembers]
If you have the GroupGUID, that'll get you the fastest turnaround. Just supply it (as 1 GUID or an array), and you'll get the monitors therein.
If you don't want to mess with GUIDs... well, 1) get over it, and 2) ok, you don't have to. You can supply the group .. um .. Description (not Name... nope, not Name) - and if you've cached the Groups, you can use PowerShell's autocomplete to help you. This can be a little slower, if the data is not cached, as it'll have to request the groups to find the GUID from the name, THEN it can query the members.
And there's a filter here too, so you can use a string, array of strings, or regex to filter the monitors to a specific subset (see Note about Request-uptGroup's filter above).
And, if you've cached the Groups, specifying nothing on the command line will look for members of all the groups cached (so, be careful of that All Monitors one...).
So, something like this:
PS C:\>Request-uptGroupMember -GroupGUID 0ee92a05-7979-4e18-a620-2346eeabde9a
MonitorGUID Name
----------- ----
608174e8-01ec-4565-9abe-3ad5136b3a45 This is my monitor
You could also do this:
PS C:\>Request-uptGroup -Filter 'Prod' | Request-uptGroupMember
MonitorGUID Name
----------- ----
608174e8-01ec-4565-9abe-3ad5136b3a45 This is my monitor
Request Maintenance Periods
To see what MPs are defined on monitors, you use the Request-uptMonitorMaintenancePeriod
function
for querying individual monitors, or the Request-uptGroupMaintenancePeriod
function for querying
groups (the Group one just wraps the GroupMember function and pipes it to the MonitorMP function,
basically just helping shorten things for you).
Syntax
Request-uptGroupMaintenancePeriod [-Credential <pscredential>] [-ShowSummary] [-IncludeAllMonitors]
Request-uptGroupMaintenancePeriod [-GroupGUID] <guid[]> [-Credential <pscredential>] [-ShowSummary] [-IncludeAllMonitors]
Request-uptGroupMaintenancePeriod [-Description] <string[]> [-Credential <pscredential>] [-ShowSummary] [-IncludeAllMonitors]
and
Request-uptMonitorMaintenancePeriod [-Credential <pscredential>] [-ShowSummary] [-IncludeAllMonitors]
Request-uptMonitorMaintenancePeriod [-MonitorGuid] <guid[]> [-Credential <pscredential>] [-ShowSummary] [-IncludeAllMonitors]
Request-uptMonitorMaintenancePeriod [-Name] <string[]> [-Credential <pscredential>] [-ShowSummary] [-IncludeAllMonitors]
These are very similar, really only differing in the GUID you use (GroupGUID vs MonitorGUID). On the command line, you can reference the group Description (even if not cached) or the Monitor Name (only if cached).
The ShowSummary
switch is leftover from an earlier incarnation of the function - but it's still
useful: rather than showing each MP, it instead shows a list of monitors with their MPs
grouped/summarized together. Vs the default view of each MP not grouped.
The IncludeAllMonitors
switch includes all monitors - even those without MPs. This is useful to verify
what does and does not have MPs defined.
The default output lists a stylized view of MPs. Uptrends returns MPs with different properties,
depending if the MP is onetime vs daily/weekly/monthly. The default view of MPs will group the
props together for simpler viewing - however, this view is not indicative of the actual
property names; you'll want to view the real properties via Format-List
or something similar
if you really want to know the real props....
PS C:\>Request-uptGroup -Filter 'Prod' | Request-uptGroupMaintenancePeriod
ID Disable MonitorGUID Name Mode Start End
-- ------- ----------- ---- ---- ----- ---
490638 All 608174e8-01ec-4565-9abe-3ad5136b3a45 This is my monitor OneTime 06/07/2019 16:03 06/28/2019 15:15
489633 Alerts 608174e8-01ec-4565-9abe-3ad5136b3a45 This is my monitor Daily 16:02 16:12
and
PS C:\>Request-uptMonitorMaintenancePeriod -MonitorGUID '608174e8-01ec-4565-9abe-3ad5136b3a45'
ID Disable MonitorGUID Name Mode Start End
-- ------- ----------- ---- ---- ----- ---
490638 All 608174e8-01ec-4565-9abe-3ad5136b3a45 This is my monitor OneTime 06/07/2019 16:03 06/28/2019 15:15
489733 Alerts 608174e8-01ec-4565-9abe-3ad5136b3a45 This is my monitor Weekly Mon @ 16:02 16:12
This is a wide output, mostly because I include the MonitorGUID and Name both ... they're just both sooooo handy.
Notice that this includes 2 MPs on a single Monitor. If you used the ShowSummary
switch,
it would look like this:
PS C:\>Request-uptMonitorMaintenancePeriod -MonitorGUID '608174e8-01ec-4565-9abe-3ad5136b3a45' -ShowSummary
MonitorGUID : 608174e8-01ec-4565-9abe-3ad5136b3a45
Name : This is my monitor
Period : {490638:OneTime:DisableMonitoring, 489733:Weeekly:DisableNotifications}
Of course, with the ShowSummary switch, you can pipe it to | Select-Object -ExpandProperty Period
and
get back to that first list... it's all just creative formating.
Setting or Changing Maintenance Periods
The main piece of information needed to do almost anything with the API is a GUID: whether for MonitorGroups or Monitors themselves (although there's a bit of inconsistency what can be done with one versus the other). The only time you need something other than a GUID is if you're working with MPs ... then you need the ID (and also, usually, a GUID).
Key thing to remember about MPs (explained several times above): the default
table-view of MPs simplifies the MPs properties so they can all be viewed
together in a nice, succinct table. The actual properties are vieable when you
pipe to Format-Table (a la ... | Format-Table *
)
See https://www.uptrends.com/support/kb/api/maintenance-periods for some fun light reading.
Define a New Maintenance Period
To create a Maintenance Period, you have to feed the API a properly formatted set of information. This function... creates that info for you.
The types of Maintenance Periods are:
- OneTime - only happen once and never again
- Daily - happen daily at the same time each day
- Weekly - happen once a week on the same day and same time
- Monthly - happen once a month, on a specific day of the month
Depending on the type of MP, you'll need to specify either the WeekDay or the MonthDay when the MP should occur.
The Start date/time is the only one you really need to specify as a date. You can specify and End date/time, or how many minutes or how many hours the MP should last.
Finally, MPs can DisableAlertsOnly or, by default, it will disable Alerts AND Monitoring. If you're really working on the system, you'll prolly want to use the default and disable all Monitoring. But, sometimes, you want the Monitors to continue, but you just don't care to hear about it. Your choice.
Syntax
New-uptMaintenancePeriod -OneTime -Start <DateTime> [-End <DateTime>] [-Minutes <Int32>] [-Hours <Int32>] [-DisableAlertsOnly ] [-ID <Int32>] [<CommonParameters>]
New-uptMaintenancePeriod -Daily -Start <DateTime> [-End <DateTime>] [-Minutes <Int32>] [-Hours <Int32>] [-DisableAlertsOnly ] [-ID <Int32>] [<CommonParameters>]
New-uptMaintenancePeriod -Weekly -Start <DateTime> [-End <DateTime>] [-Minutes <Int32>] [-Hours <Int32>] -WeekDay <String> [-DisableAlertsOnly ] [-ID <Int32>] [<CommonParameters>]
New-uptMaintenancePeriod -Monthly -Start <DateTime> [-End <DateTime>] [-Minutes <Int32>] [-Hours <Int32>] -MonthDay <Int32> [-DisableAlertsOnly ] [-ID <Int32>] [<CommonParameters>]
Reasonably self-explanatory here. (And yeah, I'm sorry I couldn't figure out the right combo of ParameterSetNames to minimize some of the overlap).
Prolly the one piece that needs explaining is the -DisableAlertsOnly
switch.
By default, these MPs will disable all monitoring AND alerting. This switch
will keep monitoring active, but stop alerts.
A example of a one-time MP is
PS C:\>$b = New-uptMaintenancePeriod -OneTime -Start '5/22/2019 7pm' -Hours 2 -DisableAlertsOnly
PS C:\>$b
Name Value
---- -----
ID 0
MaintenanceType DisableNotifications
StartDateTime 2019-05-22T19:00:00.0000000
EndDateTime 2019-05-22T21:00:00.0000000
ScheduleMode OneTime
By the way, TimeZones are gonna be a pain with these things. Just saying.
Similarly, a weekly MP looks like this:
PS C:\>$b = New-uptMaintenancePeriod -Weekly -Start '5/22/2019 7pm' -Hours 2 -WeekDay Tuesday
PS C:\>$b
Name Value
---- -----
ID 0
MaintenanceType DisableMonitoring
ScheduleMode Weekly
WeekDay Tuesday
StartTime 19:00
EndTime 21:00
Add a Maintenance Period to a Monitor
A function to add a pre-defined MaintenancePeriod object to one or several monitors. This works at the monitor level and is intended for the one- or few-offs that occur.
If you need a quick way to set MPs on all Monitors in a Group, use the Add-uptGroupMaintenancePeriod function.
Syntax
Add-uptMonitorMaintenancePeriod [-MonitorGUID] <Guid[]> [[-MaintenancePeriod] <Object>] [[-Credential] <PSCredential>]
So, to add an MP to a monitor:
PS C:\>$mp = New-uptMaintenancePeriod -Onetime -Start $((get-date).AddHours(2)) -Hours 2
PS C:\>Add-uptMonitorMaintenancePeriod -MonitorGUID '76c69d9f-05a7-4e8e-a6cc-7c6dc17538f1' -MaintenancePeriod $mp
Add a Maintenance Period to a Group
Possibly better than the Add-uptMonitorMaintenancePeriod function...
The quickest way to add an MP to a lot of monitors: add it to the Group. The drawback ... Uptrends does not return anything other than a status code, so the only proof that it succeeds is a "quick" list of all MPs on the Group :(
Syntax
Add-uptGroupMaintenancePeriod [-GroupGUID] <Guid[]> [-MaintenancePeriod] <Object> [[-Credential] <PSCredential>]
So, to add an MP to every Monitor in a Group:
PS C:\>$mp = New-uptMaintenancePeriod -Onetime -Start $((get-date).AddHours(2)) -Hours 2
PS C:\>Add-uptGroupMaintenancePeriod -GroupGUID '76c69d9f-05a7-4e8e-a6cc-7c6dc17538f1' -MaintenancePeriod $mp
Edit a Maintenance Period
Doesn't matter if you set the MP on a Monitor or a Group... you can only edit an MP on a monitor: you need the MonitorGUID and the MP ID. Luckily, that's all contained in the MPs returned by the various MP Request functions.
This function adjusts the settings of an MP - so you can change the end time, or the week day... whatever you need to change, you prolly can change it. The key pieces of information are the MonitorGUID, the MP ID, and the changes.
And since MonitorGUID and MP ID are both required, it's best to pull the specific MP(s) you want via
Request-uptMonitorMaintenancePeriod | where-object { $_.ID -eq ### }
and then changing the approp property... and then using it in the command line.
Syntax
Edit-uptMaintenancePeriod [-MaintenancePeriod] <PSObject[]> [-Credential <PSCredential>] [<CommonParameters>]
So, changing the day on a Weekly MP requires: first getting the MP, then editing the day, then saving it.
PS C:\>$mp = Request-uptMonitorMaintenancePeriod -MonitorGUID '76c69d9f-05a7-4e8e-a6cc-7c6dc17538f1' | Where-Object { $_.ID -eq 503378 }
PS C:\>$mp.WeekDay = 'Tuesday'
PS C:\>Edit-uptMaintenancePeriod -MaintenancePeriod $mp
Bam! Just that ez
And you can do that for multiple MPs just by adjusting the Where-Object
statement to return more MPs. Just bear in mind that you'll have to adjust
EACH MP in the array ... so $MP[0].Weekday
, $MP[1].Weekday
etc. (or,
of course, a nice tidy foreach-object loop).
Delete a Maintenance Period
Very similar to the Edit... this function deletes an MP - gone. Bye Bye.
Here, the key pieces of information are the MonitorGUID and the MP ID
And since MonitorGUID and MP ID are both required, it's best to pull the specific MP(s) you want via the Request-uptMonitorMaintenancePeriod function, and then using it in the command line.
Syntax
Remove-uptMaintenancePeriod [-MaintenancePeriod] <PSObject[]> [-Credential <PSCredential>] [<CommonParameters>]
So, to delete an MP with a specific ID:
PS C:\>$mp = Request-uptMonitorMaintenancePeriod -MonitorGUID '76c69d9f-05a7-4e8e-a6cc-7c6dc17538f1' | Where-Object { $_.ID -eq 503378 }
PS C:\>Remove-uptMaintenancePeriod -MaintenancePeriod $mp
and to delete all MPs on that Monitor
PS C:\>$mp = Request-uptMonitorMaintenancePeriod -MonitorGUID '76c69d9f-05a7-4e8e-a6cc-7c6dc17538f1'
PS C:\>Remove-uptMaintenancePeriod -MaintenancePeriod $mp