How can I return whole line by matching pattern from variable?
Have below code to write particular events to variable:
$date = (get-date).AddDays(-1)
$log = Get-WinEvent -FilterHashtable @{ LogName='Security'; StartTime=$Date; Id='6416'}
If accessing particular event message:
$log[0].Message
Return text is:
Device ID: SWD\\MMDEVAPI\\{0.0.1.00000000}
Device Name: Headset
Class ID: {.......}
Class Name: AudioEndpoint
How can I get whole line by matching pattern "Class Name:"?
Need to get below output
Class Name: AudioEndpoint
Tried below command but it returns the same whole content:
select-string -Pattern "Class Name:" -InputObject $log[0].Message
In PowerShell (Core) 7 (the modern, cross-platform, install-on-demand edition):
$log[0].Message -split '\r?\n' |
Select-String -Raw -Pattern "Class Name:"
In Windows PowerShell (the legacy, ships-with-Windows, Windows-only edition of PowerShell whose latest and last version is 5.1):
$log[0].Message -split '\r?\n' |
Select-String -Pattern "Class Name:" |
ForEach-Object Line
Whenever you pass a multiline string - such as $log[0].Message
in your case - to Select-String
, it is considered a single input object (string), and if the pattern passed to -Pattern
matches anywhere in that multiline string, the string as a whole is considered a match - which is what you saw.
Select-String
's -LiteralPath
or path wildcard patterns to -Path
.Get-Item
or Get-ChildItem
calls determining the files of interest to Select-String
.Therefore, the solution to your problem is to split the multiline string into individual lines - which is what the -split
operation above does - and pass them one by one to Select-String
via the pipeline,[1] so as to ensure line-by-line matching.
\r?\n
matches both Windows-format and Unix-format newlines; see this answer for details.By default - and invariably in Windows PowerShell (except if you use -Quiet
) - Select-String
outputs [Microsoft.PowerShell.Commands.MatchInfo]
instances that are wrappers around matching input strings, enriched with metadata about each match.
A wrapped input string can be accessed via the .Line
property, which is what the ForEach-Object
call above does (using simplified syntax).
In PowerShell (Core) 7 you can opt to forgo creation of the wrapper objects in favor of directly outputting matching input strings, by way of the -Raw
switch.
[1] Note that while pipeline input ultimately also binds to the -InputObject
parameter, the latter's purpose is to merely facilitate pipeline input, as an implementation detail. To wit, because this parameter is defined as [psobject]
in this case, you can not meaningfully pass multiple input strings to it by argument (e.g.,
-InputObject 'line 1', 'line 2'
), as that would result in those strings getting joined with spaces to form a single input string.
For more information, see GitHub issue #4242.