DirectoryEntry to change password: Different behavior between Vista/Server2008
Asked Answered
E

2

6

On a Vista dev machine I used this code successfully to change user "Administrator" password:

directoryEntry.Invoke("SetPassword", "new");

When I moved it over to my Server 2008 dev machine that code did not work, and I was forced to use the following code:

directoryEntry.Invoke("ChangePassword", new object[] { "old", "new" });

My question is, why?

For both cases, I created my DirectoryEntry object as such:

DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("WinNT://{0}/{1}", computerName, username));

Thanks! 8)

In case you guys find it helpful, heres the actual code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.DirectoryServices;
using System.Security.Principal;

namespace AccountMod
{
   class Program
   {
        static void Main()
        {
           Console.WriteLine("Attempting reset...\n");
           try
           {
               String machineNameAndUser =    WindowsIdentity.GetCurrent().Name.ToString();
               String machineName =    WindowsIdentity.GetCurrent().Name.ToString().Substring(0,    machineNameAndUser.IndexOf('\\'));
            Console.WriteLine("Computer's name: " + machineName);
            ResetPassword(machineName, "Administrator", "new");
            //ChangePassword("Administrator", "current", "new");                      Console.WriteLine("Finished...");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
                Console.WriteLine(e.InnerException);
            }
            Console.ReadKey();

        }

        public static void ResetPassword(string computerName, string username, string newPassword)
        {
            DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("WinNT://{0}/{1}", computerName, username));
            directoryEntry.Invoke("SetPassword", newPassword);
            //directoryEntry.Invoke("ChangePassword", new object[] { "current", "new" });
        }
    }
}
Ebon answered 11/4, 2010 at 1:37 Comment(2)
Any details of how you knew it failed - i.e., was there an Exception?Moonwort
Oh, and if there was an exception, could you please post the entire exception? That is, post the complete output of ex.ToString().Akilahakili
C
5

Are you (or could you upgrade to) .NET 3.5? The AD integration for users, groups, computers has been massively improved in .NET 3.5 - check out the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 for details.

In your case, you could do something like:

// establish context for local machine
PrincipalContext ctx = new PrincipalContext(ContextType.Machine);

// find the "Administrator" account
UserPrincipal admin = UserPrincipal.FindByIdentity(ctx, "Administrator");

// set the password to a new value
admin.SetPassword("new-top-secret-password");
admin.Save();

and you're done! The WinNT: provider is very limited in what it can do and should be avoided if ever possible.

Contuse answered 11/4, 2010 at 6:51 Comment(2)
Thanks! I like this solution and will use it in exchange for the WinNT provider.Ebon
Do I need the old password to set a new one?Affray
A
0

Check user properties for which you want to set password, if

user cannot change password

property is checked then u cant set password by using directoryEntry.Invoke("SetPassword", "new");Use admin credential while creating DirectoryEntry object or uncheck " user cannot change password" property

Arri answered 1/2, 2013 at 7:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.