【问题标题】:Create Event Log in Sub Directory under Applications and Settings Logs在应用程序和设置日志下的子目录中创建事件日志
【发布时间】:2014-10-13 08:43:07
【问题描述】:

我一直在寻找一种方法来在Applications and Services Logs 的子目录下创建多个单独的事件日志,就像有一个子目录Microsoft 然后它有一个子目录Windows然后用App登录的其他各种目录。

  • Applications and Services\Microsoft\Windows\All-User-Install-Agents
  • 应用程序和服务\Microsoft\Windows\AppHost
  • ...

我想创建类似下面的东西

  • 应用程序和服务\我的公司\应用程序 1
  • 应用程序和服务\我的公司\应用程序 2
  • 应用程序和服务\我的公司\应用程序 3

我遇到的所有示例只允许您直接在Applications and Services目录下创建日志,而不是创建子目录。

谢谢

【问题讨论】:

    标签: c# event-log windows-server-2012-r2


    【解决方案1】:

    如果仍然需要,我为我想出了一个很好的工作解决方案,尽管它使用的是 Powershell 而不是 C#。 您需要 2 个步骤:

    1. 自行创建日志
    2. 创建(如果需要)事件源

    这是我用于创建位于自定义事件日志的子文件夹的代码:

    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("§", "/")))
        {
            &reg 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)
    }
    

    这里是创建源/填充事件日志的方法:

    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."
    

    亲切的问候和愉快的编码

    【讨论】:

    • 嗯,我很高兴看到有人在没有 .NET 的情况下解决了这个问题……但我遇到了各种错误; pastebin.com/DKxdWQpY
    【解决方案2】:

    我正在努力让子文件夹也能正常工作,因为我希望有这样的结构:

    - Application and Services Logs
    -- Company Name
    --- Application 1
    ---- ApplicationLog
    --- Application 2
    ---- SecurityLog
    ---- OperationalLog
    

    我找不到任何直接使用 C 或 PowerShell 的方法,但是在对注册表项和https://docs.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://docs.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)
    

    【讨论】:

    • 请提供经过测试的代码.. 或至少完整的代码.. :( 我猜 $secondaryLocation 是 HKLM:\SYSTEM\CurrentControlSet\Services\EventLog ?? 这也不起作用
    • 嗯,我很高兴看到有人在没有 .NET 的情况下解决了这个问题……这个想法很好,但根本行不通。您是否曾经尝试过将其复制/粘贴到 PowerShell 中? :(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多