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. 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