fluent-plugin-windows-eventlog icon indicating copy to clipboard operation
fluent-plugin-windows-eventlog copied to clipboard

Scriptblock from powershell in DescriptionTitle escaping json value

Open philipsabri opened this issue 5 years ago • 4 comments

We noticed our Elastic couldnt parse some logs coming from the Powershell channel, and after some investigation and getting the clean json log directly from windows_eventlog2 and file output we could clearly see its the parser from this plugin that makes them escape the json value, or not putting them inside the right key at all.

Example log:

{
    "ProviderName": "Microsoft-Windows-PowerShell",
    "ProviderGUID": "{A0C1853B-5C40-4B15-8766-3CF1C58F985A}",
    "EventID": "4104",
    "Qualifiers": "",
    "Level": "3",
    "Task": "2",
    "Opcode": "15",
    "Keywords": "0x0",
    "TimeCreated": "2020-08-05T08:54:21.118916000Z",
    "EventRecordID": "22338",
    "ActivityID": "{4FC9EF57-59A7-0001-26CA-FA52A759D601}",
    "RelatedActivityID": "",
    "ProcessID": "14424",
    "ThreadID": "13956",
    "Channel": "Microsoft-Windows-PowerShell/Operational",
    "Computer": "x",
    "UserID": "x",
    "Version": "1",
    "DescriptionTitle": "Creating Scriptblock text (1 of 1):\r\n#==========================================\r\n# Configuration\r\n#==========================================",
    "#==========================================\r\n#_function_exitreport\r\n#==========================================\r\nfunction_exitreport_($status,_$result)\r\n.write-host_($status_+_\":\"_+_$result_+": "\"`n\")",
    "if_($compare_-eq_\"critical\"_-or_$current_-eq_\"critical\")\r\n____": [
      "Return \"CRITICAL\""
    ],
    "elseif_($compare_-eq_\"warning\"_-or_$current_-eq_\"warning\")\r\n____": [
      "Return \"WARNING\""
    ],
    "elseif_($compare_-eq_\"unknown\"_-or_$current_-eq_\"unknown\")\r\n____": [
      "Return \"UNKNOWN\""
    ],
    "else\r\n": [
      "Return \"OK\""
    ],
    "time": "2020-08-05T08:54:21.118916000Z",
    "fluentd_host": "x",
    "infra_elastic_msg_id": "x"
  }

We can cleary see that "elseif_($compare_-eq_\"unknown\"_-or_$current_-eq_\"unknown\")\r\n____" is a json key when it looks like it should be in the DescriptionTitle, or might even have its own key named ScriptBlockText after watching th eventviewer xml.

Event in the eventviewer XML:

