Search Log Files Using PowerShell
You’re troubleshooting an application and need to look through the logs to find out what is happening. We’ve all been there, right? Log files are an important resource during troubleshooting. So much so, that if you open a ticket with the software vendor, their support will likely open up their communication by requesting the log files.
By reading and searching log files, you can find clues and insights that can help you diagnose and fix the problem. However, reading and searching log files can also be a tedious and time-consuming task, especially if you have to deal with large, complex, or multiple log files. That’s why using PowerShell to read and search log files can be a helpful time saver. PowerShell is a powerful scripting language that can automate and simplify many tasks related to system administration, including working with log files.
In this blog post, we’ll talk about how to use PowerShell to read and search log files during troubleshooting.
Want to follow along? You can get the sample log file by using these commands:
|
|
|
|
|
|
Reading an Entire Log File
If you’re following along, be sure your terminal’s Present Working Directory (pwd) is
C:\temp
and that you have theC:\temp\sample.log
file in that directory.
The most basic task is getting the content of the log file. We can accomplish this simply:
|
|
The above command will read the entire log file and display its contents in your terminal window; the output would look something like this (I’ve truncated the output to just the first item for the sake of reducing the amount of scrolling in this blog post, as the output is hundreds of lines long):
|
|
Being able to read the file is one thing, but it’s not the most helpful thing in the world.
Searching a Single Log File
What if we have an error and want to find out more about it? We can search the log file for the error using the Select-String
command:
|
|
This first gets all the content of the log file, then selects any lines that have our search pattern in them. The -SimpleMatch
switch allows for a basic search instead of the default search which uses regular expressions (regex).
Note: If you want to shorten up this command, you can replace
Select-String
with its aliassls
.
Now the output looks like this:
|
|
Now we’d know that some unset reports failed to upload, have their timestamps, and the error code which likely denotes the reason that they failed to upload (though we’d need to consult the application vendor’s documentation to verify).
This same example could be used to look for any instances of a specific error message in the log:
|
|
Note: The
-Pattern
parameter can accept multiple items in an array as an input! You could search two errors by usingPattern '0x800004005','0x800005007'
if you needed to.
What if we wanted to look at the first error we returned for the Failure message and get some context? Select-String
has a parameter -Context
that lets us return X number of lines before the matched pattern, and Y number of lines after the matched pattern. Let’s get that first instance of the error and also get the 3 lines before the error to see if something else relevant to the issue happened:
|
|
In the above example, Get-Content sample.log
is reading the entire log file, and then we pipe that output into Select-String -Pattern "Failed to upload all unsent reports." -SimpleMatch -Context 3,0
where we search for the error using -Pattern
and -SimpleMatch
, and also ask for the 3 lines before the error with -Context 3,0
.
The output looks like this:
|
|
If this were a real-world situation, those preceding lines could tell us why the error occurred.
Searching Multiple Log Files
Alright, that’s not so bad for a single log file. But what if the application has multiple log files? No problem! This gets a little more involved, but still easily doable. I’ll provide an example here, but there’s no follow-along since we only downloaded one log file for the sample.
By inserting a *
into the path of the log file(s), we can account for any files in the folder which have the file extension .log
.
|
|
The output looks like this:
|
|
If you wanted, you could even output this into the PowerShell GridView, which will open the results in a GUI window that allows you to sort by columns and filter further. Use the same command but replace
Format-Table -AutoSize
withOut-GridView
in that case.
With the above command, you now have results of your search from two log files in a single view, rather than opening both files and manually searching files.
Filtering by Date
When troubleshooting, it’s often helpful to narrow the scope of time involved. When you’re dealing with systems that use verbose logging, there can be a lot of content to search through. The method of filtering by date can vary from situation to situation based on how the application logs its actions, but for this specific example, we’ll essentially read the lines of the log and search for a partial datetime:
|
|
The above command will return any entries in any log files in C:\temp
which contain occurred on September 28th, 2016 between 4:00 AM and 4:59 AM. This is an example of significantly narrowing the scope of the logs you are reviewing, and the output looks like this:
|
|
Again, you could instead pipe the result into
Out-GridView
instead ofFormat-Table
if you so choose.
Find Recently Written Log Files
Many applications will truncate their log files to prevent a single log file from growing too large. You’ve probably seen a log file directory before that has multiple files in it like:
- events01.log
- events02.log
- events03.log
- etc…
If you want to be sure you only look at log files that have been recently written to, then this is how to find those:
|
|
This will return you a list of files with the .log
file extension in the C:\temp
directory whose LastWriteTime
property is one hour ago or newer. You can modify as needed to narrow down the time period you want.
Watch a Log File
Alright so you know the log file that you need to look at, but of course nobody can tell you the last time the issue occurred. Like we often do in IT work, we can have the person experiencing the issue reproduce the issue. We’ll want to be watching the log file while this happens to be sure we see the issue get logged. There’s an easy way to do this with PowerShell!
|
|
Here we are getting the last 5 lines of the log file, and waiting for new entries to appear. As they appear, they’ll be displayed in the terminal.
Note: If you want to shorten this command a bit, you can replace
Get-Content
with its alias:type
.
Conclusion
In this post we looked at how to use PowerShell to read and search log files for troubleshooting purposes. We have seen how to read an entire log file using the Get-Content
cmdlet, how to search a single log file using the Select-String
cmdlet, and how to search multiple log files at once using the Get-ChildItem
and Where-Object
cmdlets. We have also learned how to filter log files by date using the LastWriteTime
property.
By using PowerShell to work with log files, we can save time and effort, as well as perform more advanced and flexible searches. PowerShell is a powerful scripting language that can help us with many tasks related to system administration, including log file analysis and troubleshooting.
I hope you enjoyed this blog post and found some bit of helpful information in it. The next time you need to review a log file (especially if its on a Windows Core server), do consider using these techniques to find the information you’re looking for!