How to programmatically create Windows user accounts on Windows 7 or Windows Server 2008?

7

I've been trying to create new local user accounts on windows 7 machine. I used the System.DirectoryServices.DirectoryEntry class (as in here) but it doesn't seem to work.

Here's the code in the article:

static void Main(string[] args)
{
try
    {
 DirectoryEntry AD = new DirectoryEntry("WinNT://" + 
                     Environment.MachineName + ",computer");
 DirectoryEntry NewUser = AD.Children.Add("TestUser1", "user");
 NewUser.Invoke("SetPassword", new object[] {"#12345Abc"});
 NewUser.Invoke("Put", new object[] {"Description", "Test User from .NET"});
 NewUser.CommitChanges();
 DirectoryEntry grp;

 grp = AD.Children.Find("Guests", "group");
 if (grp != null) {grp.Invoke("Add", new object[] {NewUser.Path.ToString()});}
 Console.WriteLine("Account Created Successfully");
 Console.ReadLine();
}
catch (Exception ex)
{
 Console.WriteLine(ex.Message);
 Console.ReadLine();

}
}

When executing this line

DirectoryEntry NewUser = AD.Children.Add("TestUser1", "user");

I get a

System.Runtime.InteropServices.COMException with "{"Unknown error (0x80005000)"}"

as the exception message, and -2147463168 as the error code.

I assume this is probably because the article targets Windows XP and below machines, and I'm targeting windows 7 and Windows server 2008.

Any help appreciated!

Update:
For some mysterious reason, i'm no longer seeing that System.Runtime.InteropServices.COMException, however, when committing the changes here newuser.CommitChanges(), I get a "UnAuthorizedAccessException". I tried running the app as administrator, but still not working.

Update 2:
OK, after changing to the UserPrincipal class, i got the follwoing code to work:

public UserPrincipal CreateNewUser(string sUserName, string sPassword)
        {
            // first check that the user doesn't exist
            if (GetUser(sUserName) == null)
            {
                PrincipalContext oPrincipalContext = GetPrincipalContext();

                UserPrincipal oUserPrincipal = new UserPrincipal(oPrincipalContext);
                oUserPrincipal.Name = sUserName;
                oUserPrincipal.SetPassword(sPassword);
                //User Log on Name
                //oUserPrincipal.UserPrincipalName = sUserName;
                oUserPrincipal.Save();

                return oUserPrincipal;
            }

            // if it already exists, return the old user
            return GetUser(sUserName);
        }
    }


This code runs well when I run it as a console app -of course run as administrator- but when i deployed it as a windows service, with the security account set as "LocalSystem", i get an InvlaidOperationException saying "The underlying store does not support this property"

Thoughts?

c#
windows-7
asked on Stack Overflow May 12, 2011 by Galilyou • edited Jun 2, 2011 by Galilyou

2 Answers

8

OK, if you check my last update, the following snippet worked:

public UserPrincipal CreateNewUser(string sUserName, string sPassword)
        {
            // first check that the user doesn't exist
            if (GetUser(sUserName) == null)
            {
                PrincipalContext oPrincipalContext = GetPrincipalContext();

                UserPrincipal oUserPrincipal = new UserPrincipal(oPrincipalContext);
                oUserPrincipal.Name = sUserName;
                oUserPrincipal.SetPassword(sPassword);
                //User Log on Name
                //oUserPrincipal.UserPrincipalName = sUserName;
                oUserPrincipal.Save();

                return oUserPrincipal;
            }

            // if it already exists, return the old user
            return GetUser(sUserName);
        }
    }

That worked as a console app, but failed to execute due to security exceptions when deployed as a windows service. A solution is to trust that assembly (the windows service assembly) so that the .net security will let it run. That's done, now everything is cool!

answered on Stack Overflow Jul 26, 2011 by Galilyou
0

You need to prefix your username with CN=, like so:

DirectoryEntry NewUser = AD.Children.Add("CN=TestUser1", "user");

answered on Stack Overflow May 13, 2011 by Warren Rumak

User contributions licensed under CC BY-SA 3.0