<Event
    xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
    <System>
        <Provider Name="Microsoft-Windows-PowerShell" Guid="{A0C1853B-5C40-4B15-8766-3CF1C58F985A}" />
        <EventID>4104</EventID>
        <Version>1</Version>
        <Level>3</Level>
        <Task>2</Task>
        <Opcode>15</Opcode>
        <Keywords>0x0</Keywords>
        <TimeCreated SystemTime="2020-08-05T08:54:21.118916000Z" />
        <EventRecordID>22338</EventRecordID>
        <Correlation ActivityID="{4FC9EF57-59A7-0001-26CA-FA52A759D601}" />
        <Execution ProcessID="14424" ThreadID="13956" />
        <Channel>Microsoft-Windows-PowerShell/Operational</Channel>
        <Computer>x</Computer>
        <Security UserID="S-1-5-18" />
    </System>
    <EventData>
        <Data Name="MessageNumber">1</Data>
        <Data Name="MessageTotal">1</Data>
        <Data Name="ScriptBlockText">#========================================== # Configuration #========================================== <# $ConfWindowsUpdateSettings = 'Name;Value WUServer;http://x:x WUStatusServer;http://x:x TargetGroupEnabled;1 DoNotConnectToWindowsUpdateInternetLocations;0 ' | ConvertFrom-Csv -Delimiter ";" #> $ConfWindowsUpdateSettings = 'Name;Value WUServer;http://x:x WUStatusServer;http://x:x TargetGroupEnabled;1 ' | ConvertFrom-Csv -Delimiter ";" $WarnMissingUpdates = 10 $CritMissingUpdates = 20 $WarnLastInstallDate = -30 $CritLastInstallDate = -60 $Result = "" $Status = "OK" $PerfStats = "" #========================================== # Function Exit_State #========================================== Function Exit_State ($Status) { Switch ($Status) { "OK" {Return 0} "WARNING" {Return 1} "CRITICAL" {Return 2} "UNKNOWN" {Return 3} } } #========================================== # Function ExitReport #========================================== Function ExitReport ($Status, $Result) { Write-Host ($Status + ":" + $Result + "`n") Exit [int](Exit_State $Status) } #========================================== # Function Max_State #========================================== Function Max_State ($Current, $Compare) { If ($Compare -eq "CRITICAL" -or $Current -eq "CRITICAL") { Return "CRITICAL" } ElseIf ($Compare -eq "WARNING" -or $Current -eq "WARNING") { Return "WARNING" } ElseIf ($Compare -eq "UNKNOWN" -or $Current -eq "UNKNOWN") { Return "UNKNOWN" } Else { Return "OK" } } #Status examples #$Status = Max_State $Status "OK" #$Status = Max_State $Status "WARNING" #$Status = Max_State $Status "CRITICAL" #$Status = Max_State $Status "UNKNOWN" #========================================== # Main #========================================== $Error.Clear() # Verify Windows Update Settings $TempResult = $null $WindowsUpdateSettings = Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" foreach ($Setting in $ConfWindowsUpdateSettings) { If ($WindowsUpdateSettings.($Setting.Name) -ne $Setting.Value) { $Status = Max_State $Status "WARNING" $TempResult += ("{0}," -f $Setting.Name) } } If ($TempResult) { $Result += " Settings: {0};" -f $TempResult.TrimEnd(",") } Else { $Result += " Settings: OK;" } # Verify service not disabled $wuauserv = Get-Service -Name wuauserv if ($wuauserv.StartType -eq "Disabled") { Set-Service -Name wuauserv -StartupType Manual } #<# # Get update information from Microsoft update $UpdateSession = New-Object -ComObject 'Microsoft.Update.Session' $UpdateSearcher = $UpdateSession.CreateUpdateSearcher() $SearchResult = $UpdateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0") $HistoryCount = $UpdateSearcher.GetTotalHistoryCount() $UpdateHistory = $UpdateSearcher.QueryHistory(0,$HistoryCount) $MissingUpdates = ($SearchResult.Updates | Where-Object {$_.Title -notlike '*Definition Update*' -and $_.Description -notlike '*Install this update to revise the files that are used to detect viruses, spyware, and other potentially unwanted software.*'} | Measure-Object | Select-Object -ExpandProperty Count) $LastInstallDate = (Get-Date ($UpdateHistory | Sort-Object -Descending -Property Date | Where-Object {$_.Title -notlike 'Definition Update *' -and $_.Description -notlike '*Install this update to revise the files that are used to detect viruses, spyware, and other potentially unwanted software.*'} | Select-Object -First 1 -ExpandProperty Date) -Format "yyyy-MM-dd HH:mm:ss") #$LastInstallTitle = ($UpdateHistory | Sort-Object -Descending -Property Date | Where-Object {$_.Title -notlike 'Definition Update *'} | Select-Object -First 1 -ExpandProperty Title) #> # Verify missing count $Result += " Missing: {0};" -f $MissingUpdates $PerfStats += "Missing={0};{1};{2} " -f $MissingUpdates, $WarnMissingUpdates, $CritMissingUpdates If ($MissingUpdates -ge $CritMissingUpdates) { $Status = Max_State $Status "CRITICAL" } ElseIf ($MissingUpdates -ge $WarnMissingUpdates) { $Status = Max_State $Status "WARNING" } # Verify last install date $Result += " Last: {0}" -f (Get-Date $LastInstallDate -Format "yyyy-MM-dd") If ([datetime]$LastInstallDate -lt (Get-Date).AddDays($CritLastInstallDate)) { $Status = Max_State $Status "CRITICAL" } ElseIf ([datetime]$LastInstallDate -lt (Get-Date).AddDays($WarnLastInstallDate)) { $Status = Max_State $Status "WARNING" } # Check for errors If ($Error.Count -gt 0) { $Status = Max_State $Status "UNKNOWN" $Result += "; Errors: {0}" -f $Error.Count #$Error | Out-File -FilePath C:\x.txt -Append } #========================================== # Exit and Report #========================================== $Result += "|" + $PerfStats ExitReport $Status $Result
        </Data>
        <Data Name="ScriptBlockId">acad77d5-f5ce-414b-96de-ea6f78ba3021</Data>
        <Data Name="Path">C:\Program Files\x</Data>
    </EventData>
    <RenderingInfo Culture="en-US">
        <Message>Creating Scriptblock text (1 of 1): #========================================== # Configuration #========================================== <# $ConfWindowsUpdateSettings = 'Name;Value WUServer;http://x:x WUStatusServer;http://x:x TargetGroupEnabled;1 DoNotConnectToWindowsUpdateInternetLocations;0 ' | ConvertFrom-Csv -Delimiter ";" #> $ConfWindowsUpdateSettings = 'Name;Value WUServer;http://x:x WUStatusServer;http://x:x TargetGroupEnabled;1 ' | ConvertFrom-Csv -Delimiter ";" $WarnMissingUpdates = 10 $CritMissingUpdates = 20 $WarnLastInstallDate = -30 $CritLastInstallDate = -60 $Result = "" $Status = "OK" $PerfStats = "" #========================================== # Function Exit_State #========================================== Function Exit_State ($Status) { Switch ($Status) { "OK" {Return 0} "WARNING" {Return 1} "CRITICAL" {Return 2} "UNKNOWN" {Return 3} } } #========================================== # Function ExitReport #========================================== Function ExitReport ($Status, $Result) { Write-Host ($Status + ":" + $Result + "`n") Exit [int](Exit_State $Status) } #========================================== # Function Max_State #========================================== Function Max_State ($Current, $Compare) { If ($Compare -eq "CRITICAL" -or $Current -eq "CRITICAL") { Return "CRITICAL" } ElseIf ($Compare -eq "WARNING" -or $Current -eq "WARNING") { Return "WARNING" } ElseIf ($Compare -eq "UNKNOWN" -or $Current -eq "UNKNOWN") { Return "UNKNOWN" } Else { Return "OK" } } #Status examples #$Status = Max_State $Status "OK" #$Status = Max_State $Status "WARNING" #$Status = Max_State $Status "CRITICAL" #$Status = Max_State $Status "UNKNOWN" #========================================== # Main #========================================== $Error.Clear() # Verify Windows Update Settings $TempResult = $null $WindowsUpdateSettings = Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" foreach ($Setting in $ConfWindowsUpdateSettings) { If ($WindowsUpdateSettings.($Setting.Name) -ne $Setting.Value) { $Status = Max_State $Status "WARNING" $TempResult += ("{0}," -f $Setting.Name) } } If ($TempResult) { $Result += " Settings: {0};" -f $TempResult.TrimEnd(",") } Else { $Result += " Settings: OK;" } # Verify service not disabled $wuauserv = Get-Service -Name wuauserv if ($wuauserv.StartType -eq "Disabled") { Set-Service -Name wuauserv -StartupType Manual } #<# # Get update information from Microsoft update $UpdateSession = New-Object -ComObject 'Microsoft.Update.Session' $UpdateSearcher = $UpdateSession.CreateUpdateSearcher() $SearchResult = $UpdateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0") $HistoryCount = $UpdateSearcher.GetTotalHistoryCount() $UpdateHistory = $UpdateSearcher.QueryHistory(0,$HistoryCount) $MissingUpdates = ($SearchResult.Updates | Where-Object {$_.Title -notlike '*Definition Update*' -and $_.Description -notlike '*Install this update to revise the files that are used to detect viruses, spyware, and other potentially unwanted software.*'} | Measure-Object | Select-Object -ExpandProperty Count) $LastInstallDate = (Get-Date ($UpdateHistory | Sort-Object -Descending -Property Date | Where-Object {$_.Title -notlike 'Definition Update *' -and $_.Description -notlike '*Install this update to revise the files that are used to detect viruses, spyware, and other potentially unwanted software.*'} | Select-Object -First 1 -ExpandProperty Date) -Format "yyyy-MM-dd HH:mm:ss") #$LastInstallTitle = ($UpdateHistory | Sort-Object -Descending -Property Date | Where-Object {$_.Title -notlike 'Definition Update *'} | Select-Object -First 1 -ExpandProperty Title) #> # Verify missing count $Result += " Missing: {0};" -f $MissingUpdates $PerfStats += "Missing={0};{1};{2} " -f $MissingUpdates, $WarnMissingUpdates, $CritMissingUpdates If ($MissingUpdates -ge $CritMissingUpdates) { $Status = Max_State $Status "CRITICAL" } ElseIf ($MissingUpdates -ge $WarnMissingUpdates) { $Status = Max_State $Status "WARNING" } # Verify last install date $Result += " Last: {0}" -f (Get-Date $LastInstallDate -Format "yyyy-MM-dd") If ([datetime]$LastInstallDate -lt (Get-Date).AddDays($CritLastInstallDate)) { $Status = Max_State $Status "CRITICAL" } ElseIf ([datetime]$LastInstallDate -lt (Get-Date).AddDays($WarnLastInstallDate)) { $Status = Max_State $Status "WARNING" } # Check for errors If ($Error.Count -gt 0) { $Status = Max_State $Status "UNKNOWN" $Result += "; Errors: {0}" -f $Error.Count #$Error | Out-File -FilePath C:\x.txt -Append } #========================================== # Exit and Report #========================================== $Result += "|" + $PerfStats ExitReport $Status $Result ScriptBlock ID: acad77d5-f5ce-414b-96de-ea6f78ba3021 Path: C:\x
        </Message>
        <Level>Warning</Level>
        <Task>Execute a Remote Command</Task>
        <Opcode>On create calls</Opcode>
        <Channel>Microsoft-Windows-PowerShell/Operational</Channel>
        <Provider />
        <Keywords />
    </RenderingInfo>
