Invoke Get-WinEvent without parameters

You may be used to invoke cmdlets without parameters and get a nice default end-user experience. However, you may be surprised by the default behavior of the Get-WinEvent cmdlet. In a Windows PowerShell 5.1 console, you may encounter the following error:

Get-WinEvent : The data is invalid
At line:1 char:1
+ Get-WinEvent
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WinEvent], EventLogInvalidDataException
+ FullyQualifiedErrorId : The data is invalid,Microsoft.PowerShell.Commands.GetWinEventCommand

This issue has already been reported a long time ago on uservoice.

Let’s try to find out what happens behind the scene, when you invoke the Get-WinEvent cmdlet without parameters.

The default parameter set is named GetLogSet and has the following parameters:

# Get the name of the default parameter set
Get-Command Get-WinEvent | Select DefaultParameterSet

# What are its parameters
(Get-Command Get-WinEvent).ParameterSets | 
Where isDefault | 
Select -ExpandProperty Parameters | Out-GridView


Notice that none of them is mandatory.

What kind of error is this?

$Error[0].Exception.GetType().Fullname
$Error[0] | Select -Property *

We actually get an error that has the following fully qualified name System.Diagnostics.Eventing.Reader.EventLogInvalidDataException


If you invoke the Get-WinEvent cmdlet with one of the common parameters, the Debug switch, you get the following:

Get-WinEvent -Debug

An xml query is created with 434 log names (the index starts at 0).

Let’s extract this xml query.
If you remember my post about how to Make Get-WinEvent cmdlet perform quicker, you know that the XML query also appears in the Verbose stream.
By merging the output and verbose stream and removing the ending dot and the first line, I can capture the xml query in a variable named q.

# oneliner
$q = ((( $(try {Get-WinEvent -Verbose -ErrorAction Stop 4>&1} catch {}).Message) -split "`n")[1]) -replace '\.',''

# same oneliner split on multiple lines for a better readability
$q = (
 (
  (
   $(
   try {
    Get-WinEvent -Verbose -ErrorAction Stop 4>&1
   } catch {}
   ).Message
  ) -split "`n"
 )[1]
) -replace '\.',''

[xml]$q

The captured xml query is valid because casting it to the XML type alias or accelerator (for [System.Xml.XmlDocument]) doesn’t throw an error.

By using a dichotomic approach, it’s possible to find out when the error occurs.

# There are 434 Query nodes in this XML query
([xml]$q).QueryList.Query | Measure
# A query with 257 Paths fails
Get-WinEvent -FilterXml (
[xml](
'<QueryList><Query>{0}</Query></QueryList>' -f "$(
(
Select-Xml -Xml ([xml]$q) -XPath '//Query' |
Select -First 257
).Node.InnerXML
)"
)
)
# A query with 256 Paths succeeds
Get-WinEvent -FilterXml ([xml]('<QueryList><Query>{0}</Query></QueryList>'-f "$((Select-Xml -Xml ([xml]$q) -XPath '//Query' | Select -First 256).Node.InnerXML)"))

It appears that the number of Paths is the culprit. You can have a single Query node with a huge number of Paths or a huge number of Query nodes with a Path, it doesn’t make a difference. In both cases having more than 256 Paths will produce this undesirable behavior.


You get actually the same error if you do the following

Get-WinEvent -LogName *
# Use the Debug switch to uncover the XML query:
Get-WinEvent -LogName * -Debug


The LogName is the non-mandatory parameter that belongs to the default parameter set named GetLogSet. It has the same behavior as invoking the Get-WinEvent cmdlet without parameters.

I haven’t seen many blog posts about this error and the following shed some lights on the 256 Paths limit:
http://www.powershellish.com/blog/2015-01-19-get-winevent-max-logs
Nice work Craig 🙂

5 thoughts on “Invoke Get-WinEvent without parameters

  1. I confess I didn’t go into depth but do I get it right that if one would limit the parameters to be returned to the ones of interest this would reduce/eliminate the given error?

    • The problem is not the parameters, it’s the 256 Paths limit.
      If they set the limit to 4096, we would not get this error.
      If they cannot raise the limit, they should limit the Paths to the 256 limit or throw a more specific error saying that this limit has been reached.

      • Doh 🙂
        So in other words enabling the GPO “Local Computer Policy > Computer Configuration > Administrative Templates > System > Filesystem > Enable Win32 long paths” should do the trick then?
        Would be at least a way for bigger environments.

      • It’s not a NTFS filesystem limit. Here it’s about the number of eventlog names. The XML query built references these with a Path property.

  2. Pingback: Dew Drop – December 30, 2019 (#3101) | Morning Dew

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.