Powershell: filtering event logs - powershell

Ive written a small script to retreive event logs from application for the last 10 days but i receive the error. Any ideas why the error appear?
Where-Object : Cannot bind parameter 'FilterScript'. Cannot convert
value "False" to type "System.Management.Automation.ScriptBlock".
Error: "Invalid cast from 'System.Boolean' to
'System.Management.Automation.ScriptBlock'."
#Sets the application log to query
$Log ="Application"
$FilterHashTable = #{LogName=$Log}
#stores the computer name
$ComputerName = $env:COMPUTERNAME
#sets the date 10 days ago
$DeleteDate = Get-Date
$DeleteDate = $DeleteDate.AddDays(-10)
Write-Verbose $DeleteDate
#retrieve WMIevent and logs the information
$Winevent = Get-WinEvent -ComputerName $ComputerName -FilterHashTable $FilterHashTable -ErrorAction SilentlyContinue
# Filter on time
$Winevent | where-object ($_.timecreated -gt $DeleteDate)

Where-Object needs a scriptblock parameter - use curly braces {...} not parentheses (...) to contain your filter logic.
Currently PS is checking your criteria and returning a boolean, instead of applying it as a filter.

Related

Splunk String Search

I have a powershell command value for a process field that I am trying to match in my splunk search but I am getting
"Error in 'SearchParser': Subsearches are only valid as arguments to commands. Error at position '3271' of search query 'litsearch (index=notable ((sourcetype="WMI:LocalPr...{snipped} {errorcontext = andLine"=[[Decoded Ba}'.":
`macro` rule_name="rule-name" process="[[Decoded Base64]] -LogName Microsoft-Windows-Diagnostics-Performance/Operational
| Where-Object {$_.Id -eq 100 -and $_.TimeCreated -ge ((Get-Date) - (New-TimeSpan -Day 90))}
| Format-list ;<!LF!>$ImpersonatedUser.ImpersonationContext.Undo()<!LF!>"
I need a solution for grabbing every instance that this value occurs

Apply conditional to output of a commandlet

I want to output the result of the commandlet (Invoke-Command) on success and add a custom message if the result is null. The code as shown below produces the desired results except in the event of a null response, it simply outputs nothing on that line.
I can not pipe directly to an if statement, nor can I output on 2 opposing conditions (True & False). Is it possible to get a custom response on $null while not suppressing the normal output on success?
Invoke-Command -ComputerName PC1, PC2, PC3 -Scriptblock {get-eventlog system | where-object {$_.eventid -eq 129} | select MachineName, EventID, TimeGenerated, Message -last 1}
If you run the example code block assuming that PC1 and PC3 have the event ID but PC2 does not, the output will simply skip PC2.
I want to output something like "Event Not found" in that case.
Placing the entire thing in a loop and then running the results through another conditional loops destroys performance so that is not an ideal solution.
I would create a new object for returning from Invoke-Command. So you are sure you will receive from every host something even the event log is not present. And might you can change get-eventlog to Get-WinEvent. Get-WinEvent was for my tasks the most time faster than get-eventlog.
[System.Management.Automation.ScriptBlock]$Scriptblock = {
[System.Collections.Hashtable]$Hashtable = #{
WinEvent = Get-WinEvent -FilterHashtable #{ LogName = 'System'; Id = 129 } -MaxEvents 1 -ErrorAction SilentlyContinue #-ErrorAction SilentlyContinue --> otherwise there is an error if no event is available
}
return (New-Object -TypeName PSCustomObject -Property $Hashtable)
}
Invoke-Command -ComputerName 'PC1', 'PC2', 'PC3' -Scriptblock $Scriptblock

get-winevent: cannot filter specific field FailureReason %%2313

I'm poking around with get-winevent for the event 4625 because i need the failure-reason, which is in a xml field of the event.
the first thing i tried is to print out all fields hoping, the failure reason is available somewhere in the data-path of the xml, with no success.
i did not found a way to query the statuscode %%2313 to something with powershell to get the readable text.
the last thing i did is filtering the specific event and write the statusmessage myself in a custom field of my export file.
I used this code to accomplish that:
Get-WinEvent -FilterHashtable #{Path="c:\temp\test.evtx";} -ErrorAction SilentlyContinue |
Where-Object {($_.id -eq "4625" -and $_.properties[9].value -in "%% 2313")}|ForEach-Object{
$SelectorStrings = [string[]]#(
'Event/EventData/Data[#Name="TargetUserName"]',
'Event/EventData/Data[#Name="TargetDomainName"]',
'Event/EventData/Data[#Name="WorkstationName"]',
'Event/EventData/Data[#Name="IpAddress"]',
'Event/EventData/Data[#Name="IpPort"]',
'Event/EventData/Data[#Name="LogonType"]',
'Event/EventData/Data[#Name="FailureReason"]',
'Event/EventData/Data[#Name="Remark"]'
)
$PropertySelector = [System.Diagnostics.Eventing.Reader.EventLogPropertySelector]::new($SelectorStrings)
$TargetUserName,$TargetDomainName,$WorkstationName,$IpAddress,$IpPort,$LogonType,$FailureReason,$Remark = $_.GetPropertyValues($PropertySelector)
$Remark ="Unbekannter Benutzername oder ungültiges Kennwort."
#Create the PSCustomObject from the given Fieldnames
[PSCustomObject]#{
TimeCreated = $_.TimeCreated
Id = $_.Id
UserName = $TargetUserName
Domain = $TargetDomainName
WorkstationName = $WorkstationName
IPAddress = $IpAddress
Port = $IpPort
LogonType = $LogonType
Message = ($_.Message).split(".")[0]
Remark = $Remark
FailureReason =$FailureReason
}
}|Export-Csv -NoTypeInformation -Force -Encoding UTF8 -Path 'c:\temp\failurereason.csv'
but: it seams i cannot filter for %%2313 as property value. no idea why. Even with quotation marks or something, dont get any event out.