</Event>

Also as we see here, there is a lot of information missing in the ScriptBlockText when fluentd picking it up

fluentd config:

<source>
    @type                           windows_eventlog2
    @id                             windows_eventlog2_0
    read_interval                   1
    tag                             x
    rate_limit                      200
    channels                        x
    parse_description               true
    render_as_xml                   true
    description_locale		    en_US
    <storage>   
        @type                       local
        persistent                  true
        path                        x
    </storage>
</source>

philipsabri avatar Aug 06 '20 10:08 philipsabri

Event in the eventviewer XML:

The XML seems broken. I've checked it by some XML validators and all of them report the following error:

The Content Of Elements Must Consist Of Well-formed Character Data Or Markup., Line '22', Column '143'.

It seems that an invalid < exists in <Data Name="ScriptBlockText"> node:

=== # Configuration #========================================== <# $ConfWindowsUpdateSettings
                                                                ^ Here!
                                                                ^ Here!
                                                                ^ Here!

ashie avatar Aug 07 '20 01:08 ashie

The XML seems broken.

~~I agree the XML is broken. Is there something we can do about this or is it up to Microsoft?~~

Also I didnt know I could save the eventlog as .xml so here is the original .xml file of the event if that would make any difference.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Events><Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'><System><Provider Name='Microsoft-Windows-PowerShell' Guid='{A0C1853B-5C40-4B15-8766-3CF1C58F985A}'/><EventID>4104</EventID><Version>1</Version><Level>3</Level><Task>2</Task><Opcode>15</Opcode><Keywords>0x0</Keywords><TimeCreated SystemTime='2020-08-05T08:54:21.118916000Z'/><EventRecordID>22338</EventRecordID><Correlation ActivityID='{4FC9EF57-59A7-0001-26CA-FA52A759D601}'/><Execution ProcessID='14424' ThreadID='13956'/><Channel>Microsoft-Windows-PowerShell/Operational</Channel><Computer>x</Computer><Security UserID='x'/></System><EventData><Data Name='MessageNumber'>1</Data><Data Name='MessageTotal'>1</Data><Data Name='ScriptBlockText'>#==========================================
# Configuration
#==========================================

