You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非域环境下如何快速找到交互式用户组SID并添加至Event Log Readers组?

非域环境下如何快速找到交互式用户组SID并添加至Event Log Readers组?

首先得跟你说个关键点:你其实已经拿到交互式用户的SID了!WellKnownSidType.InteractiveSid就是它的正确标识,之所以用PrincipalSearcher搜不到,是因为交互式用户(Interactive)不是一个常规的本地组,它是Windows内置的特殊安全主体,不会出现在常规的组列表里,所以遍历本地组自然找不到它~

之前的代码慢,主要是因为GroupPrincipal和Principal这些封装类在非域环境下会做一些额外的系统查询,拖慢了速度。咱们可以换用更底层的DirectoryEntry来操作,直接对接Windows的ADSI接口,速度会快很多,而且逻辑也不复杂。

下面是优化后的代码,我给你加了详细注释,你直接用就行:

using System.DirectoryServices;
using System.Security.Principal;

// 1. 直接获取两个内置SID,这一步你原来的写法完全正确
var eventLogReadersSid = new SecurityIdentifier(WellKnownSidType.WinBuiltinEventLogReadersGroup, null);
var interactiveUsersSid = new SecurityIdentifier(WellKnownSidType.InteractiveSid, null);

// 2. 用DirectoryEntry直接打开本地机器的组容器
using (var localMachine = new DirectoryEntry("WinNT://./computer,computer"))
{
    // 3. 找到Event Log Readers组(先把SID转成NT账户名再查找)
    using (var eventLogReadersGroup = localMachine.Children.Find(
        eventLogReadersSid.Translate(typeof(NTAccount)).Value, 
        "group"))
    {
        // 4. 把交互式用户的SID转换成可添加的账户格式
        var interactiveAccount = new NTAccount(interactiveUsersSid.Translate(typeof(NTAccount)).Value);
        var interactiveSidString = interactiveUsersSid.ToString();

        // 5. 检查组内是否已存在该成员,避免重复添加
        bool isAlreadyMember = false;
        foreach (object member in eventLogReadersGroup.Invoke("Members", null))
        {
            using (var memberEntry = new DirectoryEntry(member))
            {
                var memberSid = new SecurityIdentifier((byte[])memberEntry.Properties["objectSid"].Value, 0);
                if (memberSid.ToString() == interactiveSidString)
                {
                    isAlreadyMember = true;
                    break;
                }
            }
        }

        // 6. 如果不存在就添加并保存更改
        if (!isAlreadyMember)
        {
            eventLogReadersGroup.Invoke("Add", new object[] { interactiveAccount.ToString() });
            eventLogReadersGroup.CommitChanges();
            DebugLog($"用户({interactiveAccount.Value})已添加至Event Log Readers组");
        }
    }
}

为什么这个方法更快?

  • 跳过了PrincipalContext和GroupPrincipal这些封装层,直接和Windows本地目录服务交互,减少了不必要的中间查询步骤
  • 用DirectoryEntry.Invoke直接调用ADSI原生方法,比Principal类的成员检查逻辑更高效

另外提醒你:运行这段代码需要管理员权限,不然会没有修改组的权限哦~

备注:内容来源于stack exchange,提问作者Jon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 11:53:07