【问题标题】:How to store an object in the Windows Event Log?如何在 Windows 事件日志中存储对象?
【发布时间】:2019-12-31 00:36:17
【问题描述】:

最近,我们为所有脚本添加了选项,以便在 Windows 事件日志中记录它们的消息。这对短消息很有用,但我们似乎无法找到以结构化方式保存事件的方法,以便我们以后可以使用它们创建对象。

可以存储多个对象属性的事件示例:

这是如何使用 PowerShell 完成的?

我们已经按照here 的描述尝试了以下方法,但没有成功:

Write-EventLog -LogName HCScripts -Source 'Test (Brecht)' -EventId 4 -Message "<Data Name=""MyKey1"">MyValue1</Data>"

this post 中描述了其他选项,但我们似乎无法弄清楚如何正确执行。

通过以下方式读取事件:

Function Get-WinEventDataHC {
    Param (
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [System.Diagnostics.Eventing.Reader.EventLogRecord[]]$Event
    )

    Process {
        foreach ($E in $Event){
            $XML = [XML]$E.ToXml()

            # Some events use other nodes, like 'UserData' on Applocker events...
            $XMLData = $null
            if ($XMLData = @($XML.Event.EventData.Data)){
                For ($i=0; $i -lt $XMLData.count; $i++){
                    $Params = @{
                        InputObject       = $E
                        NotePropertyName  = $EventXML.Event.EventData.Data[$i].Name
                        NotePropertyValue = $EventXML.Event.EventData.Data[$i].’#text’
                    }
                    Add-Member @Params
                }
            }

            $E
        }
    }
}
Get-WinEvent -ProviderName 'Test (Brecht)' | Select-Object -First 1 | Get-WinEventDataHC | fl *

感谢您的帮助。

【问题讨论】:

  • 假设问题可能是您所做的与定义的架构不匹配?它必须是您存储的 XML 吗?您也可以在其中轻松处理 JSON 或其他一些基于文本的对象结构。我不太了解 XML,但也许你可以让它忽略模式?也许这与它无关,在这种情况下,我的错。
  • 它不一定是 XML,但它是 Windows 事件日志使用的标准。我们是否选择使用其他东西,可能是消息未正确显示在 GUI 中。 XML 通常仅在事件的 XML 详细信息窗格中可见。

标签: powershell events logging


【解决方案1】:

我找到了两种可能的解决方案来解决“如何使用 PowerShell?”这个问题。第一个涉及自定义 PowerShell 方法并利用系统程序集写入事件日志。第二个涉及实现自定义提供程序。应该注意,这不会将 XML 存储在 &lt;Data&gt; 节点中。它将数据存储在独立的元素中。

方法一:自定义PowerShell函数

这个方法来自Kevin Holman写的一篇文章他的解释很出色。我在这里复制了代码,所以这里的答案将是完整的。

  1. 定义您也想记录的事件日志和源,加载System.Diagnostics.EventLog 程序集,最后创建一个函数CreateParamEvent,它将使用特定参数写入事件日志。

    #Define the event log and your custom event source
    $evtlog = "Application"
    $source = "MyEventSource"
    
    #Load the event source to the log if not already loaded.  This will fail if the event source is already assigned to a different log.
    if ([System.Diagnostics.EventLog]::SourceExists($source) -eq $false) {
        [System.Diagnostics.EventLog]::CreateEventSource($source, $evtlog)
    }
    
    #function to create the events with parameters
    function CreateParamEvent ($evtID, $param1, $param2, $param3)
      {
        $id = New-Object System.Diagnostics.EventInstance($evtID,1); #INFORMATION EVENT
        #$id = New-Object System.Diagnostics.EventInstance($evtID,1,2); #WARNING EVENT
        #$id = New-Object System.Diagnostics.EventInstance($evtID,1,1); #ERROR EVENT
        $evtObject = New-Object System.Diagnostics.EventLog;
        $evtObject.Log = $evtlog;
        $evtObject.Source = $source;
        $evtObject.WriteEvent($id, @($param1,$param2,$param3))
      }
    
  2. 下一步是设置您想要写入日志的参数并调用函数。

    #These are just examples to pass as parameters to the event
    $hostname = "computername.domain.net"
    $timestamp = (get-date)
    
    #Command line to call the function and pass whatever you like
    CreateParamEvent 1234 "The server $hostname was logged at $timestamp" $hostname $timestamp 
    

方法二:自定义事件提供者

此方法来自Daniel Gordon 撰写的一篇文章我已经降低了他示例的一些复杂性,并在此GitHub Repository 中提供了源代码和说明

  1. 您需要提供的关键数据是事件提供者清单。此清单包含新事件提供程序的详细信息。而且,最重要的是,事件的自定义有效负载。此文件中的关键元素是&lt;templates&gt; 元素。它定义了最终会在您的事件负载中变成&lt;Data&gt; 元素的字段。
    <?xml version="1.0" encoding="UTF-8"?>
    <instrumentationManifest xsi:schemaLocation="http://schemas.microsoft.com/win/2004/08/events eventman.xsd"
        xmlns="http://schemas.microsoft.com/win/2004/08/events"
        xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xs="http://www.w3.org/2001/XMLSchema" 
         xmlns:trace="http://schemas.microsoft.com/win/2004/08/events/trace">
        <instrumentation>
            <events>
                <provider name="CustomProvider"
                     symbol="CustomProvider"
                     guid="{10ABB82A-BB5A-45FF-A7D6-D7369B235DD8}"
                     resourceFileName="C:\CustomProvider\CustomProvider.dll"
                     messageFileName="C:\CustomProvider\CustomProvider.dll">  
                    <events>
                        <event symbol="CustomEvent" value="10000" version="1" channel="CustomProvider/Log" template="CustomTemplate" />
                    </events>
                    <levels/>
                    <tasks/>
                    <opcodes/>
                    <channels>
                        <channel name="CustomProvider/Log" value="0x10" type="Operational" enabled="true" />
                    </channels>
                    <templates>
                        <template tid="CustomTemplate">
                            <data name="MyKey1" inType="win:UnicodeString" outType="xs:string" />
                        </template>
                    </templates>
                </provider>
            </events>
        </instrumentation>
        <localization/>
     </instrumentationManifest>
  1. 创建清单后,我们需要在计算机上编译和安装 Provider。我在C:\CustomProvider\ 中将我的清单保存为CustomProvider.man。如果您不遵循此约定,则必须更新 CustomProvider.man 中的路径。保存后,以 Administrator 身份打开 Visual Studio 命令提示符并 cd 到 C:\CustomProvider

  1. 通过执行编译清单:mc -css Namespace CustomProvider.man

  1. 通过执行创建资源文件:rc CustomProvider.rc

  1. 编译源码:csc /target:library /unsafe /win32res:CustomProvider.res CustomProvider.cs

  1. 通过执行注册提供程序。 wevtutil im CustomProvider.man

  1. 您现在将在 Windows 事件查看器中看到自定义提供程序

  2. 要写入日志,请打开 Windows Powershell 提示符并执行

    New-WinEvent -ProviderName CustomProvider -Id 10000 -Payload @("MyValue1") 
    

    然后刷新事件日志,您将看到该事件。

【讨论】:

  • 感谢详细解释。当试图远离 Visio 时,我尝试了方法 1。这很好用,但似乎无法将属性名称与属性值一起存储。例如 'MyKey1' = 'MyValue1' 如上一个屏幕截图所示。这里的目标是稍后将信息作为对象检索回来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多