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

时间:2016-02-14 09:04:03

标签: c# powershell active-directory

我正在学习C#并且是新手。请耐心等待。

我在C#中开发了一个应用程序,通过将PowerShell命令输入到AD中来搜索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";
}

1 个答案:

答案 0 :(得分:5)

在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
}

The documentation for GetDirectoryEntry()甚至警告过你:

  

注意
  在通过DirectorySearcher返回的每个SearchResult上调用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
}