powershell 将Get-Content作为变量传递时Where-Object错误

dgtucam1  于 2023-02-19  发布在  Shell
关注(0)|答案(1)|浏览(226)

首先,我的PS知识是非常基础的,所以要提前知道。
我正在编写一个基本的脚本来搜索存档的.evtx文件中的EventID并清除“reports”。Where-Object查询位于.txt文件中,存储在.\AuditEvents\文件夹中。我正在尝试对.txt文件执行ForEach,并将每个查询传递给Get-WinEvent。
下面是查询在.txt文件中的显示方式示例:{($_.ID -eq "11")}
该脚本为:

$ae = Get-ChildItem .\AuditEvents\

ForEach ($f in $ae) {
    $qs = Get-Content -Path .\AuditEvents\$f
    Get-WinEvent -Path .\AuditReview\*.evtx -MaxEvents 500 | Select-Object TimeCreated, ID, LogName, MachineName, ProviderName, LevelDisplayName, Message | Where-Object $qs | Out-GridView -Title $f.Name
    }

这是错误:

Where-Object : Cannot bind argument to parameter 'FilterScript' because it is null.
At C:\Users\######\Desktop\PSAuditReduction\PSAuditReduction.ps1:6 char:177
+ ... e, ProviderName, LevelDisplayName, Message | Where-Object $qs | Out-G ...
+                                                               ~~~
    + CategoryInfo          : InvalidData: (:) [Where-Object], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.WhereObjectCommand
zz2j4svz

zz2j4svz1#

您的症状暗示$qs$null,这反过来又暗示文件.\AuditEvents\$f是空的。
但是,即使它有内容,也不能将结果 * string * 原样传递给Where-Object-FilterScript参数(位置隐含),script block需要一个script block{ ... })。
必须使用[scriptblock]::Create()显式地从字符串创建脚本块。
一个简单的例子:

# Simulated input using a literal string instead of file input via Get-Content
$qs = '{ 0 -eq $_ % 2 }'  # Sample filter: return $true for even numbers.

# Remove the enclosing { and }, as they are NOT part of the code itself 
# (they are only needed to define script-block *literals* in source code).
# NOTE: If you control the query files, you can simplify them
#       by omitting { and } to begin with, which makes this 
#       -replace operation unnecessary. 
$qs = $qs.Trim() -replace '^\{(.+)\}$', '$1'

# Construct a script block from the string and pass it to Where-Object
1..4 | Where-Object ([scriptblock]::Create($qs)) # -> 2, 4

注:

  • 您的代码假定每个.\AuditEvents\$f文件只包含 * 一 * 行,并且该行包含适合使用Where-Object筛选器的有效PowerShell源代码。
  • 通常,确保只从您信任的源加载您将 * 作为代码执行 * 的字符串。

退一步说:
正如Abraham Zinala所指出的,过滤事件日志条目的一种更快的方法是使用Get-WinEvent-FilterHashtable参数。
这允许您在查询文件中保存hastable常量,您可以使用Import-PowerShellDataFile将其直接读入哈希表:

# Create a file with a sample filter.
'@{Path=".\AuditEvents\.*evtx";ID=11}' > sample.txt

# Read the file into a hashtable...
$hash = Import-PowerShellDataFile sample.txt

# ... and pass it to Get-WinEvent
Get-WinEvent -MaxEvents 500 -FilterHashtable $hash | ...

相关问题