在“应用程序和设置日志”下的子目录中创建事件日志
本文关键字:日志 子目录 事件 创建 应用程序 设置 | 更新日期: 2023-09-27 18:26:17
我一直在寻找一种方法,在Applications and Services Logs
的子目录下创建多个单独的事件日志,就像有一个子目录Microsoft
,然后有一个子文件夹Windows
,然后有应用程序登录的各种其他目录一样。
- 应用程序和服务''Microsoft''Windows''所有用户安装代理
- 应用程序和服务''Microsoft''Windows''AppHost
我想创建如下
- 应用程序和服务''我的公司''应用程序1
- 应用程序和服务''我的公司''应用程序2
- 应用程序和服务''我的公司''应用程序3
我遇到的所有示例都只允许您直接在Applications and Services
目录下创建日志,而不允许创建子目录。
感谢
我一直在努力让子文件夹也能正常工作,因为我希望有一个这样的结构:
- Application and Services Logs
-- Company Name
--- Application 1
---- ApplicationLog
--- Application 2
---- SecurityLog
---- OperationalLog
我找不到任何直接使用C或PowerShell的方法,但是,在对注册表项和上提供的文档进行了一些尝试和错误之后https://learn.microsoft.com/en-us/windows/desktop/eventlog/eventlog-key我终于开始工作了。
似乎您需要在HKLM''Software''Microsoft''Windows''CurrentVersion''WINEVT''Channels中创建注册表项,其中主注册表项名称是"文件夹"结构的键。"-"被视为一种更深层次的结构。例如:CompanyName''Application''Log,应该是一个名为CompanyName Application Log的键。
以下是使用PowerShell执行此操作的示例脚本:
# Create the eventlog (in a subfolder structure)
# Params()
$PrimaryEventKey = 'Company'
$ApplicationName = 'Application'
$LogName = 'NewLog'
# Vars()
$primarylocation = 'HKLM:'Software'Microsoft'Windows'CurrentVersion'WINEVT'Channels'
$LogName = $PrimaryEventKey + '-' + $ApplicationName + '-' + $LogName
$EventRoot = (Join-Path $primarylocation $LogName)
if (!(Test-Path $EventRoot)) {
New-Item -Path ($secondarylocation + ''' + $Logname)
New-ItemProperty -Path ($secondarylocation + ''' + $Logname) -Name providerGuid -PropertyType String -Value "{$($GUID)}"
New-Item -Path $EventRoot
New-ItemProperty -Path $EventRoot -Name Enabled -PropertyType DWord -Value 1
New-ItemProperty -Path $EventRoot -Name Type -PropertyType DWord -Value 1
New-ItemProperty -Path $EventRoot -Name Isolation -PropertyType DWord -Value 0
New-ItemProperty -Path $EventRoot -Name RestrictGuestAccess -PropertyType String -Value 1
New-ItemProperty -Path $EventRoot -Name OwningPublisher -PropertyType String -Value "{$($GUID)}"
# See https://learn.microsoft.com/en-us/windows/desktop/eventlog/eventlog-key for documentation on the ChannelAccess or or RestrictGuestAccess (see: RestrictGuestAccess / Isolation)
}
else {
Write-Warning 'Event Log (Key) Already exists in registry'
}
# Write into the event log (Example)
$eventType = ([System.Diagnostics.EventLogEntryType]::Information)
$evt = New-Object System.Diagnostics.EventLog($LogName)
$evt.Source = "SomeSource"
$evt.WriteEntry("random message", $eventType, 60001)
如果仍然需要,我为自己找到了一个好的工作解决方案,尽管它使用的是Powershell而不是C#。你需要两个步骤:
- 创建日志本身
- 创建(如果需要)事件源
这里我的代码创建一个子文件夹位于自定义事件日志:
function New-WindowsCustomLog
{
<#
.SYNOPSIS
Create a custom Eventlog
.DESCRIPTION
This function will create a new eventlog located under 'Application and Serviceprotocolls' using a company subfolder and if needed additional functional subfolder.
.PARAMETER PrimaryKey
Mostly used for the company name.
.PARAMETER ApplicationName
Application name.
.PARAMETER ApplicationFunction
Optional: If you need to create another subfolder for functions.
.PARAMETER LogName
The name of the Log itself.
.PARAMETER ProviderGUID
Provider/Publisher GUID, if you don't have one, create by using New-GUID enter without {} around.
.EXAMPLE
New-WindowsCustomLog -PrimaryKey 'My Company' -ApplicationName 'My Cool Tool' -LogName 'Operational' -ProviderGUID '{49ab7419-7113-40d1-8910-8be1c3f96d21}'
.EXAMPLE
New-WindowsCustomLog -PrimaryKey 'My Company' -ApplicationName 'My Cool Tool' -ApplicationFunction 'Incoming' -LogName 'Requests' -ProviderGUID '{49ab7419-7113-40d1-8910-8be1c3f96d21}'
New-WindowsCustomLog -PrimaryKey 'My Company' -ApplicationName 'My Cool Tool' -ApplicationFunction 'Outgoing' -LogName 'Requests' -ProviderGUID '{49ab7419-7113-40d1-8910-8be1c3f96d21}'
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true,
Position = 0)]
[string]$PrimaryKey,
[Parameter(Mandatory = $true,
Position = 1)]
[string]$ApplicationName,
[Parameter(Position = 2)]
[string]$ApplicationFunction,
[Parameter(Mandatory = $true,
Position = 3)]
[string]$LogName,
[Parameter(Mandatory = $true,
Position = 4)]
[String]$ProviderGUID
)
$publisherGuid = "{$($ProviderGUID)}"
$primaryLocation = 'HKLM:'Software'Microsoft'Windows'CurrentVersion'WINEVT'Channels'
$secondaryLocation = 'HKLM:'SYSTEM'CurrentControlSet'Services'EventLog'Application'
#$thirdLocation = 'HKLM:'SYSTEM'CurrentControlSet'Services'EventLog'System' # needed for driver purposes
$publisher = 'HKLM:'SOFTWARE'Microsoft'Windows'CurrentVersion'WINEVT'Publishers'
if (-not ([string]::IsNullOrEmpty($ApplicationFunction)))
{
$primaryLogName = $PrimaryKey + '-' + $ApplicationName + '-' + $ApplicationFunction + '§' + $LogName
$secondaryLogName = $PrimaryKey + '-' + $ApplicationName + '-' + $ApplicationFunction
}
else
{
$primaryLogName = $PrimaryKey + '-' + $ApplicationName + '-' + '§' + $LogName
$primaryLogNameSlash = $primaryLogName.Replace("§", "/")
$secondaryLogName = $PrimaryKey + '-' + $ApplicationName
}
$evtxFilePath = "%SystemRoot%'System32'Winevt'Logs'$($secondaryLogName)%4$($LogName).evtx"
$primaryEventRoot = Join-Path -Path $primaryLocation -ChildPath $primaryLogName
$secondaryEventRoot = Join-Path -Path $secondaryLocation -ChildPath $secondaryLogName
#$thirdEventRoot = Join-Path -Path $thirdLocation -ChildPath $secondaryLogName # needed for driver purposes
$publisherEventRoot = Join-Path -Path $publisher -ChildPath $publisherGuid
if (-not (Test-Path $primaryLogNameSlash)) #$primaryEventRoot.Replace("§", "/")))
{
® add $primaryLogNameSlash.Replace(":", "") # used because I wasn't able to write a real / to registry key name by CMDLET
New-ItemProperty -Path $primaryLogNameSlash -Name 'Enabled' -PropertyType DWord -Value 1
New-ItemProperty -Path $primaryLogNameSlash -Name 'Type' -PropertyType DWord -Value 1
New-ItemProperty -Path $primaryLogNameSlash -Name 'Isolation' -PropertyType DWord -Value 0
New-ItemProperty -Path $primaryLogNameSlash -Name 'RestrictGuestAccess' -PropertyType String -Value "1"
New-ItemProperty -Path $primaryLogNameSlash -Name 'OwningPublisher' -PropertyType String -Value $publisherGuid
}
if (-not (Test-Path $secondaryEventRoot))
{
New-Item -Path $secondaryEventRoot
New-ItemProperty -Path $secondaryEventRoot -Name 'ProviderGuid' -PropertyType String -Value $publisherGuid
New-ItemProperty -Path $secondaryEventRoot -Name 'File' -PropertyType ExpandString -Value $evtxFilePath
}
<# needed for driver purposes
if (-not (Test-Path $thirdEventRoot))
{
New-Item -Path $thirdEventRoot
New-ItemProperty -Path $thirdEventRoot -Name 'ProviderGuid' -PropertyType String -Value $publisherGuid
#New-ItemProperty -Path $thirdEventRoot -Name 'EventMessageFile' -PropertyType ExpandString -Value $evtMessageFile
}
#>
if (-not (Test-Path $publisherEventRoot))
{
New-Item -Path $publisherEventRoot -Value $secondaryLogName
New-ItemProperty -Path $publisherEventRoot -Name 'Enabled' -PropertyType DWord -Value 1
$channelReference = Join-Path -Path $publisherEventRoot -ChildPath "ChannelReference"
New-Item -Path $channelReference
New-ItemProperty -Path $channelReference -Name 'Count' -PropertyType DWord -Value 1
$reference0 = Join-Path -Path $channelReference -ChildPath "0"
New-Item -Path $reference0 -Value $primaryLogName.Replace("§", "/")
New-ItemProperty -Path $reference0 -Name 'Flags' -PropertyType DWord -Value 0
New-ItemProperty -Path $reference0 -Name 'Id' -PropertyType DWord -Value 16
}
return $primaryLogNameSlash
}
接下来是一个创建事件源的简单功能(如果日志可用并且源尚未注册):
function New-WindowsEventSource
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true,
Position = 0)]
[ValidateScript({ [System.Diagnostics.EventLog]::Exists($_) })]
[string]$EventLogName,
[Parameter(Mandatory = $true,
Position = 1)]
[ValidateScript({ (-not ([System.Diagnostics.EventLog]::SourceExists($_))) })]
[string]$EventSourceName
)
[System.Diagnostics.EventLog]::CreateEventSource($EventSourceName, $EventLogName)
}
以下是如何创建源/填充EventLog:
New-WindowsEventSource -EventLogName "My Company-My Cool Tool-Incoming/Requests" -EventSourceName "webbrowser"
Write-EventLog -LogName "My Company-My Cool Tool-Incoming/Requests" -Source "webbrowser" -EntryType Information -EventId 100 -Message "New request received."
亲切的问候和愉快的编码