Click here to Skip to main content
15,886,799 members
Articles / Programming Languages / C#

UserManager: a class to manipulate local Windows users and groups

Rate me:
Please Sign up or sign in to vote.
4.71/5 (12 votes)
2 Aug 2006CPOL 48.5K   754   40  
UserManager was built to simplify local users and groups manipulation
//************************************************************************************
// UserManager 
// Copyright (C) 2006, Massimo Beatini
//
// This software is provided "as-is", without any express or implied warranty. In 
// no event will the authors be held liable for any damages arising from the use 
// of this software.
//
// Permission is granted to anyone to use this software for any purpose, including 
// commercial applications, and to alter it and redistribute it freely, subject to 
// the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not claim 
//    that you wrote the original software. If you use this software in a product, 
//    an acknowledgment in the product documentation would be appreciated but is 
//    not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be 
//    misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
//************************************************************************************
using System;
using System.DirectoryServices;
using System.Collections;

namespace MBeatini
{
	/// <summary>
	/// UserManager.
    /// 
    /// This class contains a set of methods to create/modify 
    /// local windows users and groups using the WinNT ADSI provider.
	/// </summary>
	public class UserManager
	{
        /// <summary>
        /// Account options definition
        /// </summary>
        public enum ADAccountOptions
        {
            UF_TEMP_DUPLICATE_ACCOUNT = 0x0100,
            UF_NORMAL_ACCOUNT = 0x0200,
            UF_INTERDOMAIN_TRUST_ACCOUNT = 0x0800,
            UF_WORKSTATION_TRUST_ACCOUNT = 0x1000,
            UF_SERVER_TRUST_ACCOUNT = 0x2000,
            UF_DONT_EXPIRE_PASSWD = 0x10000,
            UF_SCRIPT = 0x0001,
            UF_ACCOUNTDISABLE = 0x0002,
            UF_HOMEDIR_REQUIRED = 0x0008,
            UF_LOCKOUT = 0x0010,
            UF_PASSWD_NOTREQD = 0x0020,
            UF_PASSWD_CANT_CHANGE = 0x0040,
            UF_ACCOUNT_LOCKOUT = 0x0010,
            UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x0080,
        }



		private string aErrMsg = "";

        /// <summary>
        /// this property exsposes the captured error messages
        /// </summary>
		public string ErrorMessage
		{
			get
			{
				return aErrMsg;
			}
		}

        /// <summary>
        /// constructor
        /// </summary>
		public UserManager()
		{
			//
			// TODO: Add constructor logic here
			//
        }


        #region Users