&lt;#
$ConfWindowsUpdateSettings = 'Name;Value
WUServer;http://x:x
WUStatusServer;http://x:x
TargetGroupEnabled;1
DoNotConnectToWindowsUpdateInternetLocations;0
' | ConvertFrom-Csv -Delimiter ";"
#&gt;

$ConfWindowsUpdateSettings = 'Name;Value
WUServer;http://x:x
WUStatusServer;http://x:x
TargetGroupEnabled;1
' | ConvertFrom-Csv -Delimiter ";"

$WarnMissingUpdates = 10
$CritMissingUpdates = 20

$WarnLastInstallDate = -30
$CritLastInstallDate = -60

$Result = ""
$Status = "OK"
$PerfStats = ""

#==========================================
# Function Exit_State
#==========================================
Function Exit_State ($Status)
{
    Switch ($Status)
    {
        "OK" {Return 0}
        "WARNING" {Return 1}
        "CRITICAL" {Return 2}
        "UNKNOWN" {Return 3}
    }
}

#==========================================
# Function ExitReport
#==========================================
Function ExitReport ($Status, $Result)
{
	Write-Host ($Status + ":" + $Result + 	"`n")
	Exit [int](Exit_State $Status)
}

#==========================================
# Function Max_State
#==========================================
Function Max_State ($Current, $Compare)
{
	If ($Compare -eq "CRITICAL" -or $Current -eq "CRITICAL")
    {
		Return "CRITICAL"
	}
	ElseIf ($Compare -eq "WARNING" -or $Current -eq "WARNING")
    {
		Return "WARNING"
	}
	ElseIf ($Compare -eq "UNKNOWN" -or $Current -eq "UNKNOWN")
    {
		Return "UNKNOWN"
	}
	Else
{
		Return "OK"
	}
}

