您的位置:首页 > 编程语言 > Delphi

Delphi如何远程增加账号到本地管理员组同时远程添加计划任务

2013-09-18 15:42 603 查看
问题背景:

最近有大领导的硬盘坏了导致数据丢失,当然拿到外面去恢复,但没有全部恢复。所以这个incident就触发了一个问题, 如何避免发生类似的事情。所以我就想,能否尽可能早的检测出用户的硬盘的问题,在彻底坏之前就备份好数据并更换掉硬盘。

总体的思路:

我们知道如硬盘有问题了,比如坏道啊什么的,Windows系统会产生相应的一条日志。所以如果我们能够集中监测到用户的这类日志,就可以尽可能的避免数据丢失的事故发生。我们知道WINDOWS系统有一个event转发的功能,所以只要将所有用户的相应的日志转发到一台服务器上我们就可以实现集中监测了。同时我们知道:日志转发有两种方式:collector initiated和source initiated.  Source initiated 我们可以用GPO,但我们的GPO都要鬼佬来approve,如这样天知道什么时候能approve,甚至都不会approve.所以我就选择collector
initiated。但这样就产生一个问题,如何在每台机器上启用日志转发,另外这种方法的日志转发需要将服务器添加到在每台用户的本机管理员组内。

 

下面是源代码(需要NTSET Collection控件):

unit EventForwarding;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, IdBaseComponent, IdComponent, IdRawBase, IdRawClient,ComObj,ComCtrls,

  IdIcmpClient,StdCtrls, NTCommon, UserMan;

type

  TForm1 = class(TForm)

    Button1: TButton;

    IdIcmpClient1: TIdIcmpClient;

    Edit1: TEdit;

    NTUserMan1: TNTUserMan;

    Edit2: TEdit;

    Label1: TLabel;

    Label2: TLabel;

    Function PingResult(HostName:String):String;

    Function RunDosCommand(Command: string): string;

    Function GetTime(currenttime:TdateTime):String;

    Function WaitExeFinish(const sExeName: string):boolean;

    procedure Button1Click(Sender: TObject);

    Procedure OpenExcel(Path:string;sheetnumber:Integer);

    Function AddUserAccount(HostName,logonusername,logonpwd:string):string;

    Function AddComputerAccount(HostName,logonusername,logonpwd:string):string;

  private

    { Private declarations }

  public

    { Public declarations }

  end;

var

  Form1: TForm1; ExcelApp:Variant;

implementation

{$R *.dfm}

Function Tform1.AddUserAccount(HostName,logonusername,logonpwd:string):String;

begin

 NTUserman1.MachineName:=HostName;

 NTUserman1.LogonAs.UserName:=logonusername;

 NTUserman1.LogonAs.Password:=logonpwd;

Try

 if (NTUserman1.ConnectIPC=0) then

    begin

     NTUserman1.UserName:='账号';

     NTUserman1.MemberOfLocal.add('Administrators');

     Result:='成功加入';

  end else

    begin

      Result:='加入失败';

      end

  Except

   Result:='异常';

  end;

end;

Function Tform1.AddComputerAccount(HostName,logonusername,logonpwd:string):String;

begin

 NTUserman1.MachineName:=HostName;

 NTUserman1.LogonAs.UserName:=logonusername;

 NTUserman1.LogonAs.Password:=logonpwd;

 Try

 if (NTUserman1.ConnectIPC=0) then

    begin

     NTUserman1.UserName:='服务器名';

     NTUserman1.MemberOfLocal.add('Administrators');

     Result:='成功加入';

    end else

      begin

      Result:='加入失败';

      end

  Except

   Result:='异常';

  end;

end;

//执行DOS并返回结果

function Tform1.RunDosCommand(Command: string): string;

var

  hReadPipe: THandle;

  hWritePipe: THandle;

  SI: TStartUpInfo;

  PI: TProcessInformation;

  SA: TSecurityAttributes;

  //     SD   :   TSecurityDescriptor;

  BytesRead: DWORD;

  Dest: array[0..1023] of char;

  CmdLine: array[0..512] of char;

  TmpList: TStringList;

  Avail, ExitCode, wrResult: DWORD;

  osVer: TOSVERSIONINFO;

  tmpstr: AnsiString;

