使用WMI备份应用程序事件日志时需要seBackupPrivilige

时间:2011-05-10 10:02:37

标签: c# security wmi

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

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

在我的开发环境中,代码将每个日志文件备份到我们称之为“* .evt”文件的位置。

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

下面列出了例外的隔离。我的问题是,我是否正确地认为这是一个安全特权问题?什么代码更改将使此代码适用于我所有需要的案例?如果没有明确的答案,那么您的想法和想法将受到赞赏。

  

ErrorCode:AccessDenied

     

ErrorInformation:说明:打开日志文件但无法备份,显示错误

     

操作:ExecMethod

     

ParameterInfo:Win32_NTEventlogFile.Name =“C:\ WINDOWS \ system32 \ config \ AppEvent.Evt”

     

PrivilegesNotHeld: -       SeBackupPrivilege

     

PrivilegesRequired: -       SeBackupPrivilege

     

ProviderName:WinMgmt

     

StatusCode: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)
            );
        } 
    }
}

所有数据都被转录,因此对勘误表道歉。

1 个答案:

答案 0 :(得分:2)

我以前在访问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 */
}

从未弄清楚底层问题是什么,但这对我有用。