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));