Get-EventLog - valid message missing for some event log sources - powershell

I'm pulling and filtering System Event Log data using get-eventlog. What I'm finding is that get-event log is not able to correctly return the message associated with some entries. These entries appear normally in the event log viewer. E.g.
get-eventlog -logname system | ? { $_.source -eq "Microsoft-Windows-Kernel-General" }
returns 8 entries, all of which have a message of the following form:
The description for Event ID '12' in Source 'Microsoft-Windows-Kernel-General' cannot be found.
The local computer may not have the necessary registry information or message DLL files to display the message, or you may not have permission to access them.
The following information is part of the event:'6', '1', '7601', '18798', '1', '0', '2015-06-13T08:33:32.359599800Z'
If I filter the system event log for the same source, I can clearly see the fully formed message. e.g
The operating system started at system time ‎2015‎-‎06‎-‎13T08:33:32.359599800Z.
I ran the following to see if any other providers were unable to return valid event messages:
get-eventlog -LogName system | ? { $_.Message -like "The description for Event ID*" } | Group-Object -Property Source | Select-Object -Property Name
Name
----
Microsoft-Windows-Kernel-General
DCOM
WinRM
Microsoft-Windows-Iphlpsvc
I checked in the event log viewer to find the corresponding entries for the DCOM, WinRM and Iphlpsvc sources and confirmed that the correct message was visible.
I've run the test scripts in a admin-level PowerShell console.
Any ideas?
EDIT: Further research has revealed that PsLogList also appears to suffer from the same problem, whereas WEVTUTIL does not.
EDIT: Following suggestion by Windos, I tried get-winevent. I had tried this previously and found that it would return no Message data at all. I tried again and found the same result. I then tried
Get-WinEvent -ProviderName "Microsoft-Windows-Kernel-General"
which produced the following error
Could not retrieve information about the Microsoft-Windows-Kernel-General provider. Error: The locale specific resource for the desired message is not present.
A little googling led me to 'https://p0w3rsh3ll.wordpress.com/2013/12/13/why-does-my-get-winevent-command-fail/' who had also experienced the same error message. He suggested this was due to regional settings. I'm in Australia, so my 'format' setting in Control Panel was 'English (Australia)'. I changed this to 'English (United States)', launched a new PS console, confirmed with get-culture that I was now in the US and re-ran the get-winevent commands.
Get-WinEvent -ProviderName "Microsoft-Windows-Kernel-General" | select-object -property Message
lo and behold ...
Message
-------
The system time has changed to ?2015?-?07?-?12T01:06:52.405000000Z from ?2015?-?07?-?12T01:05:51.764208900Z.
The system time has changed to ?2015?-?07?-?12T01:05:09.671000000Z from ?2015?-?07?-?12T01:04:09.226010500Z.
The system time has changed to ?2015?-?07?-?12T01:03:49.119000000Z from ?2015?-?07?-?12T01:02:48.060593100Z.
The system time has changed to ?2015?-?07?-?12T01:02:32.128000000Z from ?2015?-?07?-?12T01:01:29.610105600Z.
The system time has changed to ?2015?-?06?-?13T08:41:12.267000000Z from ?2015?-?06?-?13T08:41:12.404273100Z.
The operating system started at system time ?2015?-?06?-?13T08:33:32.359599800Z.
The operating system is shutting down at system time ?2015?-?06?-?13T08:33:05.091743100Z.
The system time has changed to ?2015?-?06?-?13T08:32:58.947000000Z from ?2015?-?06?-?13T08:32:58.947959900Z.
Sadly though - no change got get-eventlog
get-eventlog -logname system | ? { $_.Source -eq "microsoft-windows-kernel-general" } | select-object -property Message
Message
-------
The description for Event ID '1' in Source 'Microsoft-Windows-Kernel-General' cannot be found. The local computer m...
The description for Event ID '1' in Source 'Microsoft-Windows-Kernel-General' cannot be found. The local computer m...
The description for Event ID '1' in Source 'Microsoft-Windows-Kernel-General' cannot be found. The local computer m...
The description for Event ID '1' in Source 'Microsoft-Windows-Kernel-General' cannot be found. The local computer m...
The description for Event ID '1' in Source 'Microsoft-Windows-Kernel-General' cannot be found. The local computer m...
The description for Event ID '12' in Source 'Microsoft-Windows-Kernel-General' cannot be found. The local computer ...
The description for Event ID '13' in Source 'Microsoft-Windows-Kernel-General' cannot be found. The local computer ...
The description for Event ID '1' in Source 'Microsoft-Windows-Kernel-General' cannot be found. The local computer m...

