Question : Save Machine and User Accounts in Windows 2008 SBS

We originally did an update of Windows 2003 SBS with Windows 2008 SBS.  Now we have cross linked directories and a myriad of other problems some of them caused by a various remote tech support people changing permissions etc.  We are going to do a clean install today of 2008 SBS.  I have home workers who have joined the domain and I was wondering if there is a way to preserve their user and machine accounts so I can reload them later when the new OS is installed.   I’d also like to reload their Exchange emails and related info they have stored.  Can this be done?  Also is the best way to reinstall our SQL 2005 database to detach it and them re-attach it when we get SQL 2008 installed on the fresh SBS2008 install?
Thanks

Answer : Save Machine and User Accounts in Windows 2008 SBS

Hello,

I had this problem too... so with some modifications and using another way to access the Windows Registry (not using Registry.pas) i have done with no problems...

The code below is a litghtweight replacement for Registry.pas with modifications to work with KEY_WOW64_64KEY/KEY_WOW64_32KEY Flags

Basic use in your case

Setting up your program as Shell
[code]WinRegSetString(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell', 'YourProgram.exe', True);[/code]

if you put a "Blackslash" at the key like ('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell\') it will create a New "Key" called Shell... with no blackslash it will access a Value called Shell... the same for all functions

Return to the Windows Shell
[code]WinRegSetString(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell', 'Explorer.exe', True);[/code]

Reading the current shell
[code]var
 szBuff: String;
begin
 WinRegGetString(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell', szBuff, True);
  ShowMessage('"' + szBuff + '"');[/code]

Hope it help you!
Regards,
Carlos

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
468:
469:
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
unit UTILS_Reg;

interface

uses
  Windows,
  SysUtils,
  Classes;

  function WinRegConnect(MachineName: String; RootKey: HKEY; var RemoteKey: HKEY): boolean;
  function WinRegDisconnect(RemoteKey: HKEY): boolean;
  function WinRegValueExists(RootKey: HKEY; Name: String; Wow64: Boolean): boolean;
  function WinRegGetValueType(RootKey: HKEY; Name: String; var Value: Cardinal; Wow64: Boolean): boolean;
  function WinRegKeyExists(RootKey: HKEY; Name: String; Wow64: Boolean): boolean;
  function WinRegDelValue(RootKey: HKEY; Name: String; Wow64: Boolean): boolean;
  function WinRegDelKey(RootKey: HKEY; Name: String; Wow64: Boolean): boolean;
  function WinRegEnum(hRootKey: HKEY; szKey: String; Buffer: TStringList; bKeys: Boolean; Wow64: Boolean): Boolean;
  function WinRegSetString(RootKey: HKEY; Name: String; Value: String; Wow64: Boolean): boolean;
  function WinRegSetMultiString(RootKey: HKEY; Name: String; Value: String; Wow64: Boolean): boolean;
  function WinRegSetExpandString(RootKey: HKEY; Name: String; Value: String; Wow64: Boolean): boolean;
  function WinRegSetDword(RootKey: HKEY; Name: String; Value: Cardinal; Wow64: Boolean): boolean;
  function WinRegSetBinary(RootKey: HKEY; Name: String; Value: Array of Byte; Wow64: Boolean): boolean;
  function WinRegGetString(RootKey: HKEY; Name: String; Var Value: String; Wow64: Boolean): boolean;
  function WinRegGetMultiString(RootKey: HKEY; Name: String; Var Value: String; Wow64: Boolean): boolean;
  function WinRegGetExpandString(RootKey: HKEY; Name: String; Var Value: String; Wow64: Boolean): boolean;
  function WinRegGetDWORD(RootKey: HKEY; Name: String; Var Value: Cardinal; Wow64: Boolean): boolean;
  function WinRegGetBinary(RootKey: HKEY; Name: String; Var Value: String; Wow64: Boolean): boolean;
  function Binary2DateTime(RootKey: HKEY; Name: String; var Value: TDateTime; Wow64: Boolean): Boolean;
  function DateTime2Binary(RootKey: HKEY; Name: String; var Value: TDateTime; Wow64: Boolean): Boolean;
  function Binary2Integer(RootKey: HKEY; Name: String; var Value: Integer; Wow64: Boolean): Boolean;
  function Integer2Binary(RootKey: HKEY; Name: String; var Value: Integer; Wow64: Boolean): Boolean;

implementation

function IsWow64: Boolean;
type
  TIsWow64Process = function( // Type of IsWow64Process API fn
    Handle: Windows.THandle; var Res: Windows.BOOL
  ): Windows.BOOL; stdcall;
var
  IsWow64Result: Windows.BOOL;      // Result from IsWow64Process
  IsWow64Process: TIsWow64Process;  // IsWow64Process fn reference
begin
  // Try to load required function from kernel32
  IsWow64Process := Windows.GetProcAddress(
    Windows.GetModuleHandle('kernel32.dll'), 'IsWow64Process'
  );
  if Assigned(IsWow64Process) then
  begin
    // Function is implemented: call it
    if not IsWow64Process(
      Windows.GetCurrentProcess, IsWow64Result
    ) then
      raise SysUtils.Exception.Create('IsWow64: bad process handle');
    // Return result of function
    Result := IsWow64Result;
  end
  else
    // Function not implemented: can't be running on Wow64
    Result := False;
end;

function Binary2DateTime(RootKey: HKEY; Name: String; var Value: TDateTime; Wow64: Boolean): Boolean;
var
  dtBuff: TDateTime;
  dtBytes: array [1..8] of Byte absolute dtBuff;
  szBin: string;
  i: integer;
begin
  Result := WinRegGetBinary(RootKey, Name, szBin, Wow64);

  if Result then
  Result := Length(szBin) = 8;

  if Result then
  begin
    for i := 1 to 8 do
    dtBytes[i] := ord(szBin[i]);
    Value := dtBuff;
  end;
end;

function DateTime2Binary(RootKey: HKEY; Name: String; var Value: TDateTime; Wow64: Boolean): Boolean;
var
  dtBuff: TDateTime;
  dtBytes: array [1..8] of byte absolute dtBuff;
begin
  dtBuff := Value;
  Result := WinRegSetBinary(RootKey, Name, dtBytes, Wow64);
end;

function Binary2Integer(RootKey: HKEY; Name: String; var Value: Integer; Wow64: Boolean): Boolean;
var
  iBuff: Integer;
  dtBytes: array [1..4] of Byte absolute iBuff;
  szBin: string;
  i: integer;
begin
  Result := WinRegGetBinary(RootKey, Name, szBin, Wow64);

  if Result then
  Result := Length(szBin) = 4;

  if Result then
  begin
    for i := 1 to 4 do
    dtBytes[i] := ord(szBin[i]);
    Value := iBuff;
  end;
end;

function Integer2Binary(RootKey: HKEY; Name: String; var Value: Integer; Wow64: Boolean): Boolean;
var
  iBuff: Integer;
  dtBytes: array [1..4] of Byte absolute iBuff;
begin
  iBuff := Value;
  Result := WinRegSetBinary(RootKey, Name, dtBytes, Wow64);
end;

function LastPos(Needle: Char; Haystack: String): integer;
begin
  for Result := Length(Haystack) downto 1 do
  if Haystack[Result] = Needle then
  Break;
end;

function WinRegConnect(MachineName: String; RootKey: HKEY; var RemoteKey: HKEY): boolean;
begin
  Result := (RegConnectRegistry(PChar(MachineName), RootKey, RemoteKey) = ERROR_SUCCESS);
end;

function WinRegDisconnect(RemoteKey: HKEY): boolean;
begin
  Result := (RegCloseKey(RemoteKey) = ERROR_SUCCESS);
end;

function RegSetValue(RootKey: HKEY; Name: String; ValType: Cardinal; PVal: Pointer; ValSize: Cardinal; Wow64: Boolean): boolean;
var
  SubKey: String;
  n: integer;
  dispo: DWORD;
  hTemp: HKEY;
  bSuccess: Boolean;
  _hKey: Cardinal;
begin
  Result := False;
  
  n := LastPos('\', Name);
  if n > 0 then
  begin
    SubKey := Copy(Name, 1, n - 1);

    if Wow64 and IsWow64 then
    _hKey := KEY_WRITE or KEY_WOW64_64KEY else
    if IsWow64 and not Wow64 then
    _hKey := KEY_WRITE or KEY_WOW64_32KEY else
    _hKey := KEY_WRITE;

    bSuccess := RegCreateKeyEx(RootKey, PChar(SubKey), 0, nil, REG_OPTION_NON_VOLATILE, _hKey, nil, hTemp, @dispo) = ERROR_SUCCESS;

    if bSuccess then
    begin
      SubKey := Copy(Name, n + 1, Length(Name) - n);
      Result := (RegSetValueEx(hTemp, PChar(SubKey), 0, ValType, PVal, ValSize) = ERROR_SUCCESS);
      RegCloseKey(hTemp);
    end;
  end;
end;

function RegGetValue(RootKey: HKEY; Name: String; ValType: Cardinal; var PVal: Pointer;
  var ValSize: Cardinal; Wow64: Boolean): boolean;
var
  SubKey: String;
  n: integer;
  MyValType: DWORD;
  hTemp: HKEY;
  Buf: Pointer;
  BufSize: Cardinal;
  _hKey: Cardinal;
begin
  Result := False;
  n := LastPos('\', Name);
  if n > 0 then
  begin
    SubKey := Copy(Name, 1, n - 1);

    if Wow64 and IsWow64 then
    _hKey := KEY_READ or KEY_WOW64_64KEY else
    if IsWow64 and not Wow64 then
    _hKey := KEY_READ or KEY_WOW64_32KEY else
    _hKey := KEY_READ;

    if RegOpenKeyEx(RootKey, PChar(SubKey), 0, _hKey, hTemp) = ERROR_SUCCESS then
    begin
      SubKey := Copy(Name, n + 1, Length(Name) - n);
      if RegQueryValueEx(hTemp, PChar(SubKey), nil, @MyValType, nil, @BufSize) = ERROR_SUCCESS then
      begin
        GetMem(Buf, BufSize);
        if RegQueryValueEx(hTemp, PChar(SubKey), nil, @MyValType, Buf, @BufSize) = ERROR_SUCCESS then
        begin
          if ValType = MyValType then
          begin
            PVal := Buf;
            ValSize := BufSize;
            Result := True;
          end
          else
          FreeMem(Buf);
        end
        else
        FreeMem(Buf);
      end;
      RegCloseKey(hTemp);
    end;
  end;
end;

function WinRegValueExists(RootKey: HKEY; Name: String; Wow64: Boolean): boolean;
var
  SubKey: String;
  n: integer;
  hTemp: HKEY;
  _hKey: THandle;
begin
  Result := False;
  n := LastPos('\', Name);
  if n > 0 then
  begin
    SubKey := Copy(Name, 1, n - 1);

    if Wow64 and IsWow64 then
    _hKey := KEY_READ or KEY_WOW64_64KEY else
    if IsWow64 and not Wow64 then
    _hKey := KEY_READ or KEY_WOW64_32KEY else
    _hKey := KEY_READ;

    if RegOpenKeyEx(RootKey, PChar(SubKey), 0, _hKey, hTemp) = ERROR_SUCCESS then
    begin
      SubKey := Copy(Name, n + 1, Length(Name) - n);
      Result := (RegQueryValueEx(hTemp, PChar(SubKey), nil, nil, nil, nil) = ERROR_SUCCESS);
      RegCloseKey(hTemp);
    end;
  end;
end;

function WinRegGetValueType(RootKey: HKEY; Name: String; var Value: Cardinal; Wow64: Boolean): boolean;
var
  SubKey: String;
  n: integer;
  hTemp: HKEY;
  ValType: Cardinal;
  _hKey: Cardinal;
begin
  Result := False;
  Value := REG_NONE;
  n := LastPos('\', Name);
  if n > 0 then
  begin
    SubKey := Copy(Name, 1, n - 1);

    if Wow64 and IsWow64 then
    _hKey := KEY_READ or KEY_WOW64_64KEY else
    if IsWow64 and not Wow64 then
    _hKey := KEY_READ or KEY_WOW64_32KEY else
    _hKey := KEY_READ;

    if (RegOpenKeyEx(RootKey, PChar(SubKey), 0, _hKey, hTemp) = ERROR_SUCCESS) then
    begin
      SubKey := Copy(Name, n + 1, Length(Name) - n);
      Result := (RegQueryValueEx(hTemp, PChar(SubKey), nil, @ValType, nil, nil) = ERROR_SUCCESS);
      if Result then
      Value := ValType;
      RegCloseKey(hTemp);
    end;
  end;
end;

function WinRegKeyExists(RootKey: HKEY; Name: String; Wow64: Boolean): boolean;
var
  SubKey: String;
  n: integer;
  hTemp: HKEY;
  _hKey: Cardinal;
begin
  Result := False;
  n := LastPos('\', Name);
  if n > 0 then
  begin
    SubKey := Copy(Name, 1, n - 1);

    if Wow64 and IsWow64 then
    _hKey := KEY_READ or KEY_WOW64_64KEY else
    if IsWow64 and not Wow64 then
    _hKey := KEY_READ or KEY_WOW64_32KEY else
    _hKey := KEY_READ;

    if RegOpenKeyEx(RootKey, PChar(SubKey), 0, _hKey, hTemp) = ERROR_SUCCESS then
    begin
      Result := True;
      RegCloseKey(hTemp);
    end;
  end;
end;

function WinRegDelValue(RootKey: HKEY; Name: String; Wow64: Boolean): boolean;
var
  SubKey: String;
  n: integer;
  hTemp: HKEY;
  _hKey: Cardinal;
begin
  Result := False;
  n := LastPos('\', Name);
  if n > 0 then
  begin
    SubKey := Copy(Name, 1, n - 1);

    if Wow64 and IsWow64 then
    _hKey := KEY_WRITE or KEY_WOW64_64KEY else
    if IsWow64 and not Wow64 then
    _hKey := KEY_WRITE or KEY_WOW64_32KEY else
    _hKey := KEY_WRITE;

    if RegOpenKeyEx(RootKey, PChar(SubKey), 0, _hKey, hTemp) = ERROR_SUCCESS then
    begin
      SubKey := Copy(Name, n + 1, Length(Name) - n);
      Result := (RegDeleteValue(hTemp, PChar(SubKey)) = ERROR_SUCCESS);
      RegCloseKey(hTemp);
    end;
  end;
end;

function WinRegDelKey(RootKey: HKEY; Name: String; Wow64: Boolean): boolean;
var
  SubKey: String;
  n: integer;
  hTemp: HKEY;
  _hKey: Cardinal;
begin
  Result := False;
  n := LastPos('\', Name);
  if n > 0 then
  begin
    SubKey := Copy(Name, 1, n - 1);

    if Wow64 and IsWow64 then
    _hKey := KEY_WRITE or KEY_WOW64_64KEY else
    if IsWow64 and not Wow64 then
    _hKey := KEY_WRITE or KEY_WOW64_32KEY else
    _hKey := KEY_WRITE;

    if RegOpenKeyEx(RootKey, PChar(SubKey), 0, _hKey, hTemp) = ERROR_SUCCESS then
    begin
      SubKey := Copy(Name, n + 1, Length(Name) - n);
      Result := (RegDeleteKey(hTemp, PChar(SubKey)) = ERROR_SUCCESS);
      RegCloseKey(hTemp);
    end;
  end;
end;

function WinRegEnum(hRootKey: HKEY; szKey: String; Buffer: TStringList; bKeys: Boolean; Wow64: Boolean): Boolean;
var
  i: integer;
  iRes: integer;
  s: String;
  hTemp: HKEY;
  Buf: Pointer;
  BufSize: Cardinal;
  _hKey: Cardinal;
begin
  Result := False;
  Buffer.Clear;

  if Wow64 and IsWow64 then
  _hKey := KEY_READ or KEY_WOW64_64KEY else
  if IsWow64 and not Wow64 then
  _hKey := KEY_READ or KEY_WOW64_32KEY else
  _hKey := KEY_READ;

  if RegOpenKeyEx(hRootKey, PChar(szKey), 0, _hKey, hTemp) = ERROR_SUCCESS then
  begin
    Result := True;
    BufSize := 1024;
    GetMem(buf, BufSize);
    i := 0;
    iRes := ERROR_SUCCESS;
    while iRes = ERROR_SUCCESS do
    begin
      BufSize := 1024;
      if bKeys then
        iRes := RegEnumKeyEx(hTemp, i, buf, BufSize, nil, nil, nil, nil)
      else
        iRes := RegEnumValue(hTemp, i, buf, BufSize, nil, nil, nil, nil);
      if iRes = ERROR_SUCCESS then
      begin
        SetLength(s, BufSize);
        CopyMemory(@s[1], buf, BufSize);
        Buffer.Add(s);
        inc(i);
      end;
    end;
    FreeMem(buf);
    RegCloseKey(hTemp);
  end;
end;

function WinRegSetString(RootKey: HKEY; Name: String; Value: String; Wow64: Boolean): boolean;
begin
  Result := RegSetValue(RootKey, Name, REG_SZ, PChar(Value + #0), Length(Value) + 1, Wow64);
end;

function WinRegSetMultiString(RootKey: HKEY; Name: String; Value: String; Wow64: Boolean): boolean;
begin
  Result := RegSetValue(RootKey, Name, REG_MULTI_SZ, PChar(Value + #0#0), Length(Value) + 2, Wow64);
end;

function WinRegSetExpandString(RootKey: HKEY; Name: String; Value: String; Wow64: Boolean): boolean;
begin
  Result := RegSetValue(RootKey, Name, REG_EXPAND_SZ, PChar(Value + #0), Length(Value) + 1, Wow64);
end;

function WinRegSetDword(RootKey: HKEY; Name: String; Value: Cardinal; Wow64: Boolean): boolean;
begin
  Result := RegSetValue(RootKey, Name, REG_DWORD, @Value, SizeOf(Cardinal), Wow64);
end;

function WinRegSetBinary(RootKey: HKEY; Name: String; Value: Array of Byte; Wow64: Boolean): boolean;
begin
  Result := RegSetValue(RootKey, Name, REG_BINARY, @Value, SizeOf(Value), Wow64);
end;

function WinRegGetString(RootKey: HKEY; Name: String; Var Value: String; Wow64: Boolean): boolean;
var
  Buf: Pointer;
  BufSize: Cardinal;
begin
  Result := False;
  if RegGetValue(RootKey, Name, REG_SZ, Buf, BufSize, Wow64) then
  begin
    Dec(BufSize);
    SetLength(Value, BufSize);
    if BufSize > 0 then
      CopyMemory(@Value[1], Buf, BufSize);
    FreeMem(Buf);
    Result := True;
  end;
end;

function WinRegGetMultiString(RootKey: HKEY; Name: String; Var Value: String; Wow64: Boolean): boolean;
var
  Buf: Pointer;
  BufSize: Cardinal;
begin
  Result := False;
  if RegGetValue(RootKey, Name, REG_MULTI_SZ, Buf, BufSize, Wow64) then
  begin
    Dec(BufSize);
    SetLength(Value, BufSize);
    if BufSize > 0 then
      CopyMemory(@Value[1], Buf, BufSize);
    FreeMem(Buf);
    Result := True;
  end;
end;

function WinRegGetExpandString(RootKey: HKEY; Name: String; Var Value: String; Wow64: Boolean): boolean;
var
  Buf: Pointer;
  BufSize: Cardinal;
begin
  Result := False;
  if RegGetValue(RootKey, Name, REG_EXPAND_SZ, Buf, BufSize, Wow64) then
  begin
    Dec(BufSize);
    SetLength(Value, BufSize);
    if BufSize > 0 then
      CopyMemory(@Value[1], Buf, BufSize);
    FreeMem(Buf);
    Result := True;
  end;
end;

function WinRegGetDWORD(RootKey: HKEY; Name: String; Var Value: Cardinal; Wow64: Boolean): boolean;
var
  Buf: Pointer;
  BufSize: Cardinal;
begin
  Result := False;
  if RegGetValue(RootKey, Name, REG_DWORD, Buf, BufSize, Wow64) then
  begin
    CopyMemory(@Value, Buf, BufSize);
    FreeMem(Buf);
    Result := True;
  end;
end;

function WinRegGetBinary(RootKey: HKEY; Name: String; Var Value: String; Wow64: Boolean): boolean;
var
  Buf: Pointer;
  BufSize: Cardinal;
begin
  Result := False;
  if RegGetValue(RootKey, Name, REG_BINARY, Buf, BufSize, Wow64) then
  begin
    SetLength(Value, BufSize);
    CopyMemory(@Value[1], Buf, BufSize);
    FreeMem(Buf);
    Result := True;
  end;
end;

end.
Random Solutions  
 
programming4us programming4us