В рамках разработки системы программного удалённого администрирования, написал функцию смены пароля локального пользователя Windows, решил выложить, может кому пригодится.

История написания этой функции такова — однажды  у админов возникла необходимость сменить пароль локального пользователя Administrator на всех компах.  Проблема — обойти все 300 с лишним компов. Тогда и была написана эта функция и к ней агент выполняющий её на конечных компьютерах. Потом были добавлены и другие функции —  копирование/удаление файлов, модификация реестра, запуск программ, включение/отключение служб…

unit modChangePass;

interface

uses
  Windows, SysUtils;

function SetUserPassword(UserName, NewPassword: string; var ErrMsg: string;
  var UserNotFound: boolean): boolean;

implementation

const
  NetApi32 = 'netapi32.dll';

  NERR_Success      = 0;
  NERR_BASE         = 2100;
  NERR_UserNotFound = NERR_BASE + 121; // The user name could not be found.

type
  USER_INFO_1 = record
    usri1_name: PWideChar;
    usri1_password: PWideChar;
    usri1_password_age: DWORD;
    usri1_priv: DWORD;
    usri1_home_dir: PWideChar;
    usri1_comment: PWideChar;
    usri1_flags: DWORD;
    usri1_script_path: PWideChar;
  end;
  PUSER_INFO_1 = ^USER_INFO_1;

function NetUserGetInfo(servername, username: PWideChar;
  level: DWORD; var bufptr: PByte): DWORD; stdcall;
external netapi32 name 'NetUserGetInfo';

function NetUserSetInfo(servername, username: PWideChar;
  level: DWORD; buf: PByte; parm_err: PDWORD): DWORD; stdcall;
external netapi32 name 'NetUserSetInfo';

function NetApiBufferFree(Buffer: Pointer): DWORD; stdcall;
external netapi32 name 'NetApiBufferFree';

function Str2Wide(lpStr: String):PWideChar;
var
  dwStrlen : Cardinal;
begin
  dwStrLen := lstrlen(PChar(lpStr));
  GetMem(Result,(dwStrLen+1)*2);
  StringToWideChar(lpStr,Result,dwStrLen+1);
end;

function SetUserPassword(UserName, NewPassword: string; var ErrMsg: string; var UserNotFound: boolean): boolean;
var
  wname: PWideChar;
  parm_err: DWORD;
  ecode: integer;
  buf: PByte;
  u1: USER_INFO_1;
begin
  wname:=Str2Wide(UserName);

  try
    try
      ecode:=NetUserGetInfo(nil, wname, 1, buf);
      try
        result:=(ecode=NERR_SUCCESS);
        UserNotFound:=(ecode=NERR_UserNotFound);
        if not result then begin
          ErrMsg:=SysErrorMessage(ecode);
          exit;
        end;

        u1:=PUSER_INFO_1(buf)^;

        u1.usri1_password:=Str2Wide(NewPassword);
        try
          ecode:=NetUserSetInfo(nil, u1.usri1_name, 1, @u1, @parm_err);
          result:=(ecode=NERR_SUCCESS);
          if not result then
            ErrMsg:=SysErrorMessage(ecode);
        finally
          FreeMem(u1.usri1_password);
          u1.usri1_password:=nil;
        end;

      finally
        NetApiBufferFree(buf);
      end;
    finally
      FreeMem(wname);
    end;
  except
    on E:Exception do begin
      ErrMsg:=E.ClassName+': '+E.Message;
      Result:=false;
    end;
  end;
end;

end.

Писали ли Вы свои механизмы удаленного управления компьютером клиента?

Результат

Загрузка ... Загрузка ...