Posh Security

View Original

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:

    See this content in the original post

    and

    See this content in the original post

    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?

    See this content in the original post

    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.

    See this content in the original post

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

    See this content in the original post

    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.

    See this content in the original post

    Finally let's stick it all together:

    See this content in the original post

    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:

    See this content in the original post

    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.