mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Fix Get-WinEvent -FilterHashtable to work with named event data field (#2373)
Fix Get-WinEvent -FilterHashtable to work with named event data field
Now FilterHashtable parameter in Get-WinEvent for named data field:
1. generates a valid query, ex. @{Logname="System";Param="a"}
2. generates a valid query for multiple values, ex.
@{Logname="System";Param="a","b"}
Also removed double cast in the original code and added more tests to cover the fixed scenarios.
This commit is contained in:
@@ -360,6 +360,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
private const string propOpen = "[";
|
||||
private const string propClose = "]";
|
||||
private const string filePrefix = "file://";
|
||||
private const string NamedDataTemplate = "((EventData[Data[@Name='{0}']='{1}']) or (UserData/*/{0}='{1}'))";
|
||||
|
||||
//
|
||||
// Other private members and constants
|
||||
@@ -1240,12 +1241,16 @@ namespace Microsoft.PowerShell.Commands
|
||||
default:
|
||||
{
|
||||
//
|
||||
// None of the recognized values: this must be a named payload field
|
||||
// None of the recognized values: this must be a named event data field
|
||||
//
|
||||
ExtendPredicate(ref xpathString);
|
||||
xpathString += string.Format(CultureInfo.InvariantCulture,
|
||||
"([EventData[Data[@Name='{0}']='{1}']] or [UserData/*/{0}='{1}'])",
|
||||
key, hash[key]);
|
||||
// Fix Issue #2327
|
||||
added = HandleNamedDataHashValue(key, hash[key]);
|
||||
if (added.Length > 0)
|
||||
{
|
||||
ExtendPredicate(ref xpathString);
|
||||
xpathString += added;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1299,9 +1304,9 @@ namespace Microsoft.PowerShell.Commands
|
||||
private string HandleEventIdHashValue(Object value)
|
||||
{
|
||||
string ret = "";
|
||||
if (value is Array)
|
||||
Array idsArray = value as Array;
|
||||
if (idsArray != null)
|
||||
{
|
||||
Array idsArray = (Array)(value);
|
||||
ret += "(";
|
||||
for (int i = 0; i < idsArray.Length; i++)
|
||||
{
|
||||
@@ -1328,10 +1333,9 @@ namespace Microsoft.PowerShell.Commands
|
||||
private string HandleLevelHashValue(Object value)
|
||||
{
|
||||
string ret = "";
|
||||
|
||||
if (value is Array)
|
||||
Array levelsArray = value as Array;
|
||||
if (levelsArray != null)
|
||||
{
|
||||
Array levelsArray = (Array)(value);
|
||||
ret += "(";
|
||||
for (int i = 0; i < levelsArray.Length; i++)
|
||||
{
|
||||
@@ -1360,9 +1364,10 @@ namespace Microsoft.PowerShell.Commands
|
||||
Int64 keywordsMask = 0;
|
||||
Int64 keywordLong = 0;
|
||||
|
||||
if (value is Array)
|
||||
Array keywordArray = value as Array;
|
||||
if (keywordArray != null)
|
||||
{
|
||||
foreach (Object keyword in (Array)value)
|
||||
foreach (Object keyword in keywordArray)
|
||||
{
|
||||
if (KeywordStringToInt64(keyword.ToString(), ref keywordLong))
|
||||
{
|
||||
@@ -1514,9 +1519,9 @@ namespace Microsoft.PowerShell.Commands
|
||||
private string HandleDataHashValue(Object value)
|
||||
{
|
||||
string ret = "";
|
||||
if (value is Array)
|
||||
Array dataArray = value as Array;
|
||||
if (dataArray != null)
|
||||
{
|
||||
Array dataArray = (Array)(value);
|
||||
ret += "(";
|
||||
for (int i = 0; i < dataArray.Length; i++)
|
||||
{
|
||||
@@ -1537,6 +1542,41 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HandleNamedDataHashValue helper for hashtable structured query builder.
|
||||
// Constructs and returns named event data field XPath portion as a string.
|
||||
// Fix Issue #2327
|
||||
//
|
||||
private string HandleNamedDataHashValue(String key, Object value)
|
||||
{
|
||||
string ret = "";
|
||||
Array dataArray = value as Array;
|
||||
if (dataArray != null)
|
||||
{
|
||||
ret += "(";
|
||||
for (int i = 0; i < dataArray.Length; i++)
|
||||
{
|
||||
ret += string.Format(CultureInfo.InvariantCulture,
|
||||
NamedDataTemplate,
|
||||
key, dataArray.GetValue(i).ToString());
|
||||
if (i < (dataArray.Length - 1))
|
||||
{
|
||||
ret += " or ";
|
||||
}
|
||||
}
|
||||
ret += ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += string.Format(CultureInfo.InvariantCulture,
|
||||
NamedDataTemplate,
|
||||
key, value);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Helper checking whether at least one of log, _path, provider is specified.
|
||||
// It will ThrowTerminatingError in case none of those keys are present.
|
||||
@@ -1766,15 +1806,19 @@ namespace Microsoft.PowerShell.Commands
|
||||
Exception exc = new Exception(string.Format(CultureInfo.InvariantCulture, msg, key));
|
||||
ThrowTerminatingError(new ErrorRecord(exc, "NullNotAllowedInHashtable", ErrorCategory.InvalidArgument, key));
|
||||
}
|
||||
else if (value is Array)
|
||||
else
|
||||
{
|
||||
foreach (Object elt in (Array)value)
|
||||
Array eltArray = value as Array;
|
||||
if (eltArray != null)
|
||||
{
|
||||
if (elt == null)
|
||||
foreach (Object elt in eltArray)
|
||||
{
|
||||
string msg = _resourceMgr.GetString("NullNotAllowedInHashtable");
|
||||
Exception exc = new Exception(string.Format(CultureInfo.InvariantCulture, msg, key));
|
||||
ThrowTerminatingError(new ErrorRecord(exc, "NullNotAllowedInHashtable", ErrorCategory.InvalidArgument, key));
|
||||
if (elt == null)
|
||||
{
|
||||
string msg = _resourceMgr.GetString("NullNotAllowedInHashtable");
|
||||
Exception exc = new Exception(string.Format(CultureInfo.InvariantCulture, msg, key));
|
||||
ThrowTerminatingError(new ErrorRecord(exc, "NullNotAllowedInHashtable", ErrorCategory.InvalidArgument, key));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,8 +85,7 @@ Describe 'Get-WinEvent' -Tags "CI" {
|
||||
@($results).Count | Should be 1
|
||||
$results.RecordId | should be 10
|
||||
}
|
||||
<#
|
||||
It 'Get-WinEvent can retrieve events with UserData queries using FilterHashtable' {
|
||||
It 'Get-WinEvent can retrieve events with UserData queries using FilterHashtable (one value)' {
|
||||
# this relies on apriori knowledge about the log file
|
||||
# the provided log file has been edited to remove MS PII, so we must use -ea silentlycontinue
|
||||
$eventLogFile = [io.path]::Combine($PSScriptRoot, "assets", "Saved-Events.evtx")
|
||||
@@ -95,7 +94,26 @@ Describe 'Get-WinEvent' -Tags "CI" {
|
||||
@($results).Count | Should be 1
|
||||
$results.RecordId | should be 10
|
||||
}
|
||||
#>
|
||||
It 'Get-WinEvent can retrieve events with UserData queries using FilterHashtable (array of values)' {
|
||||
# this relies on apriori knowledge about the log file
|
||||
# the provided log file has been edited to remove MS PII, so we must use -ea silentlycontinue
|
||||
$eventLogFile = [io.path]::Combine($PSScriptRoot, "assets", "Saved-Events.evtx")
|
||||
$filter = @{ path = "$eventLogFile"; DriverName = "Remote Desktop Easy Print", "Microsoft enhanced Point and Print compatibility driver" }
|
||||
$results = Get-WinEvent -filterHashtable $filter -ea silentlycontinue
|
||||
@($results).Count | Should be 2
|
||||
($results.RecordId -contains 9) | should be $true
|
||||
($results.RecordId -contains 11) | should be $true
|
||||
}
|
||||
It 'Get-WinEvent can retrieve events with UserData queries using FilterHashtable (multiple named params)' {
|
||||
# this relies on apriori knowledge about the log file
|
||||
# the provided log file has been edited to remove MS PII, so we must use -ea silentlycontinue
|
||||
$eventLogFile = [io.path]::Combine($PSScriptRoot, "assets", "Saved-Events.evtx")
|
||||
$filter = @{ path = "$eventLogFile"; PackageAware="Not package aware"; DriverName = "Remote Desktop Easy Print", "Microsoft enhanced Point and Print compatibility driver" }
|
||||
$results = Get-WinEvent -filterHashtable $filter -ea silentlycontinue
|
||||
@($results).Count | Should be 2
|
||||
($results.RecordId -contains 9) | should be $true
|
||||
($results.RecordId -contains 11) | should be $true
|
||||
}
|
||||
It 'Get-WinEvent can retrieve events with UserData queries using FilterXPath' {
|
||||
# this relies on apriori knowledge about the log file
|
||||
# the provided log file has been edited to remove MS PII, so we must use -ea silentlycontinue
|
||||
|
||||
Reference in New Issue
Block a user