无法使用remove()从列表中删除项目 [英] Can't remove items from List with remove()

查看:352
本文介绍了无法使用remove()从列表中删除项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Hi I would like to remove account names by using a foreach in method readInput that sends the accounts to method DisableADUser that would disable the accounts and remove the name from the global List invalidAccounts (whole code line 7) if the operation is successful.

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

I have tried using the Remove method and placing it in both the if and else condition in the DisableADUser method but it does not work. How should I go about resolving this? Thanks in advance. :)

//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);
        }
    }

如果需要,我也包括了我的整个代码.

If needed, I've included my entire code as well.

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);
        }
    }


}
}

推荐答案

您无法从要迭代的列表中删除项目.它与枚举器弄乱了,以从其下面删除内容.您需要将要保留的项目复制到另一个列表中,然后在必要时将其复制回去.或创建要删除的项目列表,然后一次将其全部删除.

You can't Remove items from the list you are iterating. It messes with the enumerator to delete things out from under it. You need to copy the items you want to keep to another list instead, and then copy it back if necessary; or create a list of items you want to remove, and remove them all at once at the end.

这里讨论了各种方法:

This has a discussion of various methods: Intelligent way of removing items from a List<T> while enumerating in C#

这篇关于无法使用remove()从列表中删除项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