使用remove()无法从List中删除项目

时间:2015-04-06 03:07:53

标签: c# visual-studio-2010 list foreach

您好我想在方法readInput 中使用foreach删除帐户名称,该帐户将帐户发送到方法DisableADUser ,该帐户将禁用帐户并从中删除名称如果操作成功,则全局列表invalidAccounts (整个代码行7)。

我尝试使用Remove方法并将其放在DisableADUser方法中的if和else条件中,但它不起作用。我该如何解决这个问题?提前致谢。 :)

readInput方法(第1-1行)

//Read user input
    private static string readInput(string Input)
    {

        string input = string.Empty;

        switch (Input) 
        {
                case "disable":

                invalidAccount.ForEach(delegate(String samAccountName)
                  {
                      Console.WriteLine('\n' + samAccountName);

                      //disable inactive accounts
                      DisableADUser(samAccountName);

                  });


                  //count number of invalid accounts
                  int invalidAccounts = invalidAccount.Count;

                  Console.WriteLine("\nExecution has completed. ");

                  invalidAccount.Clear();

                  Console.WriteLine("Press [enter] to continue.\n");

                  input = Console.ReadLine();

                  break;

                case "query":

                    Console.WriteLine("\nQuery for expiry has finished.\n");

                    Console.WriteLine("Press [enter] to continue.\n");

                    input = Console.ReadLine();

                    break;

                case "exit":

                    //leave console
                    Environment.Exit(2);

                    break;

                default:
                    throw new Exception("Invalid command entered.");
      }

        return input;
}

