Dar*_*te1 11 powershell events logging
最近,我们为所有脚本添加了选项,以便在Windows事件日志中记录其消息.这对于短消息非常有用,但我们似乎无法找到以结构化方式保存事件的方法,以便以后可以使用它们创建对象.
如何使用PowerShell完成此操作?
我们已经尝试过如下所述,但没有运气:
Write-EventLog -LogName HCScripts -Source 'Test (Brecht)' -EventId 4 -Message "<Data Name=""MyKey1"">MyValue1</Data>"
Run Code Online (Sandbox Code Playgroud)
在这篇文章中还有其他选项描述,但我们似乎无法弄清楚如何正确地做到这一点.
阅读事件的方法是:
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 *
Run Code Online (Sandbox Code Playgroud)
谢谢您的帮助.
我找到了两种可能的解决方案来解决“如何用 PowerShell 完成?”这个问题。第一个涉及自定义 PowerShell 方法并利用系统程序集写入事件日志。第二个涉及实现自定义提供程序。应该注意的是,这不会在<Data>节点中存储 XML 。它将数据存储在独立元素中。
方法一:自定义PowerShell函数
这种方法论来自Kevin Holman写的一篇文章, 他的解释非常出色。我在这里复制了代码,所以这里的答案将是完整的。
定义要记录的事件日志和源,加载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))
}
Run Code Online (Sandbox Code Playgroud)下一步是设置要写入日志的参数并调用该函数。
#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
Run Code Online (Sandbox Code Playgroud)方法 2:自定义事件提供程序
这种方法来自Daniel Gordon撰写的一篇文章, 我降低了他示例的一些复杂性,并在此GitHub 存储库中提供了源代码和说明
<templates>元素是元素。它定义了最终将变成<Data>事件负载中元素的字段。#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))
}
Run Code Online (Sandbox Code Playgroud)
CustomProvider.man在C:\CustomProvider\。如果您不遵循此约定,则必须更新CustomProvider.man. 保存后,以管理员身份打开 Visual Studio 命令提示符并 cd 到 C:\CustomProvidermc -css Namespace CustomProvider.manrc CustomProvider.rccsc /target:library /unsafe /win32res:CustomProvider.res CustomProvider.cswevtutil im CustomProvider.man您现在将在 Windows 事件查看器中看到自定义提供程序
要写入日志,请打开 Windows Powershell 提示符并执行
New-WinEvent -ProviderName CustomProvider -Id 10000 -Payload @("MyValue1")
Run Code Online (Sandbox Code Playgroud)
然后刷新事件日志,您将看到该事件。