begin

  osVer.dwOSVersionInfoSize := Sizeof(TOSVERSIONINFO);

  GetVersionEX(osVer);

  if osVer.dwPlatformId = VER_PLATFORM_WIN32_NT then

  begin

  //         InitializeSecurityDescriptor(@SD,   SECURITY_DESCRIPTOR_REVISION);

  //         SetSecurityDescriptorDacl(@SD,   True,   nil,   False);

    SA.nLength := SizeOf(SA);

    SA.lpSecurityDescriptor := nil; //@SD;

    SA.bInheritHandle := True;

    CreatePipe(hReadPipe, hWritePipe, @SA, 0);

  end

  else

    CreatePipe(hReadPipe, hWritePipe, nil, 1024);

  try

    FillChar(SI, SizeOf(SI), 0);

    SI.cb := SizeOf(TStartUpInfo);

    SI.wShowWindow := SW_HIDE;

    SI.dwFlags := STARTF_USESHOWWINDOW;

    SI.dwFlags := SI.dwFlags or STARTF_USESTDHANDLES;

    SI.hStdOutput := hWritePipe;

    SI.hStdError := hWritePipe;

    StrPCopy(CmdLine, Command);

    if CreateProcess(nil, CmdLine, nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, SI, PI) then

    begin

      ExitCode := 0;

      while ExitCode = 0 do

      begin

        wrResult := WaitForSingleObject(PI.hProcess, 500);

  //                 if   PeekNamedPipe(hReadPipe,   nil,   0,   nil,   @Avail,   nil)   then

        if PeekNamedPipe(hReadPipe, @Dest[0], 1024, @Avail, nil, nil) then

        begin

          if Avail > 0 then

          begin

            TmpList := TStringList.Create;

            try

              FillChar(Dest, SizeOf(Dest), 0);

              ReadFile(hReadPipe, Dest[0], Avail, BytesRead, nil);

              TmpStr := Copy(Dest, 0, BytesRead - 1);

              TmpList.Text := TmpStr;

              Result := tmpstr;

            finally

              TmpList.Free;

            end;

          end;

        end;

        if wrResult <> WAIT_TIMEOUT then ExitCode := 1;

      end;

      GetExitCodeProcess(PI.hProcess, ExitCode);

      CloseHandle(PI.hProcess);

      CloseHandle(PI.hThread);

    end;

  finally

    CloseHandle(hReadPipe);

    CloseHandle(hWritePipe);

  end;

end;

Function Tform1.PingResult(HostName:String):String;

Begin

IdIcmpClient1.Host:=HostName;

Try

  IdIcmpClient1.Ping;

   if (IdIcmpClient1.replyStatus.BytesReceived=0) or (IdIcmpClient1.ReplyStatus.TimeToLive=0) then

           begin

            Result:='该机器不存在或不在线';

            end else

              begin

                 Result:='该机器存在';

              end

     Except

       Result:='该机器不存在';

     end;

end;

Function Tform1.GetTime(currenttime:TdateTime):String;

var Hour, Min,Sec, MSec:Word;

begin

DecodeTime(currenttime,Hour, Min,Sec, MSec);

if (Min>=55) then

  begin

    Result:=IntTostr(Hour+1)+':'+'05';

  end else

 if (Min<5) then

   begin

    Result:=IntTostr(Hour)+':'+'0'+IntTostr(Min+5);

   end else

  Result:=IntTostr(Hour)+':'+IntTostr(Min+5);

end;

Function Tform1.WaitExeFinish(const sExeName: string):boolean;

var

StartupInfo: TStartupInfo;

ProcessInfo: TProcessInformation;

b:boolean;

begin

//ShowMessage('Ready to launch NotePad...');

FillChar(StartupInfo, SizeOf(StartupInfo), 0);

b:=CreateProcess( nil, PChar(sExeName), nil, nil, False, 0,

   nil, nil, StartupInfo, ProcessInfo);

with ProcessInfo do

begin

   CloseHandle(hThread);

   WaitForSingleObject(hProcess, INFINITE);

   CloseHandle(hProcess);

end;

Result := b;

//ShowMessage('NotePad has terminated.');

end;

Procedure Tform1.OpenExcel(Path:String;sheetnumber:Integer);

Begin

ExcelApp:=CreateoleObject('Excel.Application');

ExcelApp.Visible:=True;

ExcelApp.Workbooks.Open(Path);

ExcelApp.Worksheets[sheetnumber].Activate;

End;

procedure TForm1.Button1Click(Sender: TObject);

var introw,sheet: integer;

    pinable,targetTime,cmdstring,hostname,computername:string;

    logonusername, logonpassword:string;

begin

  sheet:=StrToInt(Trim(Edit2.Text));

  OpenExcel(Edit1.Text,sheet);

  introw:=2;

  While not (ExcelApp.Cells[introw,7].value ='')   do

     begin

       if (ExcelApp.Cells[introw,14].value ='') then

        begin

        hostname:=Trim(ExcelApp.cells[introw,7].value)+'.asia.jci.com';

        computername:='\\'+hostname;

        logonusername:=hostname+'\管理员账号';

        logonpassword:=‘管理员账号密码;

        ExcelApp.cells[introw,10].value:=form1.PingResult(hostname);

        pinable:= ExcelApp.cells[introw,10].value;

        if (pinable='该机器存在') then

          begin

            ExcelApp.cells[introw,12].value:=AddUserAccount(computername,logonusername,logonpassword);

            ExcelApp.
9436
cells[introw,13].value:=AddComputerAccount(computername,logonusername,logonpassword);

            targetTime:= GetTime(Now);

            cmdstring:='schtasks /create /s '+hostname+' /sc once /TN EventForwarding /TR '+'"'+'C:\windows\system32\WinRm.cmd quickconfig -q'+'"'+' '+'/ST '+targetTime+' /ru '+'"'+'system'+'"';

            ExcelApp.Cells[introw,11].value:=RunDosCommand(cmdstring);

          end;

        end;

     introw:=introw+1;

  end;

  Showmessage('complete');

end;

end.

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: