2016-02-14 2 views
3

Я изучаю C# и являюсь новичком. Пожалуйста, будьте терпеливы со мной.Запрос PowerShell AD vs C# AD Query - Speed ​​

Я разработал приложение на C# для поиска пользователей, групп и членов группы в AD с помощью команд Piping PowerShell.

Теперь я пытаюсь использовать DirectoryServices в C# для получения тех же результатов, однако время, необходимое для получения тех же результатов, намного дольше, чем в 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"; 
} 

ответ

5

В C# образца вы неявно выполнять два дополнительных поиска за объект, возвращенный DirectorySearcher, по телефону GetDirectoryEntry():

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() даже предупреждает вас об этом:

Примечание
Вызов GetDirectoryEntry на каждом SearchResult возвращается через DirectorySearcher может быть медленным.


То, что вы хотите сделать, это добавить в список имен свойств, которые вы должны будете поисковик (это то, что параметр 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 
} 
+0

Привет, Mathias, Спасибо за это, но изменение кода на выше (без GetDirectoryEntry()) дает мне ошибку «ResultPropertyValueCollection» не содержит определения «Значение» .... Я что-то пропустил в код? – Bhups

Смежные вопросы