powershell select-string not working correctly

user2443973 picture user2443973 · Feb 21, 2014 · Viewed 10.2k times · Source

I'm a beginner to powershell and having I suspect what will be a simple problem. I'm trying to do the following command, but it returns nothing as a result and I don't understand why.

I'm trying to get the description of the current section of bcdedit. If I do:

bcdedit /enum | select-string "identifier.*current" -context 0,3  

It returns the following:

> identifier {current}  
device partition=C:  
path \WINDOWS\system32\winload.exe  
description Windows 8.1  

So why doesn't the following return description Windows 8.1?

bcdedit /enum | select-string "identifier.*current" -context 0,3 | select-string "description"  

Instead it returns nothing at all.

Any information on this would be appreciated.

Answer

Ansgar Wiechers picture Ansgar Wiechers · Feb 21, 2014

You don't get the result you expect, because Select-String doesn't output strings, but MatchInfo objects. If you pipe the output of your first Select-String into the Get-Member or Format-List cmdlet, you'll get something like this:

PS C:\> bcdedit /enum | Select-String "identifier.*current" -Context 0,3 | Get-Member

   TypeName: Microsoft.PowerShell.Commands.MatchInfo

Name         MemberType Definition
----         ---------- ----------
Equals       Method     bool Equals(System.Object obj)
GetHashCode  Method     int GetHashCode()
GetType      Method     type GetType()
RelativePath Method     string RelativePath(string directory)
ToString     Method     string ToString(), string ToString(string directory)
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;}

PS C:\> bcdedit /enum | Select-String "identifier.*current" -Context 0,3 | Format-List *

IgnoreCase : True
LineNumber : 17
Line       : identifier              {current}
Filename   : InputStream
Path       : InputStream
Pattern    : identifier.*current
Context    : Microsoft.PowerShell.Commands.MatchInfoContext
Matches    : {identifier              {current}

The Line property contains the actual matching line, and the Context property contains child properties with the pre- and post-context. Since the description line you're looking for is in the PostContext child property, you need something like this for extracting that line:

bcdedit /enum | Select-String "identifier.*current" -Context 0,3 |
  Select-Object -Expand Context |
  Select-Object -Expand PostContext |
  Select-String 'description'

Bottom line: Select-String does work correctly. It just doesn't work the way you expect.