Not sure on the how or why, but it looks like if you opt for Get-WinEvent rather than Get-EventLog you'll get the info you're after.
It should be noted that when changing commands the 'Source' parameter is known as 'ProviderName' so your command becomes:
Get-WinEvent -LogName System | Where { $_.ProviderName -eq 'Microsoft-Windows-Kernel-General' }

Related

Is there a way to find which user run what application on a server using Powershell

I am trying to find a way to find out who has ran an application (for example SQL) on a server, just to get some idea.
I tried Get-Process but this doesn't give me historic information, I want to get historical information
Get-Process -IncludeUserName *
what I want the return resule is "name of application", "user who ran it" and the last datetime it was ran by that user'
As for ...
I am trying to find a way to find out who has ran an application (for
example SQL) on a server, just to get some idea.
What you are asking for here is software metering.
SQL is a service that is always running once it is installed, so, no individual user is ever going to be running it. So, that is a bad example. MS Word for example would be a better example.
Yet there is nothing native in PowerShell that does this, software metering, but of course PowerShell can look at event logs. Yet if your auditing is not setup correctly then it's moot. This is better for a software metering tool, and there are several out there. So, why try and reinvent the wheel.
As for ...
I tried Get-Process but this doesn't give me historic information, I
want to get historical information
That is not what a process is nor what Get-Process is for. It, Get-Process only checks for and lists whatever process is currently running, regardless of what/who launched it.
As for...
what I want the return resule is "name of application", "user who ran
it" and the last datetime it was ran by that user'
As long as the process is running, you can get this, with that cmdlet.
However, what are you trying to accomplish by this?
Again, there are purpose built tools to meter software use.
https://learn.microsoft.com/en-us/sccm/apps/deploy-use/monitor-app-usage-with-software-metering
If you must go down this reinvent the wheel road, using scripting, then you need a task watcher on the target machines, which watches for the WinWord process to appear.
Get-Process -IncludeUserName |
Where ProcessName -EQ 'Winword'
... you then write those results to a file or database or your own event log each time you see that process.
Use PowerShell to Create and to Use a New Event Log
New-EventLog -LogName ScriptingGuys -Source scripts
When the command runs, no output appears to the Windows PowerShell console. To ensure the command actually created a new event log, I use
the Get-EventLog cmdlet with the –List parameter. Here is the command
and the associated output.
Write-EventLog -LogName ScriptingGuys -Source scripts -Message “Dude, it works … COOL!” -EventId 0 -EntryType information
Or just to a file
Get-Process -IncludeUserName |
Where ProcessName -EQ 'Winword' |
Select-Object -Property Name, StartTime, Username |
Export-Csv -Path 'F:\Temp\AppLaunchLog.csv' -Append
Import-Csv -Path 'F:\Temp\AppLaunchLog.csv'
# Results
Name StartTime UserName
---- --------- --------
WINWORD 5/23/2019 9:02:53 PM WS01\LabUser001

Get-EventLog not parsing Message when run by SYSTEM user