Extracting part of a host name with select-object

I have a simple powershell function where I provide the log type and event and it scans all of our SQL servers. it works except the host name is returned as hostname.domain.local. I want it to return just the host name. I've tried machinename.split('.') and substring and it won't work. I've tried putting the select-object into a separate variable and was going to join it with the rest of the columns, but it takes too long to run.
Here is my sample scrap code i'm testing with before I change my function along with the commented out parts that didn't work. Looked around and found lots of resources about the commands, but they don't work when I try to use them in my script.
The error I keep getting is A positional parameter cannot be found that accepts argument '. '.
$servers = Get-Content -literalpath "C:\temp\sql_servers3.txt"
#$server
#$result =
ForEach($box in $servers) {Get-Eventlog -ComputerName $box -LogName
application -After 1-4-2018 -Entrytype Error | Where {$_.source -notin
'Perfnet','Perflib', 'ntfs', 'vss'}| select-object -property MachineName}
#$result_Host_name = select-object -inputobject $result -property
'MachineName'
#'TimeGenerated', 'MachineName'.Split('.')[1], 'EventID','message'}
#| Where {$_.source -notin 'Perfnet','Perflib', 'ntfs', 'vss'} 0
#return $result_Host_name
What you are looking for is a "Calculated Property" when using Select-Object.
| Select-Object #{n='HostName';e={($_.MachineName -split '\.')[0]}}

Powershell: How can I extract time from the message field of eventlog?

I'm trying to get unexpected shutdown times of Windows Sever 2008 machines via Get-EventLog in Powershell. I can get close by searching for events with an EventID of 6008 and selecting only message, but I need to parse within the field to grab the time it occurred (not the time the event fired).
I've tried to use replacementstrings[x] but I can't find how to specify the field to use (messages) and can't get a result.
get-eventlog -LogName System -ComputerName svr-name | Where-Object {$_.EventID -eq 6008 -AND $_.timegenerated -gt (get-date).adddays(-30)}| select message
Produces this:
Message
-------
The previous system shutdown at 3:35:32 AM on ‎7/‎29/‎2014 was unexpected.
The previous system shutdown at 3:40:06 PM on ‎7/‎10/‎2014 was unexpected.`
Retrieving all events from a remote host and filtering them on the local machine ususally doesn't perform too well, because that way you transmit tons of unrelated events over the network, just to throw them away. Get-EventLog has options for filtering messages by Event ID or before/after a given timestamp on the source, so better use those for pre-selecting the messages you're actually interested in. The timestamp of the crash can be extracted from the Message field with a regular expression and parsed into a DateTime value via ParseExact():
$log = 'System'
$server = 'svr-name'
$id = [uint64]"0x80000000" + 6008
$date = (Get-Date).AddDays(-30)
$fmt = 'h:mm:ss tt on M\/d\/yyyy'
$culture = [Globalization.CultureInfo]::InvariantCulture
Get-EventLog -LogName $log -ComputerName $server -InstanceId $id -After $date | ? {
$_.Message -match 'at (\d+:\d+:\d+ [ap]m on \d+/\d+/\d+) was unexpected'
} | select MachineName, TimeGenerated,
#{n='Crashtime';e={[DateTime]::ParseExact($matches[1], $fmt, $culture)}}
The pipeline produces a list of objects with the properties MachineName, TimeGenerated and Crashtime (the last one being a calculated property). If you collect the output of the pipeline in a variable (e.g. $evt) you can access the Crashtime property of the third object like this:
$evt = .\script.ps1
$evt[2].Crashtime
Using regex, you can pull it out as such.
$Messages = (get-eventlog -LogName System -ComputerName svr-name | Where-Object {$_.EventID -eq 6008 -AND $_.timegenerated -gt (get-date).adddays(-30) }| select message)
$Messages | ForEach-Object {
$Matched = $_.Message -match "([0-9]{1,2}:.*[0-9]{4})"
if ($Matched) {
Write-Output "System rebooted at $($Matches[1])"
}
}
There might be a better way, but I do not know what :)
Example Output from my System
System rebooted at 4:34:30 PM on ‎4/‎20/‎2014
System rebooted at 1:48:38 PM on ‎1/‎21/‎2014
System rebooted at 1:37:12 PM on ‎1/‎21/‎2014
System rebooted at 1:22:01 PM on ‎1/‎21/‎2014
System rebooted at 4:41:21 PM on ‎11/‎22/‎2013
More easy
get-eventlog system | where-object {$_.EventID -eq "6008"} | fl