lordmilko / PrtgAPI

C#/PowerShell interface for PRTG Network Monitor
MIT License
301 stars 37 forks source link

Exporting PausedbyUser since x date #49

Closed SamuelmAsh closed 5 years ago

SamuelmAsh commented 5 years ago

Hi Lord Milko, happy monday!

I am hoping you can help a smidge with exporting the a list of sensors which have been paused for longer than a certain amount of time (in this case 6 months). I am having issues working with the system string from get-date.adddays -182 and cant quite figure out how to assemble a filter. As such i was planning to use the sub-selection of day of year but this feels like im going down a bad path :)

Heres my horrific code

#Get paused for more than 6 months

goprtg 2
$6months = (get-date).AddDays(-182)

$allpauses =Get-Sensor -status Paused
$pauseusers =get-sensor -status PausedByUser

$filter1 = -status equals Paused
$fliter2 = get-sensor -status PausedByUser | where $allpauses.lastcheck -eq $6months

flt $allpauses.lastcheck -gt (get-date).AddDays(-30) |get-sensor -Status Paused

get-sensor * | -filter ($filter1, $filter2) 

$daypaused = $allpauses.lastcheck.dayofyear | -expandpropery Name

Get-Sensor  -Status PausedByUser | foreach { $_ | select LastCheck -eq (get-date).adddays(-182)| Add-Member Device $_.Device -PassThru | Add-Member Probe $_.Probe -PassThru } | Select LastCheck, Device, Probe, URL

Non of which quite works. I have the CSV exported so i can easily filter this in excel however i was hoping to be able to automatically export "whats been paused more than 6 months" reports

Kindest Samuel

lordmilko commented 5 years ago

Hi @SamuelmAsh,

You're very close, however if you look at some of these lines more carefully you'll see they don't make any sense

$fliter2 = get-sensor -status PausedByUser | where $allpauses.lastcheck -eq $6months

There's a few things going on here

  1. get-sensor -status PausedByUser - correct
  2. where $allpauses.lastcheck -eq $6months - but then things fall off the rails!
    • a. We have a list of sensors - why are we filtering against all paused sensors instead of the sensors we just retrieved?
    • $allpauses is an array, and therefore does not contain a LastCheck property. PowerShell might detect this, and automatically iterate over the array for you comparing each LastCheck to $6months. Either this will return all true or all false; whatever it does, it's just chaos!
    • By comparing for values equal to 6 months, you're practically guaranteeing you will get zero results. "six months ago" from now is a very specific date and time; as such you need to be filtering for -lt $6months
  3. $filter2 = if the code in step 2 correctly filtered for sensors that have been paused longer than 6 months, we would already have the sensors we're looking for!. So why are we creating some type of filter to re-retrieve our results?

Further down, we then have the following

flt $allpauses.lastcheck -gt (get-date).AddDays(-30) |get-sensor -Status Paused

flt is an alias for New-SearchFilter. New-SearchFilter wants to create a filter from the following items

You have failed to provide both a Property and a FilterOperator. The correct way of using New-SearchFilter would be as follows

flt LastCheck less (get-date).AddDays(-180) |get-sensor -Status Paused

Note that you also specified -30 days instead of -180 for some reason.

If I were doing this however, I would simply do it in a one liner with the following cmdlets

Get-Sensor -Status PausedByUser | where LastCheck -lt (get-date).adddays(-180)

We get all sensors that were paused by a user from PRTG, and then for each sensor, filter it based on whether its last check was older than 180 days ago. If you don't know whether -gt or -lt checks whether dates are older are younger; simply try one, and it gave you the opposite of what you want, try the other one.

As you become more proficient at programming, you will need to fully understand what the commands you type actually "mean"; this will help improve your efficiency and allow you to get to the answer sooner without relying on guess work.

The best thing you can do is familiarize yourself with what "types" are and how they are used in PowerShell and the .NET Framework. By cross referencing with resources such as MSDN and the Get-Help cmdlet you can ascertain what types of values you can specify to interface with a cmdlet.

In the case of New-SearchFilter, if you run Get-Help New-SearchFilter you will get the following output

...
SYNTAX
    New-SearchFilter [-Property] {Id | Type | Name | Tags | Active | Downtime | TotalDowntime | DownDuration | Uptime
    | TotalUptime | UpDuration | TotalMonitorTime | DataCollectedSince | Sensor | Interval | LastCheck | LastUp |
    LastDown | Device | Group | Probe | GrpDev | NotificationTypes | Access | Dependency | Status | Message | Priority
    | LastValue | UpSensors | DownSensors | DownAcknowledgedSensors | PartialDownSensors | WarningSensors |
    PausedSensors | UnusualSensors | UnknownSensors | TotalSensors | Value | Coverage | Favorite | UserName | Parent |
    DateTime | DateOnly | TimeOnly | Schedule | Period | Email | Template | LastRun | NextRun | Size | MiniGraph |
    DeviceIcon | Comments | Host | Condition | ProbeStatus | BaseType | Url | Icon | ParentId | Location | Collapsed |
    TotalGroups | TotalDevices | TicketType | ModifiedBy | Actions | Content | Position | StartDate | EndDate |
    RecordAge} [-Operator] {Equals | NotEquals | GreaterThan | LessThan | Contains} [-Value] <object> [-Illegal
    <SwitchParameter>] [-Raw <SwitchParameter>] [<CommonParameters>]
...

Every valid possible -Property and -FilterOperator is listed, while we can see the -Value can be any kind of object. This is even more clear if we instead do Get-Help New-SearchFilter -Full

...
PARAMETERS
    -Property <Property>
        Object property to filter on.

        Possible values: Id, Type, Name, Tags, Active, Downtime, TotalDowntime, DownDuration, Uptime, TotalUptime,
        UpDuration, TotalMonitorTime, DataCollectedSince, Sensor, Interval, LastCheck, LastUp, LastDown, Device,
        Group, Probe, GrpDev, NotificationTypes, Access, Dependency, Status, Message, Priority, LastValue, UpSensors,
        DownSensors, DownAcknowledgedSensors, PartialDownSensors, WarningSensors, PausedSensors, UnusualSensors,
        UnknownSensors, TotalSensors, Value, Coverage, Favorite, UserName, Parent, DateTime, DateOnly, TimeOnly,
        Schedule, Period, Email, Template, LastRun, NextRun, Size, MiniGraph, DeviceIcon, Comments, Host, Condition,
        ProbeStatus, BaseType, Url, Icon, ParentId, Location, Collapsed, TotalGroups, TotalDevices, TicketType,
        ModifiedBy, Actions, Content, Position, StartDate, EndDate, RecordAge

        Required?                    true
        Position?                    0
        Default value                Id
        Accept pipeline input?       true (ByPropertyName)
        Accept wildcard characters?  false
...

With this knowledge we now know exactly how to use this cmdlet, and can easily tell that code similar to the following

New-SearchFilter (get-process) -eq "chrome"

is wrong.

I hope this helps

Regards, lordmilko