#Status examples
#$Status = Max_State $Status "OK"
#$Status = Max_State $Status "WARNING"
#$Status = Max_State $Status "CRITICAL"
#$Status = Max_State $Status "UNKNOWN"

#==========================================
# Main
#==========================================
$Error.Clear()

# Verify Windows Update Settings
$TempResult = $null
$WindowsUpdateSettings = Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
foreach ($Setting in $ConfWindowsUpdateSettings)
{
    If ($WindowsUpdateSettings.($Setting.Name) -ne $Setting.Value)
    {
        $Status = Max_State $Status "WARNING"
        $TempResult += ("{0}," -f $Setting.Name)
    }
}
If ($TempResult)
{
    $Result += " Settings: {0};" -f $TempResult.TrimEnd(",")
}
Else
{
    $Result += " Settings: OK;"
}

# Verify service not disabled
$wuauserv = Get-Service -Name wuauserv
if ($wuauserv.StartType -eq "Disabled") {
    Set-Service -Name wuauserv -StartupType Manual
}

#&lt;#
# Get update information from Microsoft update
$UpdateSession = New-Object -ComObject 'Microsoft.Update.Session'
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
$SearchResult = $UpdateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")
$HistoryCount = $UpdateSearcher.GetTotalHistoryCount()
$UpdateHistory = $UpdateSearcher.QueryHistory(0,$HistoryCount)

$MissingUpdates = ($SearchResult.Updates | Where-Object {$_.Title -notlike '*Definition Update*' -and $_.Description -notlike '*Install this update to revise the files that are used to detect viruses, spyware, and other potentially unwanted software.*'} | Measure-Object | Select-Object -ExpandProperty Count)
$LastInstallDate = (Get-Date ($UpdateHistory | Sort-Object -Descending -Property Date | Where-Object {$_.Title -notlike 'Definition Update *' -and $_.Description -notlike '*Install this update to revise the files that are used to detect viruses, spyware, and other potentially unwanted software.*'} | Select-Object -First 1 -ExpandProperty Date) -Format "yyyy-MM-dd HH:mm:ss")
#$LastInstallTitle = ($UpdateHistory | Sort-Object -Descending -Property Date | Where-Object {$_.Title -notlike 'Definition Update *'} | Select-Object -First 1 -ExpandProperty Title)
#&gt;