        /// <summary>
        /// 
        /// </summary>
        /// <param name="LoginName"></param>
        /// <param name="LoginPassword"></param>
        /// <returns></returns>
        public bool AddUser(string LoginName, string LoginPassword)
        {
            return 	AddUser(LoginName, LoginPassword, "", null);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="LoginName"></param>
        /// <param name="LoginPassword"></param>
        /// <param name="LoginDescription"></param>
        /// <returns></returns>
        public bool AddUser(string LoginName, string LoginPassword,
            string LoginDescription)
        {
            return AddUser(LoginName, LoginPassword, LoginDescription, null);
        }
 
        /// <summary>
        /// Create a new user
        /// </summary>
        /// <param name="LoginName"></param>
        /// <param name="LoginPassword"></param>
        /// <param name="LoginDescription"></param>
        /// <param name="defaultGroup"></param>
        /// <returns></returns>
        public bool AddUser(string LoginName, string LoginPassword,
                    string LoginDescription, string defaultGroup)
        {
            bool created = false;

            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    bool found = false;

                    try
                    {
                        found = AD.Children.Find(LoginName, "user") != null;
                    }
                    catch
                    {
                        found = false;
                    }

                    if (!found)
                    {
                        using (DirectoryEntry NewUser =
                                   AD.Children.Add(LoginName, "user"))
                        {
                            // set password
                            NewUser.Invoke("SetPassword", new object[] { LoginPassword });
                            // set description
                            NewUser.Invoke("Put", new object[] {"Description", 
															   LoginDescription});

                            NewUser.CommitChanges();

                            // set default option
                            //
                            //     UF_NORMAL_ACCOUNT
                            //     UF_PASSWD_CANT_CHANGE
                            //     UF_DONT_EXPIRE_PASSWD
                            SetDefaultOptionFlags(LoginName);

                            created = true;

                            if ((defaultGroup != null) && (defaultGroup.Trim().Length > 0))
                            {
                                DirectoryEntry grp = null;

                                try
                                {
                                    using (grp = AD.Children.Find(defaultGroup, "group"))
                                    {
                                        if (grp != null)
                                        {
                                            grp.Invoke("Add", new object[] { NewUser.Path.ToString() });
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    aErrMsg = ex.Message;
                                }
                            }

                        }
                    }
                    else
                        aErrMsg = "User already exists!";

                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }

            return created;
        }


        /// <summary>
        /// Delete user
        /// </summary>
        /// <param name="LoginName"></param>
        /// <returns></returns>
        public bool RemoveUser(string LoginName)
        {
            bool deleted = false;
            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    try
                    {
                        using (DirectoryEntry NewUser = AD.Children.Find(LoginName, "user"))
                        {
                            if (NewUser != null)
                            {
                                AD.Children.Remove(NewUser);
                                deleted = true;
                            }
                            else
                            {
                                aErrMsg = "User not found!";
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        aErrMsg = ex.Message;
                    }
                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }

            return deleted;
        }


        /// <summary>
        /// Set user's password
        /// </summary>
        /// <param name="LoginName"></param>
        /// <param name="LoginPassword"></param>
        /// <returns></returns>
        public bool SetUserPassword(string LoginName, string LoginPassword)
        {
            bool setted = false;

            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    using (DirectoryEntry NewUser = AD.Children.Find(LoginName, "user"))
                    {
                        NewUser.Invoke("SetPassword", new object[] { LoginPassword });

                        NewUser.CommitChanges();
                        setted = true;
                    }
                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }
            return setted;
        }

        /// <summary>
        /// Enable a user account
        /// </summary>
        /// <param name="LoginName"></param>
        /// <returns></returns>
        public bool EnableUser(string LoginName)
        {
            bool enabled = false;

            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    using (DirectoryEntry user = AD.Children.Find(LoginName, "user"))
                    {
                        PropertyValueCollection pv = user.Properties["userFlags"];

                        int currentAccountControl = (int)pv.Value;
                        int acctControlFlags = currentAccountControl - (int)ADAccountOptions.UF_ACCOUNTDISABLE;


                        user.Properties["userFlags"].Add(acctControlFlags);

                        user.CommitChanges();

                        enabled = true;
                    }
                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }
            return enabled;
        }


        /// <summary>
        /// Disable a user account
        /// </summary>
        /// <param name="LoginName"></param>
        /// <returns></returns>
        public bool DisableUser(string LoginName)
        {
            bool disabled = false;

            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    using (DirectoryEntry user = AD.Children.Find(LoginName, "user"))
                    {
                        PropertyValueCollection pv = user.Properties["userFlags"];

                        int currentAccountControl = (int)pv.Value;
                        int acctControlFlags = currentAccountControl | (int)ADAccountOptions.UF_ACCOUNTDISABLE;


                        user.Properties["userFlags"].Add(acctControlFlags);

                        user.CommitChanges();

                        disabled = true;
                    }
                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }
            return disabled;
        }

        /// <summary>
        /// Enable user setting default flags:
        /// 
        ///     UF_NORMAL_ACCOUNT
        ///     UF_PASSWD_CANT_CHANGE
        ///     UF_DONT_EXPIRE_PASSWD
        /// 
        /// </summary>
        /// <param name="LoginName"></param>
        private static void SetDefaultOptionFlags(string LoginName)
        {
            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {

                    using (DirectoryEntry NewUser = AD.Children.Find(LoginName, "user"))
                    {
                        PropertyValueCollection pv = NewUser.Properties["userFlags"];

                        int currentAccountControl = (int)pv.Value;

                        int acctControlFlags = currentAccountControl;
                        acctControlFlags = acctControlFlags | (int)ADAccountOptions.UF_NORMAL_ACCOUNT | (int)ADAccountOptions.UF_PASSWD_CANT_CHANGE | (int)ADAccountOptions.UF_DONT_EXPIRE_PASSWD;

                        NewUser.Properties["userFlags"].Add(acctControlFlags);

                        NewUser.CommitChanges();
                    }
                }
            }
            catch 
            {
            }
        }


        /// <summary>
        /// Add an option flag to a user 
        /// </summary>
        /// <param name="LoginName"></param>
        /// <param name="optionFlag"></param>
        /// <returns></returns>
        public bool AddOptionFlagToUser(string LoginName, int optionFlag)
        {
            bool flagAdded = false;

            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    using (DirectoryEntry user = AD.Children.Find(LoginName, "user"))
                    {
                        PropertyValueCollection pv = user.Properties["userFlags"];

                        int currentAccountControl = (int)pv.Value;
                        int acctControlFlags = currentAccountControl | optionFlag;


                        user.Properties["userFlags"].Add(acctControlFlags);

                        user.CommitChanges();

                        flagAdded = true;
                    }
                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }
            return flagAdded;
        }

        /// <summary>
        /// Remove an option flag to a user
        /// </summary>
        /// <param name="LoginName"></param>
        /// <param name="optionFlag"></param>
        /// <returns></returns>
        public bool RemoveOptionFlagToUser(string LoginName, int optionFlag)
        {
            bool flagRemoved = false;

            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    using (DirectoryEntry user = AD.Children.Find(LoginName, "user"))
                    {
                        PropertyValueCollection pv = user.Properties["userFlags"];

                        int currentAccountControl = (int)pv.Value;
                        int acctControlFlags = currentAccountControl - optionFlag;


                        user.Properties["userFlags"].Add(acctControlFlags);

                        user.CommitChanges();

                        flagRemoved = true;
                    }
                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }
            return flagRemoved;
        }


        /// <summary>
        /// Return a list containing 
        /// all the user properties
        /// </summary>
        /// <param name="LoginName"></param>
        /// <returns></returns>
        public ArrayList UserProperties(string LoginName)
        {
            ArrayList userprop = new ArrayList();
            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    try
                    {
                        DirectoryEntry usr = null;

                        using (usr = AD.Children.Find(LoginName, "user"))
                        {


                            ICollection n = usr.Properties.PropertyNames;
                            foreach (object o in n)
                            {
                                string val = o.ToString();
                                if (val == "PasswordAge")
                                {
                                    // password age in days
                                    int b = ((int)usr.Properties[o.ToString()].Value) / 60 / 60 / 24;
                                    val += " = " + b.ToString();

                                }
                                else if ((val == "LoginHours") || (val == "objectSid"))
                                {
                                    Byte[] b = (byte[])usr.Properties[o.ToString()].Value;
                                    val += " = ";
                                    foreach (Byte b1 in b)
                                        val += b1.ToString("X").PadLeft(2, '0') + " ";
                                    //val += " = " + Convert.ToBase64String(b);
                                }
                                else
                                    val += " = " + usr.Properties[o.ToString()].Value.ToString();
                                userprop.Add(val);
                            }

                        }
                    }
                    catch (Exception ex)
                    {
                        aErrMsg = ex.Message;
                    }

                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }
            return userprop;
        }


        /// <summary>
        /// return a list containing all
        /// the users
        /// </summary>
        /// <returns></returns>
        public ArrayList ListUsersInServer()
        {
            ArrayList userList = new ArrayList();
            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    try
                    {
                        //set a filter to enumerate only "user" objects
                        AD.Children.SchemaFilter.Add("user");
                        foreach (DirectoryEntry usr in AD.Children)
                        {
                            userList.Add(usr.Name);
                        }
                    }
                    catch (Exception ex)
                    {
                        aErrMsg = ex.Message;
                    }

                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }
            return userList;
        }



        #endregion

        #region Groups

        /// <summary>
        /// Create a new group
        /// </summary>
        /// <param name="GroupName"></param>
        /// <param name="Description"></param>
        /// <returns></returns>
        public bool AddGroup(string GroupName, string Description)
        {
            bool created = false;

            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    bool found = false;

                    try
                    {
                        found = AD.Children.Find(GroupName, "group") != null;
                    }
                    catch
                    {
                        found = false;
                    }

                    if (!found)
                    {
                        using (DirectoryEntry grp =
                                   AD.Children.Add(GroupName, "group"))
                        {
                            grp.Invoke("Put", new object[] {"Description", 
															   Description});

                            grp.CommitChanges();

                            created = true;
                        }
                    }
                    else
                        aErrMsg = "Group already exists!";
                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }

            return created;
        }

        /// <summary>
        /// Add a user to a group
        /// </summary>
        /// <param name="LoginName"></param>
        /// <param name="GroupName"></param>
        /// <returns></returns>
        public bool AddUserToGroup(string LoginName, string GroupName)
        {
            bool added = false;

            try
            {
                using (DirectoryEntry AD = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    
                    using (DirectoryEntry NewUser = AD.Children.Find(LoginName, "user"))
                    {
                        try
                        {
                            DirectoryEntry grp = null;

                            try
                            {
                                using (grp = AD.Children.Find(GroupName, "group"))
                                {
                                    if (grp != null)
                                    {
                                        grp.Invoke("Add", new object[] { NewUser.Path.ToString() });
                                        added = true;
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                aErrMsg = ex.Message;
                            }
                        }
                        catch (Exception ex)
                        {
                            aErrMsg = ex.Message;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }
            return added;
        }


        /// <summary>
        /// return a list containing all the
        /// user belonging to a group
        /// </summary>
        /// <param name="GroupName"></param>
        /// <returns></returns>
        public ArrayList ListUsersInGroup(string GroupName)
        {
            ArrayList groupMembers = new ArrayList();
            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
  
                    try
                    {
                        DirectoryEntry grp = null;

                        using (grp = AD.Children.Find(GroupName, "group"))
                        {
                            if (grp != null)
                            {

                                object members = grp.Invoke("Members", null);
                                foreach (object member in (IEnumerable)members)
                                {
                                    DirectoryEntry x = new DirectoryEntry(member);
                                    groupMembers.Add(x.Name);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        aErrMsg = ex.Message;
                    }

                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }
            return groupMembers;

        }

        /// <summary>
        /// return a list containing all
        /// the groups
        /// </summary>
        /// <returns></returns>
        public ArrayList ListGroupsInServer()
        {
            ArrayList groupList = new ArrayList();
            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    try
                    {
                        //set a filter to enumerate only "group" objects
                        AD.Children.SchemaFilter.Add("group");
                        foreach (DirectoryEntry grp in AD.Children)
                        {
                            groupList.Add(grp.Name);
                        }
                    }
                    catch (Exception ex)
                    {
                        aErrMsg = ex.Message;
                    }

                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }
            return groupList;
        }




        /// <summary>
        /// Return a list containing
        /// all the group properties
        /// </summary>
        /// <param name="GroupName"></param>
        /// <returns></returns>
        public ArrayList GroupProperties(string GroupName)
        {
            ArrayList groupprop = new ArrayList();
            try
            {
                using (DirectoryEntry AD = new
                           DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
                {
                    try
                    {
                        DirectoryEntry usr = null;

                        using (usr = AD.Children.Find(GroupName, "group"))
                        {


                            ICollection n = usr.Properties.PropertyNames;
                            foreach (object o in n)
                            {
                                string val = o.ToString();

                                if ((val == "LoginHours") || (val == "objectSid"))
                                {
                                    Byte[] b = (byte[])usr.Properties[o.ToString()].Value;
                                    val += " = " + Convert.ToBase64String(b);
                                }
                                else
                                    val += " = " + usr.Properties[o.ToString()].Value.ToString();
                                groupprop.Add(val);
                            }

                        }
                    }
                    catch (Exception ex)
                    {
                        aErrMsg = ex.Message;
                    }

                }
            }
            catch (Exception ex)
            {
                aErrMsg = ex.Message;
            }
            return groupprop;
        }

        #endregion



    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Italy Italy
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions