DirectoryEntry to change password: Different behavior between Vista/Server2008

11,703

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.

Share:
11,703
Admin
Author by

Admin

Updated on June 05, 2022

Comments

  • Admin
    Admin almost 2 years

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