I realize this has already been answered and Tomalak's answer does a great job explaining the differences between -contains
& -match
. However, and with respect to the code itself -contains
, -in
, -match
& for that matter -eq
can be made to work with relative ease.
[EventLogRecord]
objects returned by Get-WinEvent
include a property aptly named Properties
. It's a collection of [EventProperty]
objects, the values of which are the replacement strings in the event log message.
Example:
$ip = '52.109.12.19'
$id = 5157
Get-WinEvent -FilterHashtable @{ LogName = 'security'; id = $id} |
Where-Object { $_.Properties.Value -contains $ip } |
Select-Object -Property id, message
The above example unrolls the .Value
property from the Properties collection and checks if the result contains $ip
.
With a little work, you can be more assertive by figuring out which property index holds the value (in this case IP) you're interested in. I usually use something like below to do that:
(Get-WinEvent -FilterHashtable @{ logname = 'Security'; Id = 5157 } | Select-Object -First 1).Properties
This will return a list of properties. Simply count down the list from 0 to the value you're interested in, that's the index number in the Properties collection.
Note: You can also deduce this information from the <EventData>...</EventData>
section of the event's XML view in Event Viewer.
For the purposes of the next couple of examples, I'll take an educated guess that the IP you're looking for is at [3]
. This is based on Internet research for Windows Platform Filtering event 5157 and is the "Source IP Address" from the event message.
You can use the -eq
operator like:
$ip = @('52.109.12.19')
$id = 5157
Get-WinEvent -FilterHashtable @{ LogName = 'security'; id = $id} |
Where-Object { $_.Properties.[3].Value -eq $ip } |
Select-Object -Property id, message
If you declare $ip
(or plaural $ips
) as an array it might be useful for searching multiple IPs, and you can use the -in
operator like below:
$ips = @('52.109.12.19', '52.109.12.20')
$id = 5157
Get-WinEvent -FilterHashtable @{ LogName = 'security'; id = $id} |
Where-Object { $_.Properties[3].Value -in $ips } |
Select-Object -Property id, message
Note: Added an IP to the collection just for demonstration, but this would work even when the array has only 1 element. To a certain extent, this makes the script more flexible.
I haven't performance-tested and/or compared these or other approaches, however, my bet is that the examples thus far will perform better than trying to identify the IP in the larger message text. That may be important if the logs are very large, or, for that matter, there are many logs to search. If it were me, I would probably use something like the 3rd example, using the -in
operator.
An aside and although I wouldn't suggest it for this case, you technically could use the -match
operator. The key to this is understanding how -match
works when its left operand is an array. It will return the elements that match or $null
, for example "one","two","three" -match "one"
, returns one
. However, "one","two","three" -match "four"
, returns nothing. This is usually enough for it to work in a Boolean evaluation.
$ip = @('52.109.12.19')
$id = 5157
Get-WinEvent -FilterHashtable @{ LogName = 'security'; id = $id} |
Where-Object { $_.Properties.Value -match $ip } |
Select-Object -Property id, message
Notice however the right operand is a scalar value. It won't work if it's a collection. Again, I don't recommend this approach but included it for demonstration purposes.
Note: -eq
, -like
will return similarly when the left operand is a collection. -ne
will return those values not equal to the right operand. To learn more about the behavior of comparison operators take a look at about_Comparison_Operators