首页 > 解决方案 > How to write a custom event log by an already existing provider with PowerShell?

问题描述

I am trying to find out the Name/Value mappings of the "State" data in the message of the 'Network Connected' event log:

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

So I figured I'll write a custom event log by the same provider and to the same log (path) while changing the "State" value of the message, then I can see the name mapping of that value in the event viewer.
For example, I have these Value/Name mappings so far:

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

and I want to know the rest of them.

So I tried the New-WinEvent CmdLet in PowerShell to write the logs:

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

And it was created, but the last 4 arguments I passed to the -Payload parameter were not taking effect. Only the {"name" = "SSID" and "Description" = "Description"} were appearing in that event. The last 4 arguments stay at fixed values no matter how I change them, while there were no errors or warnings when executing this line, neither did -Verbose show anything.

Custom Event Details

I passed these arguments (especially last 3) in all types and values available. I even passed the arguments of an earlier event log (Not logged by me) to this parameter suspecting I was mistaking the data-types but nothing changed.

$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)

Then I tried the Write-EventLog CmdLet:

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

But I kept getting the error: Write-EventLog : The source name "NetworkProfile" does not exist on computer "localhost". Although the source does exist and it's the source of the 'Network Connected' log, as you can see from the screenshot.

What am I doing wrong with these 2 CmdLets?

标签: powershellevent-logevent-viewer

解决方案


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

'Network Connected' 事件的消息需要 6 个参数。这些参数的预期类型可以在我从 PowerShell 获得的这个警告中看到

警告:提供的有效负载与为事件 id 1000 定义的模板不匹配。定义的模板如下:

网络配置文件模板

我将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)

New-WinEvent 输出

然后我可以更改 的值$state以从$newLog.Message.

但是,第二个 CmdLetWrite-EventLog不起作用;显然它不能由同一个提供者写入这个日志。

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

一些帮助我的链接:

如何在 Windows 事件日志中存储对象?[答案] Grady G Cooper

在 .NET 中写入事件日志 - 正确的方法

MSDN - 事件源

TechNet - New-WinEvent


推荐阅读