.NET获取AD计算机的完整属性列表(以匹配Powershell Get-ADComputer API)

时间:2018-11-20 14:50:49

标签: c# .net powershell active-directory

我正在将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#代码中正确设置所有内容。我得到了许多相同的属性,但不是全部。我希望获得指导。

谢谢。

1 个答案:

答案 0 :(得分:2)

PowerShell有时对属性使用“显示名称”,其中AD中属性的实际名称略有不同。 PowerShell还具有一些附加属性,可以将AD中的某些数据转换为有用的东西。这是一个例子。

PrimaryGroup属性返回主要组的专有名称。但是,AD中没有存储该属性的属性。主要组是根据primaryGroupId属性确定的,该属性是该组的RID(相对标识符)。

因此,您必须询问primaryGroupId属性并将其转换为实际的组。我写了一篇有关Finding all of a user’s groups的文章,其中分享了一种可以做到这一点的方法。这接受DirectoryEntry,但实际上只需要知道primaryGroupIdobjectSid(因为它使用用户的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