Use Select-String Cmdlet in PowerShell to View Contents of Log File


Summary: Use the Windows PowerShell cmdlet, Select-String, to view the contents of a log file.

Hey, Scripting Guy! Question Hey, Scripting Guy! I have a log file that I created by dumping process information from Get-Process. It is quite long, and I am trying to use Select-String to find the number of instances of a certain process. The problem is that when I find the instance, I do not know what the columns mean. I am wondering what I can do to get the column headers in addition to the process information to show up in my output. I know I can do this with a script, but I don’t want to write a script to accomplish this task. Can you help?

—BU

Hey, Scripting Guy! Answer Hello BU,

Microsoft Scripting Guy, Ed Wilson, is here. Well, I am sore again. It seems that when I go see my trainer, I come away sore. After the weekend, I start to feel good, and then BOOM!—I go back and I am sore all over again. And I do mean sore all over.

Anyway, the Scripting Wife bought me a nice one-pound bag of English Breakfast tea, so I am sitting here, trying to cool down, sipping a cup of English Breakfast tea with a cinnamon stick in it, and thinking about rejoining the world of the living. I am checking my email sent to scripter@microsoft.com, and BU, I ran across your email. The answer is, "Sure, it can be done. In fact, it is not too hard at all."

First the log file

You say that you have a log file you created by using Get-Process. I am assuming the command you used was something like the following:

Get-Process >> C:\FSO|MyProcesses.txt

The resulting log file is shwon here:

Image of command output

If I use the Select-String cmdlet to read the log file and to look for instances related to the iexplore process, I might use a command such as this:

Get-Content C:\fso\myprocesses.txt | Select-String 'iexplore'

The command and the output from the command are shown here:

Image of command output

The problem with this command, is that I cannot tell what the columns of numbers mean. Also, it is more work than is required. I do not need to use Get-Content first. I can simply use Select-String to find the information I need.

One way to get column headings

I can use two commands to get the column headings. The first is to use the Get-Content cmdlet and return only the first two lines from the file. This will give me the column headings. The command is shown here:

Get-Content C:\fso\myprocesses.txt -TotalCount 2

I can then use the previous command to display the column details, as shown here:

Image of command output

It is not ideal, but it does give me an idea of what is going on, and I can line up the column headings well enough to decipher the output. So, this will work.

Simplify things

I said that I do not need to resort to Get-Content at all. In fact, I can use Select-String to parse the file and find the information all at the same time. To do this, all I need to do is to specify the path to the file, for example:

Select-String -Path C:\fso\myprocesses.txt -Pattern iexplore

The command and the output are shown here (note that this command includes the file and the line number where the match occurred).

Image of command output

I still need to obtain the headers from the file to be able to make sense of the output. I could go back to using Get-Content, but the output would not be quite as readable. A better way is to use the regular expression OR pattern. I know that one of the columns includes the word Handles. So I can specify my pattern to be iexplore OR Handles. Here is the command I use:

Select-String -Path C:\fso\myprocesses.txt -Pattern "(iexplore|Handles)"

The command and the output are shown here:

Image of command output

The output is a little better, and the columns line up pretty well. I may decide to leave it at this. But if I do not need the Line number field or the Path field, I can clean up the output. To do this, I need to know the properties of the MatchInfo object. I get these from Get-Member as shown here:

Select-String -Path C:\fso\myprocesses.txt -Pattern "(iexplore|Handles)" | get-member -MemberType Properties

 

   TypeName: Microsoft.PowerShell.Commands.MatchInfo

 

Name       MemberType Definition

----       ---------- ----------

Context    Property   Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}

Filename   Property   string Filename {get;}

IgnoreCase Property   bool IgnoreCase {get;set;}

Line       Property   string Line {get;set;}

LineNumber Property   int LineNumber {get;set;}

Matches    Property   System.Text.RegularExpressions.Match[] Matches {get;set;}

Path       Property   string Path {get;set;}

Pattern    Property   string Pattern {get;set;}

Luckily, the property names make sense. Obviously, Pattern is the pattern I specified to find the matches. The LineNumber and Path properties are the file and the line number in the file. So I want the Line property. Here is my revised command:

Select-String -Path C:\fso\myprocesses.txt -Pattern "(iexplore|Handles)" | select line

Here is the command and the revised output. It is quite readable now.

Image of command output

BU, that is all there is to using Select-String. Join me tomorrow when I will talk about more way cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Comments (3)

  1. Useful tips. Thanks Ed.

  2. Useful tip. Thanks Ed.

  3. Brad Jeong says:

    What is ‘regular expression AND pattern’?
    this command works well for AND pattern:
    Select-String -Path C:fsomyprocesses.txt -Pattern "iexplore" | Select-String "Handles" | get-member -MemberType Properties.

    But, You may know that ‘Matches’ doesn’t have all patterns searched (that maybe have the last one or the first one).
    How could I make ‘Matches’ get all matched ‘Patterns’?

Skip to main content