August 1st, 2011

Use the PowerShell Grep Command to Parse the Command Line

Doctor Scripto
Scripter

Summary: In this article, Microsoft Scripting Guy Ed Wilson teaches how to use the Windows PowerShell version of grep to parse the command line.

 

Hey, Scripting Guy! QuestionHey, Scripting Guy! I have enjoyed reading Sean’s legacy scripting articles, but I am a bit confused. It seems that all these commands return data, and I would love to be able to easily parse the information that the commands return. Can you give me an example of that?

—KG

 

Hey, Scripting Guy! AnswerHello KG,

Microsoft Scripting Guy Ed Wilson here. The TechReady conference in Seattle last week was great. We even had a few sun sightings during the week. The day I flew into Seattle was absolutely beautiful, and I was able to see all the mountains stretching up into the sky. The Space Needle was clearly visible. All in all, it was a Seattle Chamber of Commerce type of day.

KG, if you are going to work with legacy commands very often, you will need to become competent at using the Select-String cmdlet. Often, I will look around for an object that will return the same types of information that I might obtain via a legacy command—to avoid the issue of extensive text parsing.

For example, the ipconfig command will return an IP address and a log of other information. But I can use WMI to obtain the IP address as well. The following command returns the IP address on my local computer. Note that gwmi is an alias for the Get-WMIObject cmdlet. I only have one network interface card that is ipenabled, so I can return the ipaddress property directly. Unfortunately, the ipaddress property returns an array with both the IPv4 and IPv6 address in it. I index into the array to return only the IPv4 address:

(gwmi win32_NetworkAdapterConfiguration -Filter ‘ipenabled = “true”‘).ipaddress[0]

As you can tell, typing the preceding command is a bit cumbersome when compared to typing ipconfig. However, if I put the above command in a function and I place it in my profile or some module, I can call it as easily as typing Get-IPAddress. Or if I create an alias, I can type gia. The Get-IPAddress function and code to create an alias are shown here:

Get-IPAddressFunction.ps1

Function Get-IPAddress

{

 (Get-WmiObject -class win32_NetworkAdapterConfiguration `

   -Filter ‘ipenabled = “true”‘).ipaddress[0]

} #end function Get-Ipaddress

 

New-Alias -Name GIA -Value Get-IPAddress -Description “HSG alias”

 

When I run the function to load it into memory, I can then access it by alias if I wish. This is shown in the following figure.

Image of accessing function by alias

Figuring out how to use the Select-String cmdlet can be a bit confusing. The online help for the cmdlet is rather extensive, and the examples do not seem to cover simple cases. For example, if I want to parse the results of the ipconfig command, I might be tempted to do something like this:

PS C:\> Select-String -Pattern “IPV4” -InputObject ipconfig

PS C:\>

Unfortunately, nothing is returned. I try putting parentheses around the command to force evaluation first, and I at least see something returned to the screen. The command is shown here:

Select-String -Pattern “IPV4” -InputObject (ipconfig)

The command and output are shown in the following figure.

Image of command and associated output

As can be seen in the preceding figure, the results are completely jumbled and unreadable. It seems that it might be a lost cause, but if you stick with it and use the pipeline, the output is much more readable. The command that uses the pipeline and the associated output are shown here (in addition, it does not matter if I use the simplematch switched parameter or not):

PS C:\> ipconfig | Select-String -Pattern “IPv4” -SimpleMatch

   IPv4 Address. . . . . . . . . . . : 10.0.0.188

 

PS C:\> ipconfig | Select-String -Pattern “IPv4”

   IPv4 Address. . . . . . . . . . . : 10.0.0.188

 

When I try to shorten the command, however, problems arise. I try to use select as an alias for the Select-String cmdlet, and no errors appear, but I am left with a blank screen, as shown in the following figure.

Image of blank screen

The problem is that select is an alias for the Select-Object cmdlet, and not for the Select-String cmdlet, as shown here:

PS C:\> Get-Alias select

 

CommandType  Name               Definition

Alias                  select                Select-Object

 

Well, what are the aliases for the Select-String cmdlet? According to the output, there isn’t even one:

PS C:\> Get-Alias -Definition select-string

Get-Alias : This command cannot find a matching alias because an alias with definition ‘select-string’

 does not exist.

At line:1 char:10

+ Get-Alias <<<<  -Definition select-string

    + CategoryInfo          : ObjectNotFound: (select-string:String) [Get-Alias], ItemNotFoundException

    + FullyQualifiedErrorId : ItemNotFoundException,Microsoft.PowerShell.Commands.GetAliasCommand

Now, I may decide that I would like to create an alias for Select-String. Grep would be a good one to use. The command to accomplish this appears here (you would want to place it in your startup profile; see this collection of Hey, Scripting Guy! posts for information about profiles):

New-Alias -Name grep -Value Select-String -Description “HSG alias”

When I have an alias for Select-String, I can shorten my command quite a bit. The shortened command and associated output are shown here:

PS C:\> ipconfig | grep “IPv4”

   IPv4 Address. . . . . . . . . . . : 10.0.0.188

 

KG, this should be enough to get you started playing around with the Select-String cmdlet. Join me again tomorrow, when we will explore some more ways to use this powerful cmdlet.

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

 

 

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

0 comments

Discussion are closed.