PowerShell AD 查询与 C# AD 查询 - 速度

本文关键字:查询 AD 速度 PowerShell | 更新日期: 2023-09-27 18:34:28

我正在学习C#,是一个新手。请耐心等待我。

我用 C# 开发了一个应用程序,通过将 PowerShell 命令放入其中来搜索 AD 中的用户、组和组成员。

现在,我正在尝试使用 C# 中的 DirectoryServices 来获得相同的结果,但是返回相同结果所需的时间比在 PowerShell 中要长得多。

以下是我现在使用 DirectoryServices 所做的快速测试:

using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
private void button1_Click(object sender, EventArgs e)
        {
            string textbox = textBox1.Text.ToString();
            listBox1.Items.Clear();
            listView1.Items.Clear();
            listView1.Columns.Clear();
            try
            {
                // Bind to the object for which to retrieve property data.
                DirectoryEntry de = new DirectoryEntry("");
                DirectorySearcher ds = new DirectorySearcher(de);
                ds.Filter = "(&(objectClass=Group)(cn="+ textbox + "))";
                ds.SearchScope = SearchScope.Subtree;
                SearchResultCollection rsAll = ds.FindAll();
                listView1.Columns.Add("samsaccountname");
                string samsaccountname = "";
                foreach (SearchResult searchresult in rsAll)
                {
                    if (searchresult.GetDirectoryEntry().Properties["samaccountname"].Value != null)
                    { samsaccountname = searchresult.GetDirectoryEntry().Properties["samaccountname"].Value.ToString(); }
                    else { samsaccountname = ""; }
                    ListViewItem lvi = new ListViewItem(samsaccountname);
                    //lvi.SubItems.Add(givenName);
                    //lvi.SubItems.Add(sn);
                    //lvi.SubItems.Add(mail);
                    listView1.Items.Add(lvi);
                }
                listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
            }
            catch
            {
                // Add error handling.
            }
        }

这是我在PowerShell + C#中所做的

private string SearchDLScript(string searchDL)
{
    listViewSearchDL.Items.Clear();
    listViewSearchDL.Columns.Clear();
    listViewSearchDL.Columns.Add("");
    listViewSearchDL.Items.Add("Loading list, please wait.");
    listViewSearchDL.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
    if (textSearchDL.Text.Length < 8)
    {
        listViewSearchDL.Items.Add("Hint: The more you type, the quicker the seach.");
        listViewSearchDL.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
    }
    string rbName = "";
    if (radioButtonDisplayName.Checked == true)
    {
        rbName = "DisplayName";
    } else if (radioButtonAlias.Checked == true)
    {
        rbName = "SamAccountName";
    }
    string searchDLScriptCommand = @"Import-Module ActiveDirectory
        Get-ADGroup -Filter '"+rbName+ @" -Like """ + searchDL + @"*"" ' -Properties * | Select-Object DisplayName,SamAccountName | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1";
    string scriptOutput = RunPowerShellCommands.RunPowerShellCode(searchDLScriptCommand);
    string[] strArr = scriptOutput.Split(new string[] { System.Environment.NewLine }, StringSplitOptions.None);
    strArr = strArr.Where(x => !string.IsNullOrEmpty(x)).ToArray();
    listViewSearchDL.Columns.Clear();
    listViewSearchDL.Items.Clear();
    listViewSearchDL.Columns.Add("Display Name");
    listViewSearchDL.Columns.Add("Alias");
    foreach (string user in strArr)
    {
        string userDetails = user.Replace("'"", "");
        string[] columns = userDetails.Split(',');
        ListViewItem lvi = new ListViewItem(columns[0]);
        for (int i = 1; i < columns.Count(); i++)
        {
            lvi.SubItems.Add(columns[i]);
        }
        listViewSearchDL.Items.Add(lvi);
    }
    if (scriptOutput == "'r'n")
    {
        listViewSearchDL.Items.Clear();
        listViewSearchDL.Columns.Clear();
        listViewSearchDL.Columns.Add("");
        listViewSearchDL.Items.Add("There are no records");
    }
    listViewSearchDL.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
    listViewSearchDL.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);

    return "scriptOutput";
}

PowerShell AD 查询与 C# AD 查询 - 速度

在 C# 示例中,通过调用 GetDirectoryEntry(),对 DirectorySearcher 返回的对象隐式执行两个额外的查找:

foreach (SearchResult searchresult in rsAll)
{
    if (searchresult.GetDirectoryEntry().Properties["samaccountname"].Value != null)
    { samsaccountname = searchresult.GetDirectoryEntry().Properties["samaccountname"].Value.ToString(); }
    else { samsaccountname = ""; }
    // and then updating the listview
}

GetDirectoryEntry()的文档甚至警告您这一点:

注意
在通过 DirectorySearcher 返回的每个搜索结果上调用 GetDirectoryEntry 可能会很慢。


您要做的是将所需的属性名称列表添加到搜索器(这是 Get-AD* -Properties 参数在后台执行的操作(,并在第一次搜索后返回它们:

DirectorySearcher ds = new DirectorySearcher(de);
// do this before calling FindAll()
ds.PropertiesToLoad.Add("samaccountname")

然后在处理搜索结果时,直接从每个搜索结果中获取属性值,而不是再次调用GetDirectoryEntry()

foreach (SearchResult searchresult in rsAll)
{
    if (searchresult.Properties["samaccountname"].Value != null)
    { 
        samsaccountname = searchresult.Properties["samaccountname"].Value.ToString(); 
    }
    else 
    { 
        samsaccountname = ""; 
    }
    // and then updating the listview
}