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

使用DirectoryEntry获取本地机器子条目时GUID全部重复,如何获取正确值?

问题原因

你遇到的GUID重复问题是WinNT目录服务提供程序的固有特性:该提供程序设计上没有为本地安全主体(用户、组、计算机账户等)暴露原生的对象GUID属性,你直接读取DirectoryEntry.Guid拿到的是WinNT提供程序返回的固定默认值,不是对应条目的唯一标识。


解决方案

方案1:使用System.DirectoryServices.AccountManagement 实现(推荐)

这是.NET官方封装的身份主体管理专用库,直接可以拿到正确的对象GUID,代码更简洁,也不需要手动处理WinNT提供程序的缺陷。
使用前需要先添加程序集引用System.DirectoryServices.AccountManagement,参考实现代码:

using System.DirectoryServices.AccountManagement;
using System.Collections.Generic;

public static List<(Guid ObjectGuid, string Sid, string Name, string ObjectType)> GetLocalMachineEntries()
{
    List<(Guid ObjectGuid, string Sid, string Name, string ObjectType)> result = new();
    // 连接本地计算机上下文
    using PrincipalContext localContext = new PrincipalContext(ContextType.Machine);
    // 定义查询过滤,默认查询所有主体类型,也可指定UserPrincipal、GroupPrincipal等单独查询
    using Principal queryFilter = new Principal(localContext);
    using PrincipalSearcher searcher = new PrincipalSearcher(queryFilter);
    
    foreach (Principal principal in searcher.FindAll())
    {
        result.Add((
            ObjectGuid: principal.Guid.Value, // 此处获取的即为真实唯一GUID
            Sid: principal.Sid.Value,
            Name: principal.Name,
            ObjectType: principal.StructuralObjectClass
        ));
        principal.Dispose();
    }
    return result;
}

该方案拿到的GUID是本地安全主体的真实唯一标识,仅在账户被删除重建时才会变更,修改用户名、组权限等操作都不会改变GUID,符合作为唯一标识的需求。未加入域的独立机器使用该方案不需要额外权限,普通用户权限即可正常读取所有公开的本地主体GUID。

方案2:基于现有DirectoryEntry代码适配获取GUID

如果你必须保留现有WinNT目录访问的代码逻辑,可以通过将条目SID转换为GUID的方式获取:本地账户的对象GUID实际存储在注册表路径HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets\下对应SID的子项中,也可以通过调用LsaLookupSids Win32 API传入SID获取对应的GUID。但这种方式需要处理权限问题(访问SECURITY注册表项需要管理员权限),实现复杂度远高于方案1,不推荐使用。


内容的提问来源于stack exchange,提问作者Smolakian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:24:03