Problem
I am trying to schedule a job that monitors events on remote machines.
I wrote the script based on the Get-EventLog command and it works properly when run by my account. But when I run the Get-EventLog as SYSTEM user, the .Message attribute of the returned objects shows the following error:
The description for Event ID '4724' in Source 'Microsoft-Windows-Security-Auditing' cannot be found. The local computer may not have the necessary registry information or message DLL files to display the message, or you may not have permission to access them. The following information is part of the event: {somedata}
When I use the Get-WinEvent command as SYSTEM user, the problem does not appear and the .Message part displays properly.
I would stick with Get-WinEvent, especially since the data is much easier to parse (thanks to the ToXML() method), but the Get-EventLog happens to be terribly faster :(
Question
Does anyone have any idea why the Get-EventLog fails to render .Message when run by SYSTEM user and perhaps how to fix it?
To avoid obvious answers:
the COMPUTER$ account is member of DOMAIN\Event Log Readers group,
the COMPUTER$ account does have the read privileges over the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Security on remote machines,
obviously, the registry entries for Microsoft-Windows-Security-Auditing and related DLL's are identical on both the source and target computers.
Try:
Get-WinEvent -LogName “Microsoft-Windows-Security-Auditing” | where ID -eq 4724 | select-object -ExpandProperty Message

Selecting specific lines/data from Get-Winevent message in powershell

I am trying to extract a specific line from the message output of a get-winevent cmdlet and haven't been able to find a way to do this (I could be searching incorrectly but am still learning more advanced scripting methods). What I am running is this:
Get-WinEvent -ComputerName $DC -FilterHashtable #{Logname='Security';Keywords='9007199254740992';Data=$userid} -MaxEvents 1 | Select Message | Format-List
Which will return with a message similiar to this (Changed some info to generic info):
Message : The computer attempted to validate the credentials for an account.
Authentication Package: MICROSOFT_AUTHENTICATION_PACKAGE_V1_0
Logon Account: jdoe
Source Workstation: Generic-Computername
Error Code: 0x0
I am attempting to create an easy way to find a computer someone last logged into for faster troubleshooting but I am unable to filter out only the Source Workstation line, I could just not have the correct syntax for a good search to find the results I am looking for but I have been searching for about a week now and haven't found anything close to what I am looking for, any help would be great!
Im not sure what information you want to retrieve but im pretty sure there is a better way then using Get-WinEvent to obtain that information. However, if you just want to get the value of Source Workstation you can do that with a regex:
$event = Get-WinEvent `
-ComputerName $DC `
-FilterHashtable #{Logname='Security';Keywords='9007199254740992';Data=$userid} `
-MaxEvents 1 `
| Select -expand Message
[regex]::Match($event, 'Source Workstation:\s*(.*)\s*').Groups[1].Value

Powershell Write-EventLog / Get-WinEvent Message issues

The first command creates an entry in the event log, it seems to be working because I can see the message data in event viewer. The issue is when reading it back from powershell the message field is empty.
write-eventlog System -source 'Microsoft-Windows-Kernel-General' -eventid 999 -message 'Kernel something or other'
get-winevent -filterHashTable #{Logname = 'System'; ID = '999'}| select-object -first 10
Maybe this picture explains it better. Notice the message column is blank.
The event is being written correctly, to read it back use this:
get-winevent -filterHashTable #{Logname = 'System'; ID = '999'}|
select-object -first 10 | select timecreated,providername,
#{n="Message";e={$_.properties.Value}}
The reason you can't see it in the message column is evident when launching eventvwr:
The description for Event ID 999 from source Microsoft-Windows-Kernel-General cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.
If you want to write custom messages from custom sources use New-EventLog cmdlet, here is the Scripting Guy's tutorial: http://blogs.technet.com/b/heyscriptingguy/archive/2013/06/20/how-to-use-powershell-to-write-to-event-logs.aspx
Here is the snip that ended up making it work. Credit to Raf for the link where I found this answer.
$source = "Some Name"
If ([System.Diagnostics.EventLog]::SourceExists("$source") -eq $false)
{New-EventLog -LogName $log -Source "$source"}

Measure 'Idle' time between CTRL-ALT-DEL and user typing in password and loging on -Windows 7

Windows 7 has the built in 'Boot Performance Diagnostics' and judging by the numerous reboots i've done, it does generate every now and then a detailed log on the user's login process and possible slowness.
That is not good enough for what I'm after though.
I want to measure EVERY Boot on a given machine.
There is little information however available on how to force it, except fiddling with registry keys that are System Protected so you don't tamper with them.
Some of the information can be found in the eventlogs so i switched to tracing the eventid 12
$yesterday = (get-date) - (New-TimeSpan -day 2)
$startuplog= Get-WinEvent -FilterHashTable #{LogName='System'; ID=12;
StartTime=$yesterday} -ErrorAction SilentlyContinue
But does anyone know how one can measure when the system was ready (ctrl-alt-del) and when the user hit the enter button after typing in the password? Is there a flag that can be set to raise such an event in a (diagnostics) event log?
You can compare the power state timestamp to the "Last Interactive Logon" feature of AD DS. That feature requires a domain functional level (DFF) of Windows Server 2008 r2 to work and workstation infrastructure of windows vista or later. The "msDS-LastSuccessfulInteractiveLogonTime" attribute is what you want. It's the time stamp of the last successful interactive logon (ctrl+alt+del).
To enable Last Interactive Logon on your domain:
http://technet.microsoft.com/en-us/library/dd446680(v=ws.10).aspx
Command to query attribute:
$Computer = 'hostname'
Get-ADComputer -Filter "name -eq $Computer" -Properties * | Select msDS-LastSuccessfulInteractiveLogonTime
P.S. Try to get away from using "-ErrorAction". In it's place, use Try/Catch/Finally code blocks.
http://blogs.technet.com/b/heyscriptingguy/archive/2010/03/11/hey-scripting-guy-march-11-2010.aspx