首页 > 解决方案 > 使用 Powershell 解析事件日志 (ID 4725) 和输出目标用户名字段时出现问题

问题描述

基本上,我正在尝试编写一些代码,这些代码将在任何时间触发事件 ID 4725 时从计划任务中运行。此特定事件表明特定用户已禁用其 AD 帐户 (Windows Server 2016)。

我需要做的是从此事件 ID 中获取用户名,并将其输出为变量 #UserName 以在 restmethod URI 中使用。

# Variables
$params = @{"action"="move";"destination"="/Shared/IT/Archived User Data/"}
$json = $params|ConvertTo-Json
$eventRecordId = 4725
$eventChannel = "Security"

# Gets the latest "disabled user account" event log and outputs the disabled user's name to a variable called $UserName


Get-EventLog –Log Security -InstanceId 4725 -Newest 1 | $UserName = ?{Group-Object -Property "TargetUserName"}

Echo $UserName 

# Calls the Egnyte API to move the disabled user's home folder to the archive folder
Invoke-RestMethod `
    -Method Post `
    -body $json `
    -Uri 'https://xxxxxx.egnyte.com/pubapi/v1/fs/private/"$UserName"' `
    -Headers @{Authorization = "Bearer xxxxxxxxxxxxxxxxxxxxxxx"
               Contenttype = "application/json"}

预期结果:从安全事件日志 ID 4725 中的 target-username 字段中获取用户名,将其输出到变量“#UserName”,然后将其输入到 rest-method API。

实际结果:未创建变量。

标签: windowsrestpowershellevent-logwindows-server

解决方案


OK 让我们看看这个 Event 4725 模板

(Get-WinEvent -ListProvider * -ErrorAction Ignore).Events |
        Where-Object {$_.Id -eq 4725} |
        select * | 
        Format-List

我们可以看到有一个 TargetUserName

<data name="TargetUserName" inType="win:UnicodeString" outType="xs:string"/>

因此,让我们将该 Message 解析为 XML, Get-EventLog返回一个类型System.Diagnostics.EventLogEntry

所以首先我们需要将该对象更改为System.Diagnostics.Eventing.Reader.EventLogRecord以便我们可以转换为XML

我们可以使用Get-WinEvent进行新调用,该调用将返回System.Diagnostics.Eventing.Reader.EventLogRecord类型,该类型具有将数据转换为 XML 的方法

或者我们可以从当前记录中获取索引并调用 Get-WinEvent 查找 EventRecordID。

下面是我编写的一个函数,它将解析消息字段并使用属性 ParsedMessage 创建一个新的 psobject

function Parse-WindowsEvents(){
    param(
        [Parameter(Position=1, ValueFromPipeline)]
        #[System.Diagnostics.Eventing.Reader.EventRecord[]]$Events
        [object[]]$Events
    )
    process{
        $ArrayList = New-Object System.Collections.ArrayList
        $Events  | %{
            $EventObj = $_
            $EventObjFullName = $_.GetType().FullName
            if($EventObjFullName -like "System.Diagnostics.EventLogEntry"){   
                $EventObj = Get-WinEvent -LogName security -FilterXPath "*[System[EventRecordID=$($_.get_Index())]]"
            }elseif($EventObjFullName -like "System.Diagnostics.Eventing.Reader.EventLogRecord"){

            }else{
                throw "Not An Event System.Diagnostics.Eventing.Reader.EventLogRecord or System.Diagnostics.EventLogEntry"
            }
            $PsObject =  New-Object psobject
            $EventObj.psobject.properties | %{
                $PsObject | Add-Member -MemberType NoteProperty -Name $_.Name -Value $_.Value
            }
            $XML = [xml]$EventObj.toXml()
            $PsObject2 = New-Object psobject
            $XML.Event.EventData.Data | %{
                $PsObject2 | Add-Member -MemberType NoteProperty -Name $_.Name -Value $_."#text"
            }
            $PsObject | Add-Member -MemberType NoteProperty -Name ParsedMessage -Value $PsObject2
            $ArrayList.add($PsObject) | out-null
        }
        return $ArrayList
    }
}

$Username = Get-EventLog –Log Security -InstanceId 4725 -Newest 1 | Parse-WindowsEvents | select -ExpandProperty ParsedMessage | select TargetUserName
$Username.TargetUserName
#or
$Username = (Get-EventLog –Log Security -InstanceId 4725 -Newest 1 | Parse-WindowsEvents | select -ExpandProperty ParsedMessage).TargetUserName
$Username

推荐阅读