Showing LogName in table when querying multiple logs with PowerShell get-eventlog - powershell

I'm new to PowerShell and I am trying to get recent events for a group of logs (right now application and system for testing purposes).
What's missing is a column in the final output showing the log the event came from.
I tried piping the output before the format-table to get member to see if there was a property that contained the logname and there doesn't seem to be one.
Is there a workaround to get this?
What I have right now is:
"application", "system" | foreach { Get-EventLog -LogName $_ -Newest 10 } | sort time -Descending | ft timegenerated, LogName, source, message -wrap -AutoSize
This is what I want, but the LogName column is blank because there's no such property.

Someone may be able to clean this up a little, but you could try this:
"application", "system" | foreach { $events = Get-EventLog -LogName $_ -Newest 10; $events | Add-Member -MemberType NoteProperty -Name LogName -Value (Get-Culture).TextInfo.ToTitleCase($_); $events } | sort timegenerated -Descending | ft timegenerated, LogName, source, message -wrap -AutoSize
I fixed the sort command(typo) and format the logname as proper(uppercase first letter) to clean it up.

Related

Powershell script doesn't return event log results based on where clause

I am new to powershell and found examples to display messages from the event log. The -match and -eq property don't seem to be working. Below is my script which does not return any results. When I use -notmatch or -ne it displays correctly. I’ve tried many different variations of the code, but nothing has worked.
$sysEvent = Get-EventLog -LogName Application -Newest 300
$sysError = $sysEvent | where {$_entryType -match "Information"}
$sysError | Sort-Object EventID | Format-Table EventID, EntryType, Source, TimeWritten, Message -AutoSize

Get the last 10 events in Eventlog(Application, Secuirty, System) in PowerShell

I am trying to get the the last 10 events in the «EventLog» logs «Application», «Security» and «System» parallelly. I get an error with this message:
Get-EventLog : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'LogName'"
when running the script. The script works when running with only the logname "Application".
Get-Eventlog -Newest 10 -LogName "Application","Security","System"
"Application","Security","System" | ForEach-Object {
Get-Eventlog -Newest 10 -LogName $_
}
That will get you the 10 most recent events in each log. If you want the 10 most recent events of all three logs taken together, you will need to do this:
"Application","Security","System" | ForEach-Object {
Get-Eventlog -Newest 10 -LogName $_
} | Sort-Object -Property Time -Descending | Select-Object -First 10
You can't do it the way you are trying, as -LogName requires a string and you are passing an array.
You could accomplish your task by piping an array into a ForEach-Object and going through the logs one at a time. The %{} is an alias for ForEach-Object
"Application","Security","System" | %{Get-Eventlog -Newest 10 -LogName $_}
Get-eventlog has been replaced by get-winevent. You'd still have to use foreach to get 10 of each. Grouping by logname instead of providername might be less annoying.
echo Application,Security,System | % { get-winevent $_ -maxevents 10 } |
ft -groupby logname

Adding custom property or replacing read-only property

I'm attempting to automate a loop that goes through our servers collecting logs from eventviewer to later export into a webpage which works just fine, BUT, I would like to add a property to this list or possible modify an existing read-only property.
Here is the scriptlines I'm using:
$eventlog = (Get-EventLog -LogName system -Newest 5 -EntryType Error)
$eventlog | Select-Object Source,Message,MachineName | ConvertTo-Html -Head $a | Out-File C:\logs.htm
The only real issue here is that the property "MachineName" list "name.domain.com" instead of just "name", so I went ahead and added the following:
$eventlog | ForEach-Object {
$_.MachineName=$env:COMPUTERNAME
}
This was stopped because the property is read-only so I thought I could perhaps add a property to my object and just populate it with a variable which I still believe should work but I'm not getting the hang of how Add-Memberworks fully.
Here is how I went about it:
$eventlog | Add-Member -Name Hostname -Value $env:COMPUTERNAME
or
Add-Member -InputObject $eventlog -Name Hostname -Value $env:COMPUTERNAME
Obviously this alone doesn't work but I can't get my head around how the rest of the parameters are supposed to look. I'm also fairly certain the line above isn't even right but it's enough to make you understand what I'm trying to achieve and perhaps know of a better solution!
You could use a calculated property. This way you can modify read only properties or add new....
$eventlog = (Get-EventLog -LogName system -Newest 5 -EntryType Error)
$eventlog | Select-Object Source,Message, #{l='MachineName'; e={$env:COMPUTERNAME}} |
ConvertTo-Html -Head $a |
Out-File C:\logs.htm
$eventlog | Add-Member -Name 'Hostname' -Value $env:COMPUTERNAME -MemberType NoteProperty
$eventlog | Select ...,hostname | ConvertTo-Html -Head $a | Out-File C:\logs.htm

Powershell Get-WinEvent Truncates Message