disableADUser(第1至15行)

    //disable invalid accounts
    private static void DisableADUser(string samAccountName)
    {
        try
        {
            PrincipalContext principalContext = new PrincipalContext(ContextType.Domain);

            UserPrincipal userPrincipal = UserPrincipal.FindByIdentity
                    (principalContext, samAccountName);

            userPrincipal.Enabled = false;

            userPrincipal.Save();

            if (userPrincipal.Enabled != true)
            {
                Console.WriteLine("Account has been disabled successfully");

                //remove from list invalidAccounts
                invalidAccount.Remove(samAccountName);
            }
            else
            {
                Console.Write("Unable to disable account");

                //invalidAccount.Remove(samAccountName);
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

如果需要,我也包含了我的整个代码。

namespace ConsoleApplication2
{
class Program
{
    const int UF_LOCKOUT = 0x0010;

    const int UF_PASSWORD_EXPIRED = 0x800000;

    private static List<string> invalidAccount = new List<string>();

    static void Main(string[] args)
    {

        string line;

        Console.WriteLine("Welcome to account validator V1.1.\n");

        do
        {

        Console.WriteLine("Please enter service account username, password \nand desired ldap address to proceed.\n\n");

        //pass username to GetInput method
        String serviceAccountUserName = GetInput("Username");

        //pass password to GetInput method
        String serviceAccountPassword = GetInput("Password");

        //pass ldap address to GetInput method
        String ldapAddress = GetInput("Ldap address");

        try
        { 

            using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, ldapAddress))
            {
                bool isValid = false;

                // validate the credentials
                isValid = pc.ValidateCredentials(serviceAccountUserName, serviceAccountPassword);

                if (isValid)
                {

                    Console.WriteLine("\nQuerying for users from domain " + ldapAddress + " now.\n\n");

                        //pass login details to GetSAM method
                        GetSAM(ldapAddress, serviceAccountUserName, serviceAccountPassword);

                        Console.WriteLine("\nEnter exit to leave.\n");

                        Console.WriteLine("Enter disable to disable the invalid accounts.\n");

                        Console.WriteLine("Enter query to find the expiry date of valid accounts.\n");

                        string Input = Console.ReadLine();

                        //pass input to readInput method
                        readInput(Input);

                        Console.WriteLine("\nEnter exit to leave.");

                        Console.WriteLine("Press [enter] to query database.");

                }//end of if statement for validate credentials


                else
                {
                    Console.WriteLine("\nInvalid login credentials.\n");

                    Console.WriteLine("Press [enter] and enter exit to leave.");

                    Console.WriteLine("\nPress [enter] [enter] to try again.\n");

                    Console.ReadLine();

                }//end of else statement for validate credentials

            }//end of using

        }//end of try 

        catch (Exception e)
        {
            Console.WriteLine("\nlogin attempt has failed. See exception for more information. ");

            throw new Exception("Log in attempt has failed." + " Exception caught:\n\n" + e.ToString());

        }//end of catch

        }//end of do

        while ((line = Console.ReadLine()) != "exit");

        //Thread.Sleep(60000);
    } //end of main


    //Read user input
    private static string readInput(string Input)
    {

        string input = string.Empty;

        switch (Input) 
        {
                case "disable":

                invalidAccount.ForEach(delegate(String samAccountName)
                  {
                      Console.WriteLine('\n' + samAccountName);

                      //disable inactive accounts
                      DisableADUser(samAccountName);

                  });


                  //count number of invalid accounts
                  int invalidAccounts = invalidAccount.Count;

                  Console.WriteLine("\nExecution has completed. " + invalidAccounts + " invalid accounts have been disabled.");

                  invalidAccount.Clear();

                  Console.WriteLine("Press [enter] to continue.\n");

                  input = Console.ReadLine();

                  break;

                case "query":

                    Console.WriteLine("\nQuery for expiry has finished.\n");

                    Console.WriteLine("Press [enter] to continue.\n");

                    input = Console.ReadLine();

                    break;

                case "exit":

                    //leave console
                    Environment.Exit(2);

                    break;

                default:
                    throw new Exception("Invalid command entered. Please enter command again.");
      }

        return input;
}

    // find password expiry date


    //Get SAMAccount
    private static string GetSAM(string ldapAddress, string serviceAccountUserName, string serviceAccountPassword)
    {

        string readOutput;

        int countAll = 0;

        string ldapPath = "LDAP://" + ldapAddress;

        string ldapFilter = "(&(objectclass=user)(objectcategory=person))";

        DirectoryEntry directoryEntry = new DirectoryEntry(ldapPath, serviceAccountUserName, serviceAccountPassword);

        using (DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry))
        {
            string samAccountName;

            directorySearcher.Filter = ldapFilter;

            directorySearcher.SearchScope = SearchScope.Subtree;

            directorySearcher.PageSize = 1000;

            using (SearchResultCollection searchResultCollection = directorySearcher.FindAll())
            {

                foreach (SearchResult result in searchResultCollection)
                {
                    samAccountName = result.Properties["sAMAccountName"][0].ToString();

                    //validate accounts by passing details into valSAM method
                    if (valSAM(samAccountName, ldapAddress, serviceAccountUserName, serviceAccountPassword) != true)
                    {
                        //add invalid account to list invalidAccount
                        invalidAccount.Add(samAccountName);
                    }

                    //count all accounts
                    countAll++;

                }  //end of foreach

                // Count all invalid accounts 
                int invalidAccounts = invalidAccount.Count;

                Console.WriteLine("\nFound " + invalidAccounts + " invalid accounts out of " + countAll + " user accounts.\n");

                Console.WriteLine("Query in " + ldapAddress + " has finished.");

                Console.WriteLine("Press [enter] to continue.\n");

                readOutput = Console.ReadLine();

            }//SearchResultCollection will be disposed here
        }

        return readOutput;

    }


    //Validate SAMAccount
    private static bool valSAM(string samAccountName, string ldapAddress, string serviceAccountUserName, string serviceAccountPassword)
    {
        string ldapPath = "LDAP://" + ldapAddress;

        DirectoryEntry directoryEntry = new DirectoryEntry(ldapPath, serviceAccountUserName, serviceAccountPassword);

        StringBuilder builder = new StringBuilder();

        bool accountValidation = false;

        //create instance fo the directory searcher
        DirectorySearcher desearch = new DirectorySearcher(directoryEntry);

        //set the search filter
        desearch.Filter = "(&(sAMAccountName=" + samAccountName + ")(objectcategory=user))";

        //find the first instance
        SearchResult results = desearch.FindOne();

        using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, ldapAddress))
        {

            //if users are present in database
            if (results != null)
            {

                //Check if account is activated
                bool isAccountActived = IsActive(results.GetDirectoryEntry());

                //Check if account is expired or locked
                bool isAccountLocked = IsAccountLockOrExpired(results.GetDirectoryEntry());

                accountValidation = ((isAccountActived != true) || (isAccountLocked));

                //account is invalid 
                if (accountValidation)
                {
                    builder.Append("User account " + samAccountName + " is invalid. ");

                    if ((isAccountActived != true) && (isAccountLocked))
                    {
                        builder.AppendLine("Account is inactive and locked or expired.");
                    } else if (isAccountActived != true)
                    {
                        builder.AppendLine("Account is inactive.");
                    }
                    else if (isAccountLocked)
                    {
                        builder.AppendLine("Account is locked or has expired.") ;
                    }
                    else
                    {
                        builder.AppendLine("Unknown reason. Contact admin for help.");
                    }

                    accountValidation = false;

                }

                //account is valid
                if ((isAccountActived) && (isAccountLocked != true))
                {
                    builder.AppendLine("User account " + samAccountName + " is valid.");

                    accountValidation = true;
                }

            }
            else Console.WriteLine("No users found.");

            //print only invalid accounts
            if (!accountValidation)
            {
                //prevent printing of empty lines
                if (builder.Length > 0)
                {
                    Console.WriteLine(builder);
                }
            }

        }//end of using

        return accountValidation;

    }


    //Prevent empty user input
    private static string GetInput(string Prompt)
    {

        string Result = string.Empty;

        do
        {
            Console.Write(Prompt + ": ");

            Result = Console.ReadLine();

            if (string.IsNullOrEmpty(Result)) Console.WriteLine("Empty input, please try again.\n");

        } 

        while (!(!string.IsNullOrEmpty(Result)));

        return Result;

    }


    //check if account is active
    static private bool IsActive(DirectoryEntry de)
    {
        if (de.NativeGuid == null) return false;

        int flags = (int)de.Properties["userAccountControl"].Value;

        return !Convert.ToBoolean(flags & 0x0002);
    }

    //check if account is locked or expired
    static private bool IsAccountLockOrExpired(DirectoryEntry de)
    {
        string attribName = "msDS-User-Account-Control-Computed";

        de.RefreshCache(new string[] { attribName });

        int userFlags = (int)de.Properties[attribName].Value;

        return userFlags == UF_LOCKOUT || userFlags == UF_PASSWORD_EXPIRED;
    }


    //disable invalid accounts
    private static void DisableADUser(string samAccountName)
    {
        try
        {
            PrincipalContext principalContext = new PrincipalContext(ContextType.Domain);

            UserPrincipal userPrincipal = UserPrincipal.FindByIdentity
                    (principalContext, samAccountName);

            userPrincipal.Enabled = false;

            userPrincipal.Save();

            if (userPrincipal.Enabled != true)
            {
                Console.WriteLine("User " + samAccountName + "'s account has been disabled successfully");

                //remove from list invalidAccounts
                invalidAccount.Remove(samAccountName);
            }
            else
            {
                Console.Write("Unable to disable account");

                //invalidAccount.Remove(samAccountName);
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }


}
}

1 个答案:

答案 0 :(得分:1)

您无法从正在迭代的列表中删除项目。它与调查员混淆,从它下面删除东西。您需要将要保留的项目复制到另一个列表中,然后在必要时将其复制回来;或者创建一个要删除的项目列表,并在结尾处一次删除它们。

这讨论了各种方法:Intelligent way of removing items from a List<T> while enumerating in C#