简体   繁体   English

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

[英]how to get domain user SID which is part of local system group

I have a machine within a domain (no work-group) and I have a local group Test Users and within this group I have added domain users.我在域(没有工作组)中有一台机器,我有一个本地组Test Users ,在这个组中我添加了域用户。

domain\\Administrator域\\管理员

domain\\Install域\\安装

在此处输入图片说明

Now I want to fetch all the users from the group along with their SID .现在我想从组中获取所有用户以及他们的SID With below code I am able to get all the user name within this group, but how to get 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);
                    }
                }
            }

Alternate Solution替代解决方案

You asked if there was another way, for that i am posting a different process for looking up SIDs of accounts.你问是否有另一种方法,为此我发布了一个不同的过程来查找帐户的 SID。 Use Package Manager to get the nuget package: System.DirectoryServices.AccountManagement .使用包管理器获取 nuget 包: System.DirectoryServices.AccountManagement

Since MS came about with System.DirectoryServices.AccountManagement , I have coded almost all the AD work with that assembly.自从 MS 与System.DirectoryServices.AccountManagement一起出现以来,我几乎用该程序集编写了所有 AD 工作。 Following is the code i wrote up for a different way of looking up SIDs for all members of groups/accounts in local group of a system.以下是我为查找系统本地组中组/帐户所有成员的 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;
    }

Use in main method : You would call the above the following way.在 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));

How does this work这是如何运作的

  1. PrincipalContext defines where to look up the first group, which in this case is "Local Machine". PrincipalContext定义在何处查找第一组,在本例中为“本地机器”。
  2. Looping through each group uses the PrincipalContext of the group itself when it looks up the details.在查找详细信息时,循环遍历每个组使用组本身的PrincipalContext If the group belongs to Domain, it will look up using the domain context automatically and local machine if its a local machine group.如果该组属于域,它将使用域上下文自动查找,如果它是本地机器组,它将使用本地机器。
  3. Recusively go through each group to look up its members until its all User accounts.递归地遍历每个组以查找其成员,直到其所有用户帐户。

To get the SID of the DirectoryEntry, you have to get the extended properties of the user/group.要获得 DirectoryEntry 的 SID,您必须获得用户/组的扩展属性。 You can get these properties by calling .Properties on the DirectoryEntry.您可以通过在 DirectoryEntry 上调用.Properties来获取这些属性。 You can access each of the properties by using ["propertyName"].Value but for SID, you have to convert the SID's byte array to string.您可以使用["propertyName"].Value访问每个属性,但对于 SID,您必须将 SID 的字节数组转换为字符串。 Below is the convert method from codeproject site and how to use this.下面是来自 codeproject 站点的转换方法以及如何使用它。

Method to convert Byte to String is taken from here将字节转换为字符串的方法取自here

    private static string ConvertByteToStringSid(Byte[] sidBytes)
        {
            StringBuilder strSid = new StringBuilder();
            strSid.Append("S-");
            try
            {
                // Add SID revision.
                strSid.Append(sidBytes[0].ToString());
                // Next six bytes are SID authority value.
                if (sidBytes[6] != 0 || sidBytes[5] != 0)
                {
                    string strAuth = String.Format
                        ("0x{0:2x}{1:2x}{2:2x}{3:2x}{4:2x}{5:2x}",
                        (Int16)sidBytes[1],
                        (Int16)sidBytes[2],
                        (Int16)sidBytes[3],
                        (Int16)sidBytes[4],
                        (Int16)sidBytes[5],
                        (Int16)sidBytes[6]);
                    strSid.Append("-");
                    strSid.Append(strAuth);
                }
                else
                {
                    Int64 iVal = (Int32)(sidBytes[1]) +
                        (Int32)(sidBytes[2] << 8) +
                        (Int32)(sidBytes[3] << 16) +
                        (Int32)(sidBytes[4] << 24);
                    strSid.Append("-");
                    strSid.Append(iVal.ToString());
                }

                // Get sub authority count...
                int iSubCount = Convert.ToInt32(sidBytes[7]);
                int idxAuth = 0;
                for (int i = 0; i < iSubCount; i++)
                {
                    idxAuth = 8 + i * 4;
                    UInt32 iSubAuth = BitConverter.ToUInt32(sidBytes, idxAuth);
                    strSid.Append("-");
                    strSid.Append(iSubAuth.ToString());
                }
            }
            catch (Exception ex)
            {

                return "";
            }
            return strSid.ToString();
        }

This is how you use that method and get the SID of the DirectoryEntry entity.这就是您如何使用该方法并获取 DirectoryEntry 实体的 SID。

    var coll = memberEntry.Properties;
    object obVal = coll["objectSid"].Value;
    object userSID;
    if (null != obVal)
    {
        userSID = ConvertByteToStringSid((Byte[])obVal);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM