Click here to Skip to main content
15,881,516 members
Articles / Programming Languages / C#
Article

Windows OS User Management

Rate me:
Please Sign up or sign in to vote.
4.52/5 (14 votes)
30 Mar 20072 min read 70.2K   1.2K   37   11
Shows how to manage Windows local user accounts
Screenshot - OSUserManagement.gif

Introduction

Sometimes you may need your application to administer Windows user accounts by itself. Your application need to create OS user, modify its description, change password and perhaps delete the account when account is not needed any more. When I searched web sites for help (including msdn), I found various resources for this topic. But either they were not descriptive or with not enough source code. Some of them were in interpreted web scripts such as VBscript and Javascript. So, I collected work of all these great code contributors. And I have tried to modify these codes to suit your needs.
In this project, I have created a class called "SysUserManager". Main functions are written here. Another form is also created, from where these functions are called.

Namespaces used and steps to add them:

  1. System.DirectoryServices
    1. Choose "Project>Add Reference".
    2. Click on ".NET" tab.
    3. Select "System.DirectoryServices" from the list.
    4. Click on "Ok".
    5. Type "using System.DirectoryServices;" to import this namespace.
  2. Interop.ActiveDS and Interop.TSUSEREXLib (Only if you donot have them, for now, they are included in this application package)
    1. Download package "ADMODIFY.NET 2.1" from site:
      http://www.gotdotnet.com/workspaces/workspace.aspx?id=f5cbbfa9-e46b-4a7a-8ed8-3e44523f32e2
    2. Unzip files to a local directory.
    3. From your solution, choose "Project>Add Reference".
    4. Click on "Browse" tab.
    5. From the location where you have unzipped the package "ADMODIFY", select Interop.ActiveDs.dll and Interop.TSUSEREXLib.dll files.
    6. Click on "OK".
    7. Type "using System.Runtime.InteropServices;" to use these files.

Using the code

We have to use "directoryentry" class for OS user management. For directoryentry constructor, we need to have a connection string. Format of this string is "PROTOCOL://HOSTNAME,COMPUTER". For "protocol", we can use "WinNT" protocol to manage local user accounts. For domain accounts, we use "LDAP" protocol. While creating user, we can set various properties for that user such as "password", "description", "groups" and "flags". For "flags", we use different constant values. At last, we must issue "commitchanges()" method to save user we created. If you are running this application in Terminal Server, you can also set the code to place initial program name to start in your code.
Algorithm for the code is as follows:

  1. Create a directory entry that represents host machine.
  2. Check whether user already exists or not.
  3. Create another directory entry for new user.
  4. Set new Password (using Invoke method) for this user.
  5. If description is given in application, set description as well.
  6. Set user options as set in application. (We are using constants here to represent hex values)
  7. Confirm changes by using "CommitChanges()" method.
  8. If group is provided, add user to group.
  9. Optional step (Only for TS Servers):
    1. Set "Initial Program" and "Working Directory" for the user.

Code:

try
            {
                //Initiate DirectoryEntry Class To Connect Through WINNT Protocol
                string entryString = "WinNT://" + Environment.MachineName + ",computer";
                DirectoryEntry dirEntry = new DirectoryEntry(entryString);              
                
                    
                //Search If Specified User Already Exists
                bool userFound = false;

                try
                {
                    if (dirEntry.Children.Find(username, "user") != null)
                        userFound = true;
                }
                catch
                {
                    userFound = false;
                }

                
                if (!userFound) //If User Not Found In System
                {
                    DirectoryEntry newUser = dirEntry.Children.Add(username, "user"); //Add user
                    newUser.Invoke("SetPassword", new object[] { password }); //Set password
                    
                    if(description.Trim()!="") newUser.Invoke("Put", new object[] {"Description", description});

                    
                    //Flags
                    //1. User cannot change password
                    int ADS_UF_PASSWD_CANT_CHANGE = 0x000000040;
                    //newUser.Invoke("Put", new Object[] { "userFlags", ADS_UF_PASSWD_CANT_CHANGE });

                    //2. Password Never Expires
                    int ADS_UF_DONT_EXPIRE_PASSWD = 0x00010000;
                    //newUser.Invoke("Put", new Object[] { "userFlags", ADS_UF_DONT_EXPIRE_PASSWD });

                    int combinedFlag=0;
                    if(cannotchangepassword&&passwordneverexpires) 
                        combinedFlag = ADS_UF_DONT_EXPIRE_PASSWD | ADS_UF_PASSWD_CANT_CHANGE;
                    else if(cannotchangepassword)
                        combinedFlag = ADS_UF_PASSWD_CANT_CHANGE;
                    else if(passwordneverexpires)
                        combinedFlag = ADS_UF_DONT_EXPIRE_PASSWD;

                    //3. Account Disabled
                    if (!active)
                    {
                        int ADS_UF_ACCOUNTDISABLE = 0x0002;
                        combinedFlag = combinedFlag | ADS_UF_ACCOUNTDISABLE;
                    }

                    
                    newUser.Invoke("Put", new Object[] { "userFlags", combinedFlag });
                    
                    //Commit Changes
                    newUser.CommitChanges();

                    returnVal = "success";

                    //If defaultGroup Is Provided, Add New User To This Group
                    if (defaultGroup.Trim() != "")
                    {
                        try
                        {
                            DirectoryEntry grpEntry = dirEntry.Children.Find(defaultGroup, "group");
                            if (grpEntry != null)
                            {
                                //Add User To defaultGroup
                                grpEntry.Invoke("Add", new object[] { newUser.Path.ToString() });
                            }
                        }
                        catch(Exception ex)
                        {
                            returnVal = _ErrorMsg = ex.Message;
                        }

                    }

                    try
                    {
                        DirectoryEntry userDE = dirEntry.Children.Find(username, "user");

                        //For Terminal Settings (Only If this is Terminal Server)
                        ActiveDs.IADsUser iADsUser = (ActiveDs.IADsUser)userDE.NativeObject;
                        m_TsUser = (TSUSEREXLib.IADsTSUserEx)iADsUser;

                        m_TsUser.TerminalServicesInitialProgram = "Notepad.exe"; //For Example
                        m_TsUser.TerminalServicesWorkDirectory = Environment.GetEnvironmentVariable("windir");

                        userDE.CommitChanges();
                    }
                    catch {  }
                   

                } 
                else //If User Already Exists
                {
                    returnVal = "User already exists!";
                } //End of - if (!userFound)

                _ErrorMsg = "";
               
            catch (Exception ex)
            {
                returnVal = _ErrorMsg = ex.Message;
            } 

 

Code to modify user settings, deleting user etc. is included in the project.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


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

Comments and Discussions

 
General- Pin
MohammadaliToofani8-May-10 20:22
MohammadaliToofani8-May-10 20:22 
GeneralCode is a bit rough, but it shows the major points Pin
jeroenp11-Oct-09 1:59
jeroenp11-Oct-09 1:59 
GeneralSetPassword can be bad Pin
Member 319984818-Aug-08 12:19
Member 319984818-Aug-08 12:19 
GeneralRe: SetPassword can be bad Pin
Ashutosh Bhawasinka12-Jan-09 6:13
Ashutosh Bhawasinka12-Jan-09 6:13 
Generalshowed the way... Thx! Pin
baskint25-Feb-08 9:53
baskint25-Feb-08 9:53 
Generalchange password of windows 2003 server user by remote machine Pin
pprabhu5-Dec-07 18:30
pprabhu5-Dec-07 18:30 
QuestionHow to also remove user's profile directory Pin
mstavrev26-Oct-07 5:14
mstavrev26-Oct-07 5:14 
GeneralThe error occur when modify user Pin
stevenyoung31-Mar-07 13:55
stevenyoung31-Mar-07 13:55 
GeneralRe: The error occur when modify user Pin
Ritesh_Singh31-Mar-07 20:01
Ritesh_Singh31-Mar-07 20:01 
GeneralAPIs too Pin
Vasudevan Deepak Kumar31-Mar-07 4:54
Vasudevan Deepak Kumar31-Mar-07 4:54 
GeneralA little blunt but definitely informative Pin
Rei Miyasaka31-Mar-07 0:18
Rei Miyasaka31-Mar-07 0:18 
Funny how sometimes at first glance, an article looks like it's just stating the obvious.

But then you realize that you would have never managed to dig up such information elsewhere.

Thanks!

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.