Using Powershell to parse logs

So we are in a situation where we need some sort of “backup” methodology to using Splunk to audit logs of each machine in the case Splunk was to go down. It was mentioned that perhaps PS would be able to do this.

So I am reaching out to the community here to get some advice, although I have little experience with PS is this possible and if so would someone be willing to get me on the correct path of thinking to create a script to do this?

This is a broad question, but I would have to say yes, PS can audit logs similar to Splunk. I use both for my work. We use PS for systems where Splunk is not viable. The audit script I use is huge, not able to post here but it can be done. The one I wrote also backs up logs and creates the report in HTML.

To be brief, look into Get-WinEvent and Get-WmiObject (Get-CimInstance for PS6/7). I highly recommend using XML filters for your Get-WinEvent queries for performance reasons.

google is your friend here :slight_smile:

A great resource for security related event ID’s is here:


So when you say huge like 200+ lines of code huge?


Yes … and then some. But it depends on what you are hoping for. If you want to provide a “backup” for Splunk and achieve the same functionality/output as Splunk, I can’t see where you can do that under 200 lines. At least not with extensive error checking and logging.

Splunk does an amazing job, but it is what I call “noisy”. What I was able to do with PS versus Splunk is create a VERY easy to read/understand/navigate HTML report that managers can understand and use. Again, Splunk is our primary tool and the first choice, but not all systems in our environment can use Splunk, hence creating an Audit with PS.

I should also point out that in our environment, Splunk is rock solid and so far, has never required the need for a backup.


Oh boy… For now I want to keep it simple. Perhaps just start with looking for failed Logins and account Permissions changes on lets say a network on 10 hosts. Once I start getting the idea on how I can get this to work I will expand it.

Here is what I use for Failed logins. Looks daunting (maybe someone can suggest a way to shorten) but reduces the noise. $System must be defined as the remote host.

$XPath = “(Event[System[EventID=4625 or EventID=4771 or EventID=4776 or EventID=5461]]) and (Event[EventData[Data[@Name=‘LogonType’] = ‘2’]] or Event[EventData[Data[@Name=‘LogonType’] = ‘3’]] or Event[EventData[Data[@Name=‘LogonType’] = ‘7’]] or Event[EventData[Data[@Name=‘LogonType’] = ‘10’]] or Event[EventData[Data[@Name=‘LogonType’] = ‘11’]]) and (Event[EventData[Data[@Name=‘SubjectUserSid’] != ‘S-1-0-0’]]) and (Event[EventData[Data[@Name=‘TargetUserName’] != ‘’]])”

$AuditData = Get-WinEvent -LogName ‘Security’ -ComputerName $System -FilterXPath $XPath

You mention “permission changes” … permissions on what?



Do you think this site a good place to get an understanding of how to do this?



Thanks much for getting me going in the right direction!

Permission Changes. Probably from looking at the list account creation. That is a very good list to look at.


Thank you for that code. Now I assume the parameters -Logname, -ComputerName and - FilterXPath are the tailored out parameters. Logname being the name of the log file. Computername being the name of the host you are searching and FilterxPath being the path where the log file is located?




-Logname - Yes, defined in this case as the Security log which is located here: C:\windows\Systems32\winevt\logs\security.evtx

-ComputerName - you can leave this off if you are executing on your local system. If you want to query remote systems, give it a valid hostname. In my example I use the variable $System as I am in a loop for multiple systems. You can either set that variable or a variable of your choice, or use a string value as in -ComputerName ‘hostname’.

-FilterXPath - No, this is NOT where the logfile is located. It defines the XML query you will use to get items from the Security log. Be careful as it is Case Sensitive, at least the logical operators are. I messed with these queries far too long before I figured that out.