# Verify missing count
$Result += " Missing: {0};" -f $MissingUpdates
$PerfStats += "Missing={0};{1};{2} " -f $MissingUpdates, $WarnMissingUpdates, $CritMissingUpdates
If ($MissingUpdates -ge $CritMissingUpdates)
{
    $Status = Max_State $Status "CRITICAL"
}
ElseIf ($MissingUpdates -ge $WarnMissingUpdates)
{
    $Status = Max_State $Status "WARNING"
}

# Verify last install date
$Result += " Last: {0}" -f (Get-Date $LastInstallDate -Format "yyyy-MM-dd")
If ([datetime]$LastInstallDate -lt (Get-Date).AddDays($CritLastInstallDate))
{
    $Status = Max_State $Status "CRITICAL"
}
ElseIf ([datetime]$LastInstallDate -lt (Get-Date).AddDays($WarnLastInstallDate))
{
    $Status = Max_State $Status "WARNING"
}

# Check for errors
If ($Error.Count -gt 0)
{
    $Status = Max_State $Status "UNKNOWN"
    $Result += "; Errors: {0}" -f $Error.Count
    #$Error | Out-File -FilePath C:\x -Append
}

#==========================================
# Exit and Report
#==========================================
$Result += "|" + $PerfStats
ExitReport $Status $Result
</Data><Data Name='ScriptBlockId'>acad77d5-f5ce-414b-96de-ea6f78ba3021</Data><Data Name='Path'>C:\x.ps1</Data></EventData><RenderingInfo Culture='en-US'><Message>Creating Scriptblock text (1 of 1):
#==========================================
# Configuration
#==========================================

&lt;#
$ConfWindowsUpdateSettings = 'Name;Value
WUServer;http://x:x
WUStatusServer;http://x:x
TargetGroupEnabled;1
DoNotConnectToWindowsUpdateInternetLocations;0
' | ConvertFrom-Csv -Delimiter ";"
#&gt;

$ConfWindowsUpdateSettings = 'Name;Value
WUServer;http://x:x
WUStatusServer;http://x:x
TargetGroupEnabled;1
' | ConvertFrom-Csv -Delimiter ";"

$WarnMissingUpdates = 10
$CritMissingUpdates = 20

$WarnLastInstallDate = -30
$CritLastInstallDate = -60

$Result = ""
$Status = "OK"
$PerfStats = ""

#==========================================
# Function Exit_State
#==========================================
Function Exit_State ($Status)
{
    Switch ($Status)
    {
        "OK" {Return 0}
        "WARNING" {Return 1}
        "CRITICAL" {Return 2}
        "UNKNOWN" {Return 3}
    }
}

#==========================================
# Function ExitReport
#==========================================
Function ExitReport ($Status, $Result)
{
	Write-Host ($Status + ":" + $Result + 	"`n")
	Exit [int](Exit_State $Status)
}

#==========================================
# Function Max_State
#==========================================
Function Max_State ($Current, $Compare)
{
	If ($Compare -eq "CRITICAL" -or $Current -eq "CRITICAL")
    {
		Return "CRITICAL"
	}
	ElseIf ($Compare -eq "WARNING" -or $Current -eq "WARNING")
    {
		Return "WARNING"
	}
	ElseIf ($Compare -eq "UNKNOWN" -or $Current -eq "UNKNOWN")
    {
		Return "UNKNOWN"
	}
	Else
{
		Return "OK"
	}
}

#Status examples
#$Status = Max_State $Status "OK"
#$Status = Max_State $Status "WARNING"
#$Status = Max_State $Status "CRITICAL"
#$Status = Max_State $Status "UNKNOWN"

#==========================================
# Main
#==========================================
$Error.Clear()

# Verify Windows Update Settings
$TempResult = $null
$WindowsUpdateSettings = Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
foreach ($Setting in $ConfWindowsUpdateSettings)
{
    If ($WindowsUpdateSettings.($Setting.Name) -ne $Setting.Value)
    {
        $Status = Max_State $Status "WARNING"
        $TempResult += ("{0}," -f $Setting.Name)
    }
}
If ($TempResult)
{
    $Result += " Settings: {0};" -f $TempResult.TrimEnd(",")
}
Else
{
    $Result += " Settings: OK;"
}

