使用 WMI 备份应用程序事件日志时需要 seBackup特权

本文关键字:seBackup 特权 日志 WMI 备份 应用程序 事件 使用 | 更新日期: 2023-09-27 17:56:13

我有一个函数,可以将事件日志存档到所需格式的文件中。

我正在针对Windows事件日志进行测试,ApplicationSecuritySystem。在所有测试中,代码都是以本地管理员权限运行的。

在我的开发环境中,代码成功地将每个日志文件备份到我们命名为"*.evt"的文件。

在目标参考系统上,SecuritySystem日志工作正常,但处理Application日志会引发ManagementException

下面包括对异常的询问。我的问题是,我假设这是一个安全特权问题是否正确?哪些代码更改将使此代码适用于所有我想要的情况?如果没有明确的答案,您的想法和想法将受到赞赏。

错误代码:访问被拒绝

错误信息: 说明: 打开了日志文件,但无法备份,权限错误

操作:执行方法

参数信息: Win32_NTEventlogFile.Name="C:''WINDOWS''system32''config''AppEvent.Evt"

特权不持有:- SeBackupPrivilege

所需权限:- SeBackupPrivilege

提供商名称: WinMgmt

状态代码:2147749891

using System.Management;
/* ... Omitted for brevity */
public static void WMIBackup(String logName, String targetFile)
{
    ManagementScope scope = new ManagementScope("root''CIMV2");
    scope.Options.Impersonation = ImpersonationLevel.Impersonate;
    scope.Options.EnablePrivileges = true;
    ObjectQuery query = new ObjectQuery(
        String.Format("SELECT * FROM Win32_NTEventLog WHERE LogFileName={0}", 
            logName)
    );
    using (ManagementObjectSearcher search = 
        new ManagementObjectSearcher(scope, query))
    {
        var logs = search.Get();
        if (logs.Count != 1)
            throw new ArgumentOutOfRangeException("logName not found");
        foreach (ManagementObject log in logs)
        {
            ManagementClass eventLogClass = 
                new ManagementClass("Win32_NTEventLogFile");
            ManangementBaseObject params = 
                eventLogClass.GetMethodParameters("BackupEventLog");
            params["ArchiveFileName"] = targetFile;
            log.InvokeMethod(
                "BackupEventLog",
                params,
                new InvokeMethodOptions(
                    null, 
                    InvokeMethodOptions.InfiniteTimeout)
            );
        } 
    }
}

所有数据均已转录,因此对勘误表表示歉意。

使用 WMI 备份应用程序事件日志时需要 seBackup特权

我过去在访问WMI和/或COM接口时遇到过问题。 它将在一个系统上工作,而在另一个系统上失败。

我发现如果您重试,则不会发生错误。 我建议当它失败时,你等待一小段时间(半秒左右),然后重试。

我的代码在所有 COM 和 WMI 调用周围有一个重试循环,类似于此示例:

int errorCount = 0;
bool success = false;
while (!success || errorCount < maxRetryCount)
{
    try
    {
         /* Call to WMI interface */
         DoSomething();
         success = true;
    }
    catch (Exception ex)
    {
         if (errorCount < maxRetryCount)
         {
             logWarning(ex);
         }
         else
         {
             logError(ex);
             throw; /* pass exception up the stack 
             or break and handle failure below */
         }
    }
}
if (!success)
{
    /* Handle failure */
}

从来没有弄清楚根本问题是什么,但这对我有用。