DirectoryEntry для смены пароля: различное поведение между Vista/Server2008

На компьютере с Vista я успешно использовал этот код для изменения пароля пользователя «Администратор»:

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

Когда я перенес его на свою машину разработки Server 2008, этот код не работал, и мне пришлось использовать следующий код:

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

Мой вопрос, почему?

В обоих случаях я создал свой объект DirectoryEntry как таковой:

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

Спасибо! 8)

Если вы, ребята, сочтете это полезным, вот фактический код.

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

person sholsapp    schedule 11.04.2010    source источник
comment
Любые подробности о том, как вы узнали, что это не удалось, т.е. было ли исключение?   -  person Ruben Bartelink    schedule 11.04.2010
comment
О, и если было исключение, не могли бы вы опубликовать полное исключение? То есть опубликуйте полный вывод ex.ToString().   -  person John Saunders    schedule 11.04.2010


Ответы (2)


Вы (или могли бы перейти) на .NET 3.5? Интеграция с AD для пользователей, групп и компьютеров значительно улучшена в .NET 3.5 — ознакомьтесь со статьей MSDN Управление принципами безопасности каталогов в .NET Framework 3.5 для получения подробной информации.

В вашем случае вы можете сделать что-то вроде:

// 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();

и вы сделали! Провайдер WinNT: очень ограничен в своих возможностях, и его следует избегать, если это возможно.

person marc_s    schedule 11.04.2010
comment
Спасибо! Мне нравится это решение, и я буду использовать его в обмен на поставщика WinNT. - person sholsapp; 11.04.2010
comment
Нужен ли старый пароль для установки нового? - person VansFannel; 06.05.2014

Проверьте свойства пользователя, для которого вы хотите установить пароль, если

пользователь не может изменить пароль

свойство проверено, тогда вы не можете установить пароль, используя учетные данные администратора directoryEntry.Invoke("SetPassword", "new");Use при создании объекта DirectoryEntry или снимите флажок «пользователь не может изменить пароль» свойство

person sagar    schedule 01.02.2013