我试图在“网络连接”事件日志的消息中找出“状态”数据的名称/值映射:
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
也没有显示任何内容。
我在所有可用的类型和值中传递了这些参数(尤其是最后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做错了什么?
我设法使第一个CmdLet New-WinEvent
工作。奇怪的是,这是一个数据类型问题。
“网络连接”事件需要为其消息提供6个参数。这些参数的预期类型可以在我从PowerShell获得的警告中看到
警告:提供的有效内容与为事件ID 41定义的模板不匹配。定义的模板如下:
我把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
然后我将正确的类型转换为参数并将它们传递给-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)
然后我可以改变$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