尝试使用 Powershell 从 csv 导入信息但不幸的是有些结果是错误的

Trying to use Powershell to import information from a csv but unfortunately some of the results come out wrong

$AuditSuccess = Import-Csv -Path G:\LabLog.csv | Where-Object { $_.Keywords -like "Audit Success" } | Measure-Object | Select-Object count 

$AuditFailure = Import-Csv -Path G:\LabLog.csv | Where-Object { $_.Keywords -like "Audit Failure" } | Measure-Object | Select-Object count

$AuditTotal = $AuditSuccess + $AuditFailure

$EventID1 = Import-Csv -Path G:\LabLog.csv | sort | group Keywords | sort $_.EventID | select EventID -last 1

$EventID2 = Import-Csv -Path G:\LabLog.csv | sort | group Keywords | sort $_.EventID | select EventID -last 1


Write-Host "Number of Audit Failures:" $AuditFailure "failures of" $AuditTotal "entries"
Write-Host "Most Common Event ID:" $EventID1
Write-Host "Number of Audit Successes:" $AuditSuccess "successes of" $AuditTotal "entries"
Write-Host "Most Common Event ID:" $EventID2 

我对 Powershell 还很陌生,并试图将它用于作业我需要导入一个 csv 日志,然后从中提取特定信息,在这种情况下,所有日志中的失败和成功次数以及失败和成功中最常见的事件 ID。

代码的 AuditFailure 和 AuditSuccess 部分有些工作,但结果显示为 {count = ##} 而不是数字。真正的问题在于 AuditTotal 和 EventID,它们要么在总数的情况下不产生任何结果,要么在 EventID 的情况下给出空白的结果。

我不知道这些是否是用于此的最佳命令,并且愿意接受任何帮助来解决这个问题。

Method invocation failed because [System.Management.Automation.PSObject] does 
not contain a method named 'op_Addition'.
At line:5 char:1
+ $AuditTotal = $AuditSuccess + $AuditFailure
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], 
RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

Number of Audit Failures: @{Count=13} failures of  entries
Most Common Event ID: @{EventID=}
Number of Audit Successes: @{Count=6480} successes of  entries
Most Common Event ID: @{EventID=}

抱歉,这是错误输出

Number of Audit Failures: 2469 failures of 19247 entries                               
  Most common Event ID: 5038     
Number of Audit Successes: 16778 successes of 19247 entries                               
  Most common Event ID: 4624

这是它应该看起来的样子,尽管数字应该不同

最终有几个问题;让我们从主要的:

开始
$AuditTotal = $AuditSuccess + $AuditFailure

导致了 [System.Management.Automation.PSObject] does not contain a method named 'op_Addition' 错误,因为 $AuditSuccess$AuditFailure 的值是 自定义对象 ],而不是 数字 - 和 + 运算符 (转换为 op_Addition 方法)没有为 自定义对象操作数 [pscustomobject] 类型的操作数)定义。

要使用Select-Object提取单个属性,必须使用-ExpandProperty;例如:

$AuditSuccess = ... | Measure-Object | Select-Object -ExpandProperty Count

没有 -ExpandProperty有(隐含的)-Property 参数,你得到一个 [pscustomobject] 实例 ,它有一个 属性, .Count.


下一个问题是 sort $_.EventID 不会按预期工作,因为自动变量 $_ 在 [= 中只有一个(有意义的)值61=]脚本块;如果没有预定义的 $_ 值(不应该有任何值),$_.EventId 的计算结果为 $null 并且实际上被 忽略 .

虽然 Sort-Object EventId 通常是正确的解决方案(只需提供 属性 name),但在这种情况下,输入对象会 not 有一个 .EventId 属性,因为 group (Group-Object) 输出是 [Microsoft.PowerShell.Commands.GroupInfo] 个实例,每个实例代表一个 个原始输入对象。

根据您的意图在成功和失败中找到最常出现的事件 ID,命令必须重组如下,以成功为例:

$EventID1 = Import-Csv -Path G:\LabLog.csv | 
  Where-Object { $_.Keywords -like "Audit Success" } | 
    Group-Object EventID |
      Sort-Object Count -Descending |
        Select-Object -ExpandProperty Values -First 1

即输入的对象先按关键字过滤,然后按事件ID分组,再按每个事件ID组中的对象数排序,返回条目最多的组的事件ID .

最后:

  • 您的代码中有很多重复工作,最明显的是对同一个输入文件重复调用 Import-Csv,这会减慢它的速度。

  • Write-Host is generally the wrong tool to use,除非意图是明确地只写入显示器,绕过 PowerShell 的输出流。

$AuditSuccess = Import-Csv -Path G:\LabLog.csv | Where-Object { $_.Keywords -like "Audit Success" } | Measure-Object | Select-Object -ExpandProperty count 

$AuditFailure = Import-Csv -Path G:\LabLog.csv | Where-Object { $_.Keywords -like "Audit Failure" } | Measure-Object | Select-Object -ExpandProperty count

$AuditTotal = $AuditSuccess + $AuditFailure

$EventID1 = Import-Csv -Path G:\LabLog.csv | Where-Object { $_.Keywords -like "Audit Success" } | sort $_.EventID | Select-Object -ExpandProperty EventID -last 1

$EventID2 = Import-Csv -Path G:\LabLog.csv | Where-Object { $_.Keywords -like "Audit Failure" } | sort $_.EventID | Select-Object -ExpandProperty EventID -last 1


Write-Host "Number of Audit Failures:" $AuditFailure "failures of" $AuditTotal "entries"
Write-Host "Most Common Event ID:" $EventID1
Write-Host "Number of Audit Successes:" $AuditSuccess "successes of" $AuditTotal "entries"
Write-Host "Most Common Event ID:" $EventID2 

感谢您的帮助,这里是答案。

这是避免多次重新读取 CSV 文件的另一种方法。它还避免了如此频繁地通过管道 相当 发送内容。 [咧嘴一笑]

# fake reading in a CSV file
#    in real life, use Import-CSV
$InStuff = @'
EventID, Keywords
1001, Audit Success; SomeOtherWord
1001, Audit Success
2002, NothingRightNow
3003, Audit Failure
4004, Audit Success
5005, IgnoreThisOne
6006, Audit Success
7007, Audit Failure
7007, Audit Failure
'@ | ConvertFrom-Csv

$SuccessList = $InStuff.Where({$_.Keywords -match 'success'})
$SuccessCount = $SuccessList.Count
$SL_MostFrequentEventID = ($SuccessList |
    Group-Object -Property EventID |
    Sort-Object -Property Count)[-1].Name


$FailureList = $InStuff.Where({$_.Keywords -match 'failure'})
$FailureCount = $FailureList.Count
$FL_MostFrequentEventID = ($FailureList |
    Group-Object -Property EventID |
    Sort-Object -Property Count)[-1].Name

$FS_TotalCount = $FailureCount + $SuccessCount

Write-Host ''
Write-Host ('Number of Audit Failures {0} out of {1} entries.' -f $FailureCount, $FS_TotalCount)
Write-Host ('    Most Common Failure Event ID = {0}' -f $FL_MostFrequentEventID)
Write-Host ('Number of Audit Successes {0} out of {1} entries.' -f $SuccessCount, $FS_TotalCount)
Write-Host ('    Most Common Success Event ID = {0}' -f $SL_MostFrequentEventID)

输出...

Number of Audit Failures 3 out of 7 entries.
    Most Common Failure Event ID = 7007
Number of Audit Successes 4 out of 7 entries.
    Most Common Success Event ID = 1001