# Verify service not disabled
$wuauserv = Get-Service -Name wuauserv
if ($wuauserv.StartType -eq "Disabled") {
    Set-Service -Name wuauserv -StartupType Manual
}

#&lt;#
# Get update information from Microsoft update
$UpdateSession = New-Object -ComObject 'Microsoft.Update.Session'
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
$SearchResult = $UpdateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")
$HistoryCount = $UpdateSearcher.GetTotalHistoryCount()
$UpdateHistory = $UpdateSearcher.QueryHistory(0,$HistoryCount)

$MissingUpdates = ($SearchResult.Updates | Where-Object {$_.Title -notlike '*Definition Update*' -and $_.Description -notlike '*Install this update to revise the files that are used to detect viruses, spyware, and other potentially unwanted software.*'} | Measure-Object | Select-Object -ExpandProperty Count)
$LastInstallDate = (Get-Date ($UpdateHistory | Sort-Object -Descending -Property Date | Where-Object {$_.Title -notlike 'Definition Update *' -and $_.Description -notlike '*Install this update to revise the files that are used to detect viruses, spyware, and other potentially unwanted software.*'} | Select-Object -First 1 -ExpandProperty Date) -Format "yyyy-MM-dd HH:mm:ss")
#$LastInstallTitle = ($UpdateHistory | Sort-Object -Descending -Property Date | Where-Object {$_.Title -notlike 'Definition Update *'} | Select-Object -First 1 -ExpandProperty Title)
#&gt;

# Verify missing count
$Result += " Missing: {0};" -f $MissingUpdates
$PerfStats += "Missing={0};{1};{2} " -f $MissingUpdates, $WarnMissingUpdates, $CritMissingUpdates
If ($MissingUpdates -ge $CritMissingUpdates)
{
    $Status = Max_State $Status "CRITICAL"
}
ElseIf ($MissingUpdates -ge $WarnMissingUpdates)
{
    $Status = Max_State $Status "WARNING"
}

# Verify last install date
$Result += " Last: {0}" -f (Get-Date $LastInstallDate -Format "yyyy-MM-dd")
If ([datetime]$LastInstallDate -lt (Get-Date).AddDays($CritLastInstallDate))
{
    $Status = Max_State $Status "CRITICAL"
}
ElseIf ([datetime]$LastInstallDate -lt (Get-Date).AddDays($WarnLastInstallDate))
{
    $Status = Max_State $Status "WARNING"
}

# Check for errors
If ($Error.Count -gt 0)
{
    $Status = Max_State $Status "UNKNOWN"
    $Result += "; Errors: {0}" -f $Error.Count
    #$Error | Out-File -FilePath C:\x -Append
}

#==========================================
# Exit and Report
#==========================================
$Result += "|" + $PerfStats
ExitReport $Status $Result


ScriptBlock ID: acad77d5-f5ce-414b-96de-ea6f78ba3021
Path: C:\x.ps1</Message><Level>Warning</Level><Task>Execute a Remote Command</Task><Opcode>On create calls</Opcode><Channel>Microsoft-Windows-PowerShell/Operational</Channel><Provider></Provider><Keywords></Keywords></RenderingInfo></Event></Events>

philipsabri avatar Aug 07 '20 08:08 philipsabri

@ashie I checked the new XML and it has no error

philipsabri avatar Aug 07 '20 09:08 philipsabri

Try setting parse_description false. That parser seems to assume (more or less) that the format of the "Description" field matches the Security log where you have "Sections" with "Keys" and "Values" that are tab separated. The relevant code for parsing Description is at https://github.com/fluent/fluent-plugin-windows-eventlog/blob/e061144738ddd3c54971a6966d73a98335ae473f/lib/fluent/plugin/in_windows_eventlog2.rb#L357-L401.

That said, you will need something else to help pull data out of the Description field to help make it relevant.

UVduane avatar May 03 '24 21:05 UVduane