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.
To find a string inside of a string with PowerShell, you can use the Substring() method. This method is found on every string object in PowerShell. The first argument to pass to the Substring() method is the position of the leftmost character. In this case, the leftmost character is T .
The “$_” is said to be the pipeline variable in PowerShell. The “$_” variable is an alias to PowerShell's automatic variable named “$PSItem“. It has multiple use cases such as filtering an item or referring to any specific object.
Select-String uses the Pattern parameter to specify HELLO. The CaseSensitive parameter specifies that the case must match only the upper-case pattern. SimpleMatch is an optional parameter and specifies that the string in the pattern isn't interpreted as a regular expression.
You can use it like Grep in UNIX and Findstr in Windows with Select-String in PowerShell. Select-String is based on lines of text. By default, Select-String finds the first match in each line and, for each match, it displays the file name, line number, and all text in the line containing the match.
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.
Select-String
returns MatchInfo
objects, not just the string data displayed. That data is taken from the Line
and Context
properties of the MatchInfo
object.
Try this:
bcdedit /enum | select-string "identifier.*current" -context 0,3 | format-list
And you'll see the various properties of the MatchInfo
object.
Note that the Context
property is displayed as Microsoft.PowerShell.Commands.MatchInfoContext
You'll need to drill down into this object further to get more information:
(bcdedit /enum | select-string "identifier.*current" -context 0,3).context | format-list
There you'll see that the context
property is another object with PreContext
and PostContext
properties, where the actual Pre and PostContext lines are.
So:
(bcdedit /enum | select-string "identifier.*current" -context 0,3).Context.PostContext | Select-String 'description'
Will get the description line from the postcontext matches.
Or you can do this:
[string](bcdedit /enum | select-string "identifier.*current" -context 0,3) -split "`n" -match 'description'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With