Ori*_*ami 1 powershell export-csv
这是 PowerShell 的后续问题| EVTX | 将消息与数组进行比较(例如)
\n我稍微改变了策略,现在我正在收集所有已安装的服务,
\n$7045 = Get-WinEvent -FilterHashtable @{ Path="1system.evtx"; Id = 7045 } | select \n@{N=\xe2\x80\x99Timestamp\xe2\x80\x99; E={$_.TimeCreated.ToUniversalTime().ToString(\'yyyy-MM-ddTHH:mm:ssZ\')}},\nId, \n@{N=\xe2\x80\x99Machine Name\xe2\x80\x99; E={$_.MachineName}},\n@{N=\xe2\x80\x99Service Name\xe2\x80\x99; E={$_.Properties[0].Value}},@{N=\xe2\x80\x99Image Path\xe2\x80\x99;E=$_.Properties[1].Value}},\n@{N=\xe2\x80\x99RunAsUser\xe2\x80\x99; E={$_.Properties[4].Value}},@{N=\xe2\x80\x99Installed By\xe2\x80\x99; E={$_.UserId}}\nRun Code Online (Sandbox Code Playgroud)\n现在,我匹配每个对象的任何可疑特征,如果找到,我会添加一个值为“是”的“可疑”列。这是因为我想将决定权留给分析师,并且非常确定坏人可能会使用我们以前从未见过的东西。
\nforeach ($Evt in $7045)\n{\nif ($Evt.\'Image Path\' -match $sus)\n {\n\n $Evt | Add-Member -MemberType NoteProperty -Name \'Suspicious\' -Value \'Yes\'\n\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n现在,我无法让 PowerShell 显示所有列,除非我特别指定Select它们
$7045 | Format-Table\nRun Code Online (Sandbox Code Playgroud)\nCSV 导出也是如此。前两个不包括Suspicious列,但第三个包括,但那是因为我明确要求它这样做。
$7045 | select * | Export-Csv -Path test.csv -NoTypeInformation\n$7045 | Export-Csv -Path test.csv -NoTypeInformation\n$7045 | Select-Object Timestamp, Id, \'Machine Name\', \'Service Name\', \'Image Path\', \'RunAsUser\', \'Installed By\', Suspicious | Export-Csv -Path test.csv -NoTypeInformation\nRun Code Online (Sandbox Code Playgroud)\n我阅读了 MS 上的 Export-CSV 文档。在 StackOverFlow 中搜索了一些提示,我认为这与 PS 检查第一行然后比较第二行的属性是否存在有关,依此类推。\n谢谢
\n您遇到的问题部分是由于对象如何显示到控制台,第一个对象的属性决定了所有对象的显示属性(列) 。
但更大的问题是,Export-Csv不会导出那些与第一个对象的属性不匹配的属性,除非将它们显式添加到其余对象或重建对象,实现此目的的一种简单方法是使用Select-Object您所指出的在问题中。
给出以下示例:
$test = @(
[pscustomobject]@{
A = 'ValA'
}
[pscustomobject]@{
A = 'ValA'
B = 'ValB'
}
[pscustomobject]@{
C = 'ValC'
D = 'ValD'
E = 'ValE'
}
)
Run Code Online (Sandbox Code Playgroud)
Format-Table将不会显示属性B 到 E:$test | Format-Table
A
-
ValA
ValA
Run Code Online (Sandbox Code Playgroud)
Format-List可以正确显示对象,这是因为每个属性及其对应的值在显示中都有自己的控制台行:PS /> $test | Format-List
A : ValA
A : ValA
B : ValB
C : ValC
D : ValD
E : ValE
Run Code Online (Sandbox Code Playgroud)
Export-Csv并且ConvertTo-Csv还会错过属性B 到 E:$test | ConvertTo-Csv
"A"
"ValA"
"ValA"
Run Code Online (Sandbox Code Playgroud)
您可以选择不同的解决方法来解决此问题,您可以将该Suspicious属性添加到所有对象,对于那些不可疑的事件,您可以添加$null为Value。
另一种解决方法是使用Select-Object显式调用该Suspicious属性(这是有效的,因为您知道该属性在那里并且您知道它的Name)。
如果您不知道对象有多少属性,解决此问题的动态方法是使用PSObject内部成员发现它们的属性。
using namespace System.Collections.Generic
function ConvertTo-NormalizedObject {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline, Mandatory)]
[object[]] $InputObject
)
begin {
$list = [List[object]]::new()
$props = [HashSet[string]]::new([StringComparer]::InvariantCultureIgnoreCase)
}
process {
foreach($object in $InputObject) {
$list.Add($object)
foreach($property in $object.PSObject.Properties) {
$null = $props.Add($property.Name)
}
}
}
end {
$out = [ordered]@{}
foreach ($object in $list) {
foreach ($prop in $props) {
$out[$prop] = $object.$prop
}
[pscustomobject] $out
$out.Clear()
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
# From Pipeline
$test | ConvertTo-NormalizedObject | Format-Table
# From Positional / Named parameter binding
ConvertTo-NormalizedObject $test | Format-Table
Run Code Online (Sandbox Code Playgroud)
Select-Object -Unique:$prop = $test.ForEach{ $_.PSObject.Properties.Name } | Select-Object -Unique
$test | Select-Object $prop
Run Code Online (Sandbox Code Playgroud)
使用$test此示例,结果将变为:
A B C D E
- - - - -
ValA
ValA ValB
ValC ValD ValE
Run Code Online (Sandbox Code Playgroud)