Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何获取属于本地系统组的域用户SID_C#_Directory - Fatal编程技术网

C# 如何获取属于本地系统组的域用户SID

C# 如何获取属于本地系统组的域用户SID,c#,directory,C#,Directory,我在一个域中有一台机器(没有工作组),我有一个本地组测试用户,在这个组中我添加了域用户 域\管理员 域\安装 现在我想从组中获取所有用户及其SID。使用下面的代码,我可以获取此组中的所有用户名,但如何获取SID using (var groupEntry = new DirectoryEntry("WinNT://./Test Users,group")) { foreach (var member in (IEnumerable)gro

我在一个域中有一台机器(没有工作组),我有一个本地组
测试用户
,在这个组中我添加了域用户

域\管理员

域\安装

现在我想从组中获取所有用户及其
SID
。使用下面的代码,我可以获取此组中的所有用户名,但如何获取
SID

using (var groupEntry = new DirectoryEntry("WinNT://./Test Users,group"))
            {
                foreach (var member in (IEnumerable)groupEntry.Invoke("Members"))
                {
                    using (var memberEntry = new DirectoryEntry(member))
                    {
                        Console.WriteLine(memberEntry.Name);
                    }
                }
            }

要获取DirectoryEntry的SID,必须获取用户/组的扩展属性。您可以通过调用DirectoryEntry上的
.properties
来获取这些属性。您可以使用
[“propertyName”]访问每个属性。Value
但对于SID,您必须将SID的字节数组转换为字符串。下面是codeproject站点的转换方法以及如何使用它

将字节转换为字符串的方法是


替代解决方案

您问是否有其他方法,因为我正在发布一个不同的过程来查找帐户的SID。使用包管理器获取nuget包:
System.DirectoryServices.AccountManagement

自从微软推出
System.DirectoryServices.AccountManagement
以来,我已经用该程序集编写了几乎所有的广告工作。以下是我编写的代码,用于以不同的方式查找系统本地组中所有组/帐户成员的SID

    // Recursively looks up all members and returns All the SIDs of all 'User' or 'local' accounts. 
    // ---> (NOT GROUPS but you can change that if you'd like.)
    private static List<string> GetSidsForAllAccounts(GroupPrincipal grp)
    {
        List<string> listOfSids = new List<string>();
        foreach (var member in grp.Members)
        {
            if (member.StructuralObjectClass != null && member.StructuralObjectClass.ToLower().Equals("group"))
                listOfSids.AddRange(GetSidsForAllAccounts((GroupPrincipal)member));
            else
                listOfSids.Add(member.Sid.ToString());
                // You could also use below to get Name and SID, PIPE delimited.
                // listOfSids.Add($"{member.Name}|{member.Sid.ToString()}");
                // You'll have to cast member to UserPrincipal if you are looking for properties specific to User Account.
        }
        return listOfSids;
    }
//递归查找所有成员并返回所有“用户”或“本地”帐户的所有SID。
//-->(不是组,但如果愿意,可以更改。)
私有静态列表GetSidsForAllAccounts(GroupPrincipal grp)
{
List listOfSids=新列表();
foreach(grp.Members中的变量成员)
{
如果(member.StructuralObjectClass!=null&&member.StructuralObjectClass.ToLower().Equals(“组”))
AddRange(GetSidsForAllAccounts((GroupPrincipal)成员));
其他的
添加(member.Sid.ToString());
//您还可以使用下面的命令来获取名称和SID,以管道分隔。
//添加($“{member.Name}{member.Sid.ToString()}”);
//如果要查找特定于用户帐户的属性,则必须将成员强制转换为UserPrincipal。
}
返回SIDS列表;
}
在main方法中使用:您可以通过以下方式调用上述方法

    // Look up the definition of PrincipalContext to use credentials.
    // e.g. new PrincipalContext(ContextType.Machine, "domainName", "user", "pass");
    PrincipalContext local = new PrincipalContext(ContextType.Machine);
    GroupPrincipal grp = GroupPrincipal.FindByIdentity(local, "Administrators");

    List<string> allSids = GetSidsForAllAccounts(grp);
    allSids.ForEach(x => Console.WriteLine(x));
//查找PrincipalContext的定义以使用凭据。
//例如,新PrincipalContext(ContextType.Machine,“域名”,“用户”,“通行证”);
PrincipalContext local=新PrincipalContext(ContextType.Machine);
GroupPrincipal grp=GroupPrincipal.FindByIdentity(本地,“管理员”);
列出所有SID=GetSidsForAllAccounts(grp);
allSids.ForEach(x=>Console.WriteLine(x));
这是如何工作的

  • PrincipalContext
    定义在何处查找第一个组,在本例中为“本地计算机”
  • 在每个组中循环查找详细信息时,使用组本身的
    PrincipalContext
    。如果组属于域,它将使用域上下文自动查找,如果是本地计算机组,则使用本地计算机
  • 反复检查每个组以查找其成员,直到找到其所有用户帐户

  • 非常感谢,贾瓦德。还有其他方法吗?@user584018请看我的另一个答案非常好,谢谢Jawad,这个解决方案很好。我们能得到emailId吗?是的。您也可以查找用户的电子邮件地址。好的,但我没有看到任何
    member.email
    之类的
    member.Sid
    您可能必须将该用户强制转换为(UserPrincipal)才能访问电子邮件地址
        // Recursively looks up all members and returns All the SIDs of all 'User' or 'local' accounts. 
        // ---> (NOT GROUPS but you can change that if you'd like.)
        private static List<string> GetSidsForAllAccounts(GroupPrincipal grp)
        {
            List<string> listOfSids = new List<string>();
            foreach (var member in grp.Members)
            {
                if (member.StructuralObjectClass != null && member.StructuralObjectClass.ToLower().Equals("group"))
                    listOfSids.AddRange(GetSidsForAllAccounts((GroupPrincipal)member));
                else
                    listOfSids.Add(member.Sid.ToString());
                    // You could also use below to get Name and SID, PIPE delimited.
                    // listOfSids.Add($"{member.Name}|{member.Sid.ToString()}");
                    // You'll have to cast member to UserPrincipal if you are looking for properties specific to User Account.
            }
            return listOfSids;
        }
    
        // Look up the definition of PrincipalContext to use credentials.
        // e.g. new PrincipalContext(ContextType.Machine, "domainName", "user", "pass");
        PrincipalContext local = new PrincipalContext(ContextType.Machine);
        GroupPrincipal grp = GroupPrincipal.FindByIdentity(local, "Administrators");
    
        List<string> allSids = GetSidsForAllAccounts(grp);
        allSids.ForEach(x => Console.WriteLine(x));