我正在将Powershell代码转换为C#,在Powershell中,我将此API称为“ Get-ADComputer” https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-adcomputer?view=winserver2012-ps。当您查看链接中的示例时,它显示了可以返回的属性的详尽列表。
我正在尝试在C#中复制它,但是我得到了Powershell调用返回的内容的子集。例如,我正在寻找“ PrimaryGroup”,它只会在Powershell调用中返回。
以下是代码段:
POWERSHELL
Get-ADComputer -Filter "*" -Properties "*"
C#
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
class Program
{
static void Main(string[] args)
{
foreach (var p in GetProperties())
Console.WriteLine(p);
}
private static IEnumerable<string> GetDomainNames()
{
ICollection<string> domains = new List<string>();
foreach (Domain domain in Forest.GetCurrentForest().Domains)
domains.Add(domain.Name);
return domains;
}
public static List<string> GetProperties()
{
List<string> properties = new List<string>();
foreach (var domainName in GetDomainNames())
{
using (DirectoryEntry directoryEntry = new DirectoryEntry(@"LDAP://" + domainName))
{
using (DirectorySearcher mySearcher = new DirectorySearcher(directoryEntry))
{
mySearcher.Filter = ("(objectClass=computer)");
mySearcher.SizeLimit = 0; // no size limit
mySearcher.PageSize = 250; // paging
mySearcher.PropertiesToLoad.Add("PrimaryGroup"); // only want this property, for testing, comment out this line to get all properties returned
foreach (SearchResult resEnt in mySearcher.FindAll())
{
foreach (var p in resEnt.Properties.PropertyNames)
properties.Add(p.ToString());
}
}
}
}
properties.Sort();
return properties;
}
}
}
我猜我只是没有在C#代码中正确设置所有内容。我得到了许多相同的属性,但不是全部。我希望获得指导。
谢谢。
答案 0 :(得分:2)
PowerShell有时对属性使用“显示名称”,其中AD中属性的实际名称略有不同。 PowerShell还具有一些附加属性,可以将AD中的某些数据转换为有用的东西。这是一个例子。
PrimaryGroup
属性返回主要组的专有名称。但是,AD中没有存储该属性的属性。主要组是根据primaryGroupId
属性确定的,该属性是该组的RID(相对标识符)。
因此,您必须询问primaryGroupId
属性并将其转换为实际的组。我写了一篇有关Finding all of a user’s groups的文章,其中分享了一种可以做到这一点的方法。这接受DirectoryEntry
,但实际上只需要知道primaryGroupId
和objectSid
(因为它使用用户的SID来构造组的SID):
private static string GetUserPrimaryGroup(DirectoryEntry de) {
de.RefreshCache(new[] {"primaryGroupID", "objectSid"});
//Get the user's SID as a string
var sid = new SecurityIdentifier((byte[])de.Properties["objectSid"].Value, 0).ToString();
//Replace the RID portion of the user's SID with the primaryGroupId
//so we're left with the group's SID
sid = sid.Remove(sid.LastIndexOf("-", StringComparison.Ordinal) + 1);
sid = sid + de.Properties["primaryGroupId"].Value;
//Find the group by its SID
var group = new DirectoryEntry($"LDAP://<SID={sid}>");
group.RefreshCache(new [] {"cn"});
return group.Properties["cn"].Value as string;
}
您应该能够对其进行调整,以从DirectorySearcher
中提取值。
作为旁注,如果您不触摸PropertiesToLoad
集合,它将返回具有值的每个属性(不包括构造的属性)。也就是说,如果您不需要合法地查看每个属性,那么最好使用PropertiesToLoad
。