I have the following Powershell code that counts the number of errors occurring per Provider, based on Error ID and Message. What I am after is getting the count of each unique message per computer, log, provider, id and level.
However the issue that I'm having is that when I export this information to .csv the event message is being truncated. Or rather, I'm not able to quite grasp what I need to do to get the entire event message.
Here is the code that grabs the event logs and exports it to .csv.
$computername = 'mycomputer'
$logs = "application", "system"
$info = get-winevent -ComputerName $computername -FilterHashTable #{LogName=$logs; Level=1,2,3} |
sort MachineName,LogName,ProviderName,{$_.LevelDisplayName},ID |
Group MachineName, LogName, ProviderName, ID, {$_.LevelDisplayName}, Count, Message |
select #{N="Computer";E={$_.name.split(',')[0]}},#{N="Log";E={$_.name.split(',')[1]}}, #{N="Provider";E={$_.name.split(',')[2]}}, #{N="Error ID";E={$_.name.split(',')[3]}},`
#{N="Type";E={$_.name.split(',')[4]}}, count, #{N="Message";E={$_.name.split(',')[5 |
Export-Csv -notypeinformation -Path c:\Test\events.csv
If I comment out
#| Export-Csv -notypeinformation -Path c:\Test\events.csv
And output
$info
I see the complete message. I also can see more of the message if I continue to expand the array indexes. For example I get more of the message if I do this:
, #{N="Message1";E={$_.name.split(',')[6]}}, #{N="Message2";E={$_.name.split(',')[7]}}
What do I need to code correct to get the entire message out in the
#{N="Message";E={$_.name.split(',')[5]}}
selection?
I think you Can take a much easier approach, with the built-in ConvertFrom-Csv, Also the script would be much more Readable
$info = get-winevent -ComputerName $computername -FilterHashTable #{LogName=$logs; Level=1,2,3} |
sort MachineName,LogName,ProviderName,{$_.LevelDisplayName},ID |
Group MachineName, LogName, ProviderName, ID, {$_.LevelDisplayName}, Count, Message
$Array = #()
$Header = "Computer","Log","Provider","ErrorID","Type","Message","Count"
Foreach ($item in $Info)
{
$Count = $Item.Count
$CSV = $item.Name | ConvertFrom-Csv -Delimiter "," -Header $Header
$CSV.Count = $Count
$Array += $CSV
}
$Array | Export-CSV C:\Test\Events.csv -NoTypeInformation
I'm guessing you're not truncating. You've just got messages with commas in them, and Split() doesn't have any way to know what's a delimiter and what's part of the message.
Well, I suppose you could specify:
#{N="Message";E={($_.name.split(',')[5..($_.name.split(',').Count - 1)]) -join ','}}
But, honestly, this feels like some mighty gigantic hoops to jump through.
What's wrong with $_.Group[0].<item> instead of $_.name.split(',')[<num>]? Except count, you're grouping by all the fields you're pulling, aren't you? So the value on the first event should, by definition, be the same on every other event in the same group, right?
Also, why {$_.LevelDisplayName} instead of just LevelDisplayName?
And I think you'll find that Message won't work very well in a CSV unless you strip line feeds and carriage returns.
Try this:
$ComputerName = 'ComputerName';
$Logs = 'Application', 'System';
$Info = Get-WinEvent -ComputerName $ComputerName -FilterHashTable #{LogName=$Logs; Level=1,2,3} `
| Sort-Object MachineName, LogName, ProviderName, LevelDisplayName, ID `
| Group-Object MachineName, LogName, ProviderName, ID, LevelDisplayName, Count, Message `
| Select-Object #{N="Computer";E={$_.Group[0].MachineName}}, `
#{N="Log"; E={$_.Group[0].LogName}}, `
#{N="Provider";E={$_.Group[0].ProviderName}}, `
#{N="Error ID";E={$_.Group[0].ID}}, `
#{N="Type"; E={$_.Group[0].LevelDisplayName}}, `
count, `
#{N="Message"; E={$_.Group[0].Message.Replace("`r",' ').Replace("`n",' ')}} `
| Export-Csv -NoTypeInformation -Path c:\Test\events.csv;

Powershell List of Computers

How can I make this use a list of servers
Tried doing $ComputerList = gc <list location> but it doesnt seem to be working
correctly with one computer
$Start = (Get-Date).AddMinutes(-120)
$ComputerList = $env:ComputerName
$Events = gc C:\Temp\ErrorCodes.txt
# Getting all event logs
Get-EventLog -AsString -ComputerName $Computername |
ForEach-Object {
# write status info
Write-Progress -Activity "Checking Eventlogs on \\$ComputerName" -Status $_
# get event entries and add the name of the log this came from
Get-EventLog -LogName $_ -EntryType Error, Warning -After $Start -ComputerName $ComputerName -ErrorAction SilentlyContinue |
Add-Member NoteProperty EventLog $_ -PassThru | Where-Object {$Events -contains $_.eventid}
} |
# sort descending
Sort-Object -Property EventLog |
# select the properties for the report
Select-Object EventLog, EventID, TimeGenerated, EntryType, Source, Message
# output into grid view window
Out-GridView -Title "All Errors & Warnings from \\$Computername"
Force it to be an array.. Otherwise it will come in as a string if there is only one item
$ComputerList = #(gc c:\folder\computerlist.txt)
PowerShell: How can I to force to get a result as an Array instead of Object