Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用PowerShell编写已有提供程序的自定义事件日志?_Powershell_Event Log_Event Viewer - Fatal编程技术网

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

如何使用PowerShell编写已有提供程序的自定义事件日志?,powershell,event-log,event-viewer,Powershell,Event Log,Event Viewer,我试图找出“网络连接”事件日志消息中“状态”数据的名称/值映射: Path = Microsoft-Windows-NetworkProfile/Operational Source = NetworkProfile Event ID = 10000 因此,我想在更改消息的“状态”值时,我将由同一提供程序向同一日志(路径)写入自定义事件日志,然后我可以在事件查看器中看到该值的名称映射。 例如,到目前为止,我有以下值/名称映射: 1 --> 'Connected' 5 --> 'Co

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

Path = Microsoft-Windows-NetworkProfile/Operational
Source = NetworkProfile
Event ID = 10000
因此,我想在更改消息的“状态”值时,我将由同一提供程序向同一日志(路径)写入自定义事件日志,然后我可以在事件查看器中看到该值的名称映射。
例如,到目前为止,我有以下值/名称映射:

1 --> 'Connected'
5 --> 'Connected, IPV4 (Local)'
9 --> 'Connected, IPV4 (Internet)'
我想知道其他人

因此我在PowerShell中尝试了
新WinEvent
CmdLet来编写日志:

New-WinEvent -ProviderName Microsoft-Windows-NetworkProfile -Id 10000 -Payload @("SSID","Description","{B58F86AB-F35D-4F73-A41E-98EA359E1D08}",0,1,0)
Write-EventLog -LogName "Microsoft-Windows-NetworkProfile/Operational" -Source "NetworkProfile" -EventID 10000 -EntryType Information -Message $msg -Category 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:

New-WinEvent -ProviderName Microsoft-Windows-NetworkProfile -Id 10000 -Payload @("SSID","Description","{B58F86AB-F35D-4F73-A41E-98EA359E1D08}",0,1,0)
Write-EventLog -LogName "Microsoft-Windows-NetworkProfile/Operational" -Source "NetworkProfile" -EventID 10000 -EntryType Information -Message $msg -Category 0
但我一直收到错误:
Write EventLog:计算机“localhost”上不存在源名称“NetworkProfile”。
尽管该源确实存在,并且它是“网络连接”日志的源,如屏幕截图所示


这两个CmdLet我做错了什么?我成功地使第一个CmdLet
新WinEvent
工作。奇怪的是,这是一个数据类型问题。

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

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

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

因此,我必须将正确的类型转换为这个参数
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
不起作用;显然,它不能由同一提供商写入此日志。

如前所述,此CmdLet只能写入“经典”事件日志,因此无法找到
NetworkProfile

一些帮助我的链接:

New-WinEvent -ProviderName Microsoft-Windows-NetworkProfile -Id 10000 -Payload @("SSID","Description","{B58F86AB-F35D-4F73-A41E-98EA359E1D08}",0,1,0)
Write-EventLog -LogName "Microsoft-Windows-NetworkProfile/Operational" -Source "NetworkProfile" -EventID 10000 -EntryType Information -Message $msg -Category 0
通过



这很有趣。我在我的事件日志中看到类似的事件,但随后我运行了
[System.Diagnostics.eventlog]::SourceExists(“Microsoft Windows NetworkProfile”)
[System.Diagnostics.eventlog]::SourceExists(“NetworkProfile”)
它返回
False
好的,我无法为您提供完整的解决方案,但我已经找到了开始的地方:。这些“扩展”日志似乎无法通过“标准”API获得。因此,您需要使用.Net类(在PS或C#中)。因此,从
EventLogSession EventLogSession=new EventLogSession()
开始,然后打开网络配置文件事件提供程序:
System.Diagnostics.Eventing.EventProvider NetworkProfile=new System.Diagnostics.Eventing.EventProvider(Guid.Parse(“fbcfac3f-8459-419f-8e48-1f0b49cdb85e”)
@Max这很奇怪,我以为
Write EventLog
就是为了这个目的而构建的。不管怎样,我会检查如何使用.NET,thnx!看起来
Write EventLog
对应于
System.Diagnostics.EventLog
.Net类,它是上一代API(如我所见,可能是错误的)。因此,这个旧方法类无法访问“现代”日志,因此PS commandlet也是如此。这里要真正记住的一件事是正确获取类型。如果您使用了错误的类型,那么整个消息在传递到windows时会变得混乱,您将在windows中的XML消息中写入一个错误。提示:请注意整数的位长度等。混合使用32位和64位整数将破坏整个消息