无法在 PowerShell 中获取事件数据字段数据

Failed to get Event-Data Field Data in PowerShell

我正在尝试将特定数据字段 (FailureReason) 从事件 4625 获取到 CSV 字段。

我已经用下面的代码分析了事件模式:

(Get-WinEvent -ListProvider Microsoft-Windows-Security-Auditing).Events |
    Where-Object {$_.Id -eq 4625}

这导致:

Id          : 4625
Version     : 0
LogLink     : System.Diagnostics.Eventing.Reader.EventLogLink
Level       : System.Diagnostics.Eventing.Reader.EventLevel
Opcode      : System.Diagnostics.Eventing.Reader.EventOpcode
Task        : System.Diagnostics.Eventing.Reader.EventTask
Keywords    : {}
Template    : <template xmlns="http://schemas.microsoft.com/win/2004/08/events">
                <data name="SubjectUserSid" inType="win:SID" outType="xs:string"/>
                <data name="SubjectUserName" inType="win:UnicodeString" outType="xs:string"/>
                <data name="SubjectDomainName" inType="win:UnicodeString" outType="xs:string"/>
                <data name="SubjectLogonId" inType="win:HexInt64" outType="win:HexInt64"/>
                <data name="TargetUserSid" inType="win:SID" outType="xs:string"/>
                <data name="TargetUserName" inType="win:UnicodeString" outType="xs:string"/>
                <data name="TargetDomainName" inType="win:UnicodeString" outType="xs:string"/>
                <data name="Status" inType="win:HexInt32" outType="win:HexInt32"/>
                <data name="FailureReason" inType="win:UnicodeString" outType="xs:string"/>
                <data name="SubStatus" inType="win:HexInt32" outType="win:HexInt32"/>
                <data name="LogonType" inType="win:UInt32" outType="xs:unsignedInt"/>
                <data name="LogonProcessName" inType="win:UnicodeString" outType="xs:string"/>
                <data name="AuthenticationPackageName" inType="win:UnicodeString" outType="xs:string"/>
                <data name="WorkstationName" inType="win:UnicodeString" outType="xs:string"/>
                <data name="TransmittedServices" inType="win:UnicodeString" outType="xs:string"/>
                <data name="LmPackageName" inType="win:UnicodeString" outType="xs:string"/>
                <data name="KeyLength" inType="win:UInt32" outType="xs:unsignedInt"/>
                <data name="ProcessId" inType="win:Pointer" outType="win:HexInt64"/>
                <data name="ProcessName" inType="win:UnicodeString" outType="xs:string"/>
                <data name="IpAddress" inType="win:UnicodeString" outType="xs:string"/>
                <data name="IpPort" inType="win:UnicodeString" outType="xs:string"/>
              </template>

Description : Fehler beim Anmelden eines Kontos.

              Antragsteller:
                Sicherheits-ID:     %1
                Kontoname:      %2
                Kontodomäne:        %3
                Anmelde-ID:     %4

              Anmeldetyp:           %11

              Konto, für das die Anmeldung fehlgeschlagen ist:
                Sicherheits-ID:     %5
                Kontoname:      %6
                Kontodomäne:        %7

              Fehlerinformationen:
                Fehlerursache:      %9
                Status:         %8
                Unterstatus::       %10

              Prozessinformationen:
                Aufrufprozess-ID:   %18
                Aufrufprozessname:  %19

              Netzwerkinformationen:
                Arbeitsstationsname:    %14
                Quellnetzwerkadresse:   %20
                Quellport:      %21

              Detaillierte Authentifizierungsinformationen:
                Anmeldeprozess:     %12
                Authentifizierungspaket:    %13
                Übertragene Dienste:    %15
                Paketname (nur NTLM):   %16
                Schlüssellänge:     %17

通过此输出,我知道数据字段名称是 "FailureReason" 或 $_.properties[9]。我在以下代码片段中尝试了两种变体:

Get-WinEvent -FilterHashtable @{Path="c:\temp\test.evtx";} -ErrorAction SilentlyContinue |
    # which are the interesting Events in the Eventlog?
    Where-Object {($_.id -eq "4625")} |
    ForEach-Object {
        if ($_.Id -eq  4625) {
            # which extended Fields from the Eventlog are needed for further investigations?
            # example: how does the eventlog schema looks like?
            # can be examined with (Get-WinEvent -ListProvider Microsoft-Windows-Security-Auditing).Events | Where-Object {$_.Id -eq 4625}
            $SelectorStrings = [string[]]@(
                'Event/EventData/Data[@Name="TargetUserName"]',
                'Event/EventData/Data[@Name="TargetDomainName"]',
                'Event/EventData/Data[@Name="WorkstationName"]',
                'Event/EventData/Data[@Name="IpAddress"]',
                'Event/EventData/Data[@Name="IpPort"]',
                'Event/EventData/Data[@Name="LogonType"]',
                'Event/EventData/Data[@Name="FailureReason"]'
            )
            $PropertySelector = [System.Diagnostics.Eventing.Reader.EventLogPropertySelector]::new($SelectorStrings)

            $TargetUserName, $TargetDomainName, $WorkstationName, $IpAddress, $IpPort, $LogonType, $Remark, $FailureReason = $_.GetPropertyValues($PropertySelector)
            $Remark ="Failed Login !"
            #Create the PSCustomObject from the given Fieldnames
            [PSCustomObject]@{
                TimeCreated   = $_.TimeCreated
                UserName      = $TargetUserName
                Domain        = $TargetDomainName
                ComputerName  = $WorkstationName
                IPAddress     = $IpAddress
                Port          = $IpPort
                LogonType     = $LogonType
                Remark        = $Remark
                FailureReason = $FailureReason
                Message       = ($_.Message).Split(".")[0]
                #Export everything to CSV-File
            } | Export-Csv -NoTypeInformation -Force -Encoding UTF8 -Path 'c:\temp\failedlogin.csv' -Append
        }
    }

因此,CSV 文件中的所有字段都已填写,字段 "FailureReason" 除外。之后我更改了代码以获取具有相同结果的字段 "ProcessId" 的值,然后 CSV 字段也为空。

备注:代码通常比较复杂,我将其简化为所需部分。

您使用 $SelectorStrings 过滤了 7 个属性,但随后尝试填充 8 个变量。我认为您需要从此行中删除 $remark

$TargetUserName, $TargetDomainName, $WorkstationName, $IpAddress, $IpPort, $LogonType, $Remark, $FailureReason = $_.GetPropertyValues($PropertySelector)

应该是:

$TargetUserName, $TargetDomainName, $WorkstationName, $IpAddress, $IpPort, $LogonType, $FailureReason = $_.GetPropertyValues($PropertySelector)

我认为 FailureReason 值进入了 $Remark 变量,然后您立即在它后面的行中替换了它。

此外,如果您将 | Export-CSV.. 部分移动到 ForEach-Object 的结束 } 之后,那么您可以取消使用 -Append