Trying to read only a fraction of the message in a series of events. Having trouble getting good output.
My Script (assume that all variables are properly setup, I'm able to gather the correct events, etc.):
$Events = Get-WinEvent -ComputerName $Server -FilterHashtable @{LogName=$LogName;
StartTime=$StartTime} -ErrorAction SilentlyContinue
| Where-Object {$_.message -match "$Keyword1|$Keyword2"}
foreach ($Event in $Events)
{
$InStuff = $Event.Message
$InStuff = $InStuff.Split("`n").Trim("`r")
$Null = $InStuff.Where({$_ -match '<Message>(?<EventMessage>.+)</Message>'})
$EventMessage = $Matches.EventMessage
$Null = $InStuff.Where({$_ -match '\[Key\] : (?<EventKey>.+)'})
$EventKey = $Matches.EventKey
$EventXML = [xml]$Event.ToXml()
$EventArray = New-Object -TypeName PSObject -Property @{
EventID = $Event.Id
EventTime = $Event.TimeCreated
EventProvider = $Event.ProviderName
EventLog = $Event.LogName
EventMessage = $EventMessage
EventKey = $EventKey
}
$EventArray | Select EventTime,EventLog,EventProvider,EventID,EventMessage,EventKey
}
Result (notice, EventMessage is empty):
EventTime : 7/30/2018 3:43:54 PM
EventLog : CCS
EventProvider : CCS Logging
EventID : 100
EventMessage :
EventKey : R-MD
However...if in my script I do this (manually paste an excerpt from a log):
$InStuff = @'
Timestamp: 7/30/2018 3:43:54 PM
Message: <Description>An exception has been detected.</Description>
<DateTime>2018-07-30 11:43:54Z</DateTime>
<Message>Exception Message:No category found for key = R-MD.</Message>
[Key] : R-MD
[LocaleId] : 1033
'@
Instead of this:
$InStuff = $Event.Message
Then I get a good result:
EventTime : 7/30/2018 3:43:54 PM
EventLog : CCS
EventProvider : CCS Logging
EventID : 100
EventMessage : Exception Message:No category found for key = R-MD.
EventKey : R-MD
If it helps, $Event.Message.GetType()
& $Event.Message[0].GetType()
yields the following:
True | True | String | System.Object
True | True | Char | System.ValueType
Basically, to recap, I need:
<Message>
and </Message>
tags of $Event.Message
[Key] :
Both of these things seem to reside inside of $Event.Message
.
My actual logs have multiple different things that could be in there so particularly targeting X characters for splitting, etc. isn't an option and what I've managed so far is the help of some posters on Reddit or the internet in general. I've tried various RegEx combo's I've found to no avail and I can't seem to wrap my head around how to use RegEx.
I've spent the better part of 12hrs just trying to get his output correct...I'm at a loss.
Please help!
=====================
EDIT: Below is the exported event, per request:
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>System.Diagnostics.Eventing.Reader.EventLogRecord</T>
<T>System.Diagnostics.Eventing.Reader.EventRecord</T>
<T>System.Object</T>
</TN>
<ToString>System.Diagnostics.Eventing.Reader.EventLogRecord</ToString>
<Props>
<I32 N="Id">100</I32>
<Nil N="Version" />
<I32 N="Qualifiers">0</I32>
<By N="Level">4</By>
<I32 N="Task">0</I32>
<Nil N="Opcode" />
<I64 N="Keywords">36028797018963968</I64>
<I64 N="RecordId">4824</I64>
<S N="ProviderName">CCS LOGGING</S>
<Nil N="ProviderId" />
<S N="LogName">CCS</S>
<Nil N="ProcessId" />
<Nil N="ThreadId" />
<S N="MachineName">Test</S>
<Nil N="UserId" />
<DT N="TimeCreated">2018-08-03T11:57:53-04:00</DT>
<Nil N="ActivityId" />
<Nil N="RelatedActivityId" />
<S N="ContainerLog">ccs</S>
<Obj N="MatchedQueryIds" RefId="1">
<TN RefId="1">
<T>System.UInt32[]</T>
<T>System.Array</T>
<T>System.Object</T>
</TN>
<LST />
</Obj>
<Obj N="Bookmark" RefId="2">
<TN RefId="2">
<T>System.Diagnostics.Eventing.Reader.EventBookmark</T>
<T>System.Object</T>
</TN>
<ToString>System.Diagnostics.Eventing.Reader.EventBookmark</ToString>
</Obj>
<S N="LevelDisplayName">Information</S>
<S N="OpcodeDisplayName">Info</S>
<Nil N="TaskDisplayName" />
<Obj N="KeywordsDisplayNames" RefId="3">
<TN RefId="3">
<T>System.Collections.ObjectModel.ReadOnlyCollection`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]</T>
<T>System.Object</T>
</TN>
<LST>
<S>Classic</S>
</LST>
</Obj>
<Obj N="Properties" RefId="4">
<TN RefId="4">
<T>System.Collections.Generic.List`1[[System.Diagnostics.Eventing.Reader.EventProperty, System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]</T>
<T>System.Object</T>
</TN>
<LST>
<Obj RefId="5">
<TN RefId="5">
<T>System.Diagnostics.Eventing.Reader.EventProperty</T>
<T>System.Object</T>
</TN>
<ToString>System.Diagnostics.Eventing.Reader.EventProperty</ToString>
<Props>
<S N="Value">Timestamp: 8/3/2018 3:57:53 PM_x000D__x000A_Message: <Exception handlingInstanceId="7bdbceed-ef96-4f0d-985a-88f7c8641661">_x000D__x000A_ <DateTime>2018-08-03 11:57:53Z</DateTime>_x000D__x000A_ <Message>Exception Message Key:RDKEYNF_x000D__x000A_Exception Message:No record found in ApplicationLabels category for key = R-MD, Locale = 1033, Filter = Active, and EffectiveDate = 8/3/2018.</Message>_x000D__x000A_ <Source>AFS</Source>_x000D__x000A_ <HelpLink />_x000D__x000A_ <Property name="Parameters">_x000D__x000A_[CategoryName] : ApplicationLabels_x000D__x000A_[Key] : R-MD_x000D__x000A_[LocaleId] : 1033_x000D__x000A_</S>
</Props>
</Obj>
</LST>
</Obj>
</Props>
<MS>
<S N="Message">Timestamp: 8/3/2018 3:57:53 PM_x000D__x000A_Message: <Exception handlingInstanceId="7bdbceed-ef96-4f0d-985a-88f7c8641661">_x000D__x000A_ <DateTime>2018-08-03 11:57:53Z</DateTime>_x000D__x000A_ <Message>Exception Message Key:RDKEYNF_x000D__x000A_Exception Message:No record found in ApplicationLabels category for key = R-MD, Locale = 1033, Filter = Active, and EffectiveDate = 8/3/2018.</Message>_x000D__x000A_ <Source>AFS</Source>_x000D__x000A_ <HelpLink />_x000D__x000A_ <Property name="Parameters">_x000D__x000A_[CategoryName] : ApplicationLabels_x000D__x000A_[Key] : R-MD_x000D__x000A_[LocaleId] : 1033_x000D__x000A_</S>
</MS>
</Obj>
</Objs>
Running this one liner got me the value between <Message></Message>
from $InStuff:
[regex]::matches($InStuff,'<Message>(.*?)<\/Message>').value.Replace("<Message>","")
.Replace("</Message>","").Trim()
Output:
Exception Message:No category found for key = R-MD.
For the [Key] value:
[regex]::matches($InStuff,'(?<=\[Key\]).*').value.Replace(":","").Trim()
Output:
R-MD
A good website to learn about regex is: https://regex101.com/, they explain what each part of your regex is doing on the test string.