PowerShell Kieran Jacobsen PowerShell Kieran Jacobsen

PushOver and PowerShell

Pushover is an exceptional method for integrating notifications into our PowerShell scripts and workflows. Pushover gives us a simple method to send notifications to devices. I discovered Pushover in 2012, and have been maintaining a PowerShell module ever since.

The purpose of my PowerShell module is to allow you to:

  • Send Pushover notifications,
  • Test API, user, group and device tokens; and,
  • Retrieve the details of a notification receipts.

I have kept the module and the CMDLets as simple as possible. Sending a notification is a simple as specifying an API token, a user token, and a message. Pushover supports a whole lot of other functionality, and the Send-Pushover CMDLet supports:

  • Users and Group tokens,
  • Device names,
  • Priority levels (including lowest, low, normal, high and emergency),
  • Message titles,
  • A URL,
  • Custom date and time stamps; and,
  • Custom sounds.

When submitting a notification, we get the following back:

  • A response code,
  • A request identifier; and,
  • A Boolean request response code. I recommend in your scripts validating against this success property.

Most of the time, Pushover notifications are pretty straight forward. It is important to note that emergency messages, are different. Pushover will continue to notify a user until they acknowledge it. If you are sending something that is this important, you want to know if someone actually cares about it.

When a user accepts the notification, Pushover records the who, when and where. We can make use of this information either through a callback URL in a request, or through the receipt ID returned.

Now we have a variety of tokens, API, user groups and devices. How do we know if they are all valid? You can verify these are all valid using the Test-Pushover CMDLet.

Right now I haven’t included any support for Pushover’s subscription, group or licensing features. This isn’t due to any difficulties, but more that I haven’t needed these. Of course, I am always happy to have a pull request submitted for this!

You can get module from GitHub or via the PowerShell Gallery.

Kieran Jacobsen

Read More
PowerShell Kieran Jacobsen PowerShell Kieran Jacobsen

Sending SYSLOG messages from PowerShell

I have performed a number of updates to the PowerShell SYSLOG module since this post. You can read the latest post. The module has been renamed to Posh-SYSLOG.

The GitHub location has been moved to https://github.com/poshsecurity/Posh-SYSLOG.

The module is now available on the PowerShell Gallery.


I had this need to send some SYSLOG messages from PowerShell, and there are many reasons why you might want to do this one, from notifications to logging, SYSLOG can be very handy.

I looked around online and could not find a really simple and easy to use piece of code. There were some examples out there, but they were all a little rough around the edges, and I knew I could clean them up and improve upon their design.

Before we get to the code, let us take a quick look at the SYSLOG protocol. According to Wikipedia, the SYSLOG protocol was originally developed in the 1980s by Eric Allman as part of Sendmail and is now standardized by IETF in RFC5424.

A standard SYSLOG message consists of four things:

  1. A priority - how bad is it?
  2. A Timestamp - when is this occurring
  3. A hostname  - who is sending the message
  4. A Message  - kind of obvious

    One thing to note is that the priority is not that simple. The priority in the message is actually made of two things: the severity and the facility, or what the application or subsystem generating the message is. The levels are defined in the tables below:

    Facility Number Keyword Facility Description
    0 kern kernel messages
    1 user user-level messages
    2 mail mail system
    3 daemon system daemons
    4 auth security/authorization messages
    5 syslog messages generated internally by syslogd
    6 lpr line printer subsystem
    7 news network news subsystem
    8 uucp UUCP subsystem
    9 clock daemon
    10 authpriv security/authorization messages
    11 ftp FTP daemon
    12 - NTP subsystem
    13 - log audit
    14 - log alert
    15 cron clock daemon
    16 local0 local use 0 (local0)
    17 local1 local use 1 (local1)
    18 local2 local use 2 (local2)
    19 local3 local use 3 (local3)
    20 local4 local use 4 (local4)
    21 local5 local use 5 (local5)
    22 local6 local use 6 (local6)
    23 local7 local use 7 (local7)

    and

    Code Severity Keyword Description General Description
    0 Emergency emerg (panic) System is unusable. A "panic" condition usually affecting multiple apps/servers/sites. At this level it would usually notify all tech staff on call.
    1 Alert alert Action must be taken immediately. Should be corrected immediately, therefore notify staff who can fix the problem. An example would be the loss of a primary ISP connection.
    2 Critical crit Critical conditions. Should be corrected immediately, but indicates failure in a secondary system, an example is a loss of a backup ISP connection.
    3 Error err (error) Error conditions. Non-urgent failures, these should be relayed to developers or admins; each item must be resolved within a given time.
    4 Warning warning (warn) Warning conditions. Warning messages, not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time.
    5 Notice notice Normal but significant condition. Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required.
    6 Informational info Informational messages. Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required.
    7 Debug debug Debug-level messages. Info useful to developers for debugging the application, not useful during operations.

    Here are a few examples:

    1. Emergency Message from Kernel = (0 * 8) + 0 = 0
    2. Alert from User = (1 * 8) + 1 = 9
    3. Informational from mail = (2 * 8) + 6 = 22

    When you look at a SYSLOG servers output, it probably has the severity levels and facilities nicely printed, all it is doing is reversing the process. For example, if we received a priority of 58, we would firstly divide 58 by 8, this comes out at 7.25, if we just take the whole number, we can see that this was a message from the NEWS facility, if we take 7*8 from 58, we get 2, and this, we know this was a critical severity message.

    As you can see, the whole thing is rather easy. The SYSLOG protocol is brilliant in its simplicity.

    So, back to PowerShell.

    If we were going to write a PowerShell CMDLet to send a SYSLOG message, what would it look like?

    Let us start with parameters. We are going to need to know the SYSLOG server we want to send the message to, we need a message to send, and we need to define the severity and facility that is sending the message. Optionally we might want to specify the hostname of the machine sending the message (we can get this if not specified), we might want to specify a timestamp (but we could get lazy) and finally our SYSLOG server might be running the service on a different port, so we should be able to specify the port if it is different from the default, UDP514.

    How do we go about specifying the severity and facility levels? We don’t want to force users to remember 0 through to 7 and 0 through to 23? We need to make this easier! How about some sort of data type? Thankfully, we can use ENUM types within PowerShell to define some simple data types and simplify specifying these parameters. If you don’t know about ENUMs, I suggest you do some Googling, they are very handy and quite useful.

    What would the ENUM definitions look like?

    For those of you who don't know, each item in the ENUM is assigned a number, starting with 0. We will use these numbers as part of our calculation of the priority.

    So once we have these data types defined, what's next? Let's take a look at parameters. Parameter's for a function are pretty straight forward, destination server, message, severity, facility, hostname, and date/time stamp are all we really need. In terms of mandatory parameters, only the first 4 are, we can determine the other two for the user.

    What's next? Well, what about determining the priority to be sent based upon severity and facility?

    The only other tricky part is the date/timestamp, but once again, that isn't too tricky. We just use Get-Date and a custom specified format.

    Finally let's stick it all together:

    Well we now have a message to send to the syslog server? Well all that is left to do is encode and send the message using a UDP client object.

    The finished CMDLet looks like this:

    You can also see the finished product on my GitHub. I built a module based upon my prefered structure here.

    As you can see, this is all pretty simple stuff. Now we get to go off and user it in your scripts! Using this CMDLet is pretty simple, there is an example included in the comments. Simply specify the various details, and then check your SYSLOG server to see the results.

    Stay tuned into my blog for a non-PowerShell post about some issues I recently faced with Windows Integrated Authentication.

    Read More