如何使用PowerShell通过现有提供程序编写自定义事件日志?

问题描述 投票:1回答:1

我试图在“网络连接”事件日志的消息中找出“状态”数据的名称/值映射:

Path = Microsoft-Windows-NetworkProfile/Operational
Source = NetworkProfile
Event ID = 10000

所以我想我会在更改消息的“State”值时由同一个提供程序和相同的日志(路径)编写自定义事件日志,然后我可以在事件查看器中看到该值的名称映射。 例如,到目前为止,我有这些值/名称映射:

1 --> 'Connected'
5 --> 'Connected, IPV4 (Local)'
9 --> 'Connected, IPV4 (Internet)'

我想知道其余的人。

所以我在PowerShell中尝试了New-WinEvent CmdLet来编写日志:

New-WinEvent -ProviderName Microsoft-Windows-NetworkProfile -Id 10000 -Payload @("SSID","Description","{B58F86AB-F35D-4F73-A41E-98EA359E1D08}",0,1,0)

并且它已创建,但我传递给-Payload参数的最后4个参数未生效。只有{"name" = "SSID""Description" = "Description"}出现在那个事件中。无论我如何更改它们,最后4个参数都保持固定值,而执行此行时没有错误或警告,-Verbose也没有显示任何内容。

Custom Event Details

我在所有可用的类型和值中传递了这些参数(尤其是最后3个)。我甚至将一个早期事件日志(我没有记录)的参数传递给这个参数,怀疑我误解了数据类型但没有改变。

$a = ((Get-WinEvent -ProviderName Microsoft-Windows-NetworkProfile -MaxEvents 50  | Where-Object {$_.Id -eq 10000})[-1]).properties[3].value
$b = ((Get-WinEvent -ProviderName Microsoft-Windows-NetworkProfile -MaxEvents 50  | Where-Object {$_.Id -eq 10000})[-1]).properties[4].value
$c = ((Get-WinEvent -ProviderName Microsoft-Windows-NetworkProfile -MaxEvents 50  | Where-Object {$_.Id -eq 10000})[-1]).properties[5].value
New-WinEvent -ProviderName Microsoft-Windows-NetworkProfile -Id 10000 -Payload @("SSID","Description","{B58F86AB-F35D-4F73-A41E-98EA359E1D08}",$a,$b,$c)

然后我尝试了Write-EventLog CmdLet:

Write-EventLog -LogName "Microsoft-Windows-NetworkProfile/Operational" -Source "NetworkProfile" -EventID 10000 -EntryType Information -Message $msg -Category 0

但我一直收到错误:Write-EventLog : The source name "NetworkProfile" does not exist on computer "localhost".虽然源确实存在,但它是“网络连接”日志的来源,正如您从屏幕截图中看到的那样。

我对这两个CmdLets做错了什么?

powershell event-log event-viewer
1个回答
1
投票

我设法使第一个CmdLet New-WinEvent工作。奇怪的是,这是一个数据类型问题。

“网络连接”事件需要为其消息提供6个参数。这些参数的预期类型可以在我从PowerShell获得的警告中看到

警告:提供的有效内容与为事件ID 41定义的模板不匹配。定义的模板如下:

NetworkProfile Template

我把Guid参数作为一个字符串传递,但它希望它有一个[System.Guid]类型,显然当你在数组中传递New-WinEvent参数的6个参数时,-Payload不会发出警告,即使一个参数没有正确的类型。它只是创建一个带有一些固定默认参数的新事件(就像我的问题中发生的那样)。

所以我不得不把正确的类型投射到这个论点Guid。我得到了它的类型名称:

$validEvent = (Get-WinEvent -ProviderName Microsoft-Windows-NetworkProfile -MaxEvents 500  | Where-Object {$_.Id -eq 10000} | Where-Object {$_.properties[4].Value -eq 9})[-1]
$validEvent.Properties[2].Value.GetType().FullName

Arguments Type

然后我将正确的类型转换为参数并将它们传递给-Payload并且它有效:

$name = 'SSID'
$desc = 'Description'
[System.Guid]$guid = "c48f86ab-f35d-4f73-a41e-99ea359e1d08"
[System.UInt32]$type = 1
[System.UInt32]$state = 63
[System.UInt32]$categ = 2

New-WinEvent -ProviderName Microsoft-Windows-NetworkProfile -Id 10000 -Payload @($name, $desc, $guid, $type, $state, $categ)

New-WinEvent Output

然后我可以改变$state的值来从$newLog.Message获取它的名字映射。

然而,第二个CmdLet Write-EventLog不起作用;显然它不能由同一个提供者写入此日志。

正如Max所提到的,这个CmdLet只能写入“经典”事件日志,这就是为什么它找不到NetworkProfile源。

一些帮助我的链接:

How to store an object in the Windows Event Log? [Answer]Grady G Cooper Writing to the event log in .NET - the right way MSDN - Event Sources TechNet - New-WinEvent

© www.soinside.com 2019 - 2024. All rights reserved.