Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
I now have an updated "working, with issues" version DHCPCopy running on my NT4 server. To get where I am I had to rename the DHCPCopy.wbt script references from 32 version extenders to 34 versions and modify the loop extracting backup DCHP server names from the machines registry. The DHCPCOPY.wbt is compiled into a .exe file which runs under srvany.exe as defined in the DHCPCopy service parameters in the registry. By the way, DCHPCopy.exe works under srvany, DCHPCopy.exs does not.
The only remaining issue, that I am aware of, is that the backup DHCP database on the BackUP server fails to update if a user is logged in to the backup DHCP machine, and has a Window File Explorer pointing to WINNT/System32/DHCP/BACKUP. I "assume" it's a file sharing violation sort of thing. Is there a way to overcome this? I thought that since the DHCPCopy service was running under DomainAdministrator privileges that it would have permission to access anything. Also, funny thing, the DHCPCopy service will successfully erase the old backup database but then fails to write the new file.
If it can erase files and directories, they why does it not have authority to write the new files?
; This program is designed to run on the Primary DHCP server ; for a given network segment. One or many backup DHCP ; servers can be configured by installing DHCP on them with ; no scope defined and the service stopped. This service will ; copy the DHCP dattabase to each server so that DHCP can be ; started on any server if the primary DHCP server fails, ; with a minimum loss of records. This winbatch program is ; intended to be ; Winbatch File to be run as a service to ; 1 Replicate the backup DHCP database from the active DHCP server ; to the DHCP backup directory on several backup DHCP servers ; Set the RestoreFlag registry setting to ensure the Backup DHCP ; server loads the backup database when/if they start. ; 2 Read The local registry to determine the number of Backup DHCP ; servers that are to be serviced (by counting the entries ; enumerating the servers to send the file to). ; 3 Read the DHCP server registry to locate the backup dir ; 4 Read the registry to find the service configuration info ; including execution interval. ; 5 Each Backup DHCP server to support has a Key named for the ; server and the UNC path to the backup directory ; ; ;the Main portion of this program runs once each execution interval ; are re-reads all configuration parameters each time. This allows ; for configuration changes without stopping and starting the ; service. ; Written by Jim Graczyk ; Netway Solutions (Copyright) ; With Copious borrowing from Winbatch Sampe Code ;Errormode(@off) Addextender("WWWNT34I.DLL") AddExtender("wsrch34i.dll") ; Standardize on tabs as file/dir delimiters IntControl(29,@tab,0,0,0) sysroot=environment("systemroot") ;debug(@on) :Main atime=TimeYmdHms( ) ;Read Configuration settings out of the registry ;these settings pertain only to how the service should execute reghandle = RegOpenKey(@REGMACHINE,"system\currentcontrolset\services\dhcpcopy\parameters\targets") ;Read the DHCP Backup interval from the reg (in Minutes) ; No need to run more than once each time the DHCP server ; in backed up. ExecInt=regqueryvalue(@regmachine,"system\currentcontrolset\services\dhcpserver\parameters[backupinterval]") ;Read the DHCP Backup Directory ; MUST BE FULLY DECLARED PATH Backupsource=regqueryexpsz(@regmachine,"system\currentcontrolset\services\dhcpserver\parameters[backupdatabasepath]") ;read name and location for log file logfile=regqueryvalue(@regmachine,"system\currentcontrolset\services\dhcpcopy\parameters[logfile]") ;this program runs at a fixed interval ;Now that we know the interval - execint - calculate the next time we should loop ;this assumes the main loop takes less time than execint btime=TimeAdd(atime,"00:00:00:00:%execint%:00") err=wntSvcStatus("", "DHCPServer", 1000, 2) ;if the DHCP service isn't running, do nothing if err <> 4 then goto waittil ;Get a tab delimited list of all the targets by enumerating the keys in the registry targets=regquerykeys(reghandle) ; This is a list of the backup servers. ;parse the names of the servers involved ;********************************************************************** ; I think this is what you want by batcher sfraas@zoo.co.uk ; count=ItemCount(Targets,@Tab) ; Number of items in list. FOR Y=1 TO count ; Loop through list... Target%y%=ItemExtract(Y,Targets,@Tab) ; & assign each entry to a variable. NEXT ; end code by batcher sfraas@zoo.co.uk ********************************************* ;Total number of targets ntargets = count ; Debug( @Off) err=regclosekey(reghandle) ; we now have an array of all target machines and the total number ;Main loop to update each target backup DHCP server for i = 1 to ntargets ;Make sure DHCP is configured and Stopped on each Target ;query the service status by service name for current state ;clear last error xxx=wntSvcStatus(target%i%, "DHCPServer", 1000, 2) gosub errchk if err <> 0 lasterror() msg=strcat(target%i%," - DHCP Service not installed") gosub logit continue endif if xxx<>1 msg=strcat(target%i%," - DHCP Service not stopped") gosub logit continue endif ;DHCP service is installed and stopped pushtarget=target%i% gosub pushdhcp gosub xcopy gosub errchk next :waittil TimeWait(btime) ;message("","Continue??") goto main ;end :logit ;logit subroutine logs anything in the MSG variable adding a ; timsetamp msg=strcat(timedate(),": ",msg) logfhandle=fileopen(logfile, "APPEND") FileWrite(logfhandle,msg) fileclose(logfhandle) return :pushdhcp ;pushdhcp subroutine Pushes the DHCP Config hive ; to a server specified by the pushtarget variable root="system\currentcontrolset\services\DHCPServer" pushkey="Configuration" tot=0 totdir=0 level=1 ; Connect to target server registry theremachine=RegConnect(pushtarget, @regmachine) thereroot=regopenkey(theremachine,root) ;create a new key for the data to be copied. there=thereroot ;enumerate and delete everything under the \Configuration key configkeyhandle=regopenkey(there,"Configuration") configkeys=regquerykeys(configkeyhandle) ;parse the names of keys involved start=1 count=0 while @true finish=StrScan(configkeys,@tab,start,@FWDSCAN) If finish == 0 break else count=count+1 configkey%count% = StrSub(configkeys,start,finish - start) start = finish + 1 endif endwhile ;Total number of keys nkeys = count for j = 1 to nkeys regdeletekey(configkeyhandle,configkey%j%) ; message("deleting",configkey%j%) next regclosekey(configkeyhandle) ; remote keys are deleted, copy new ones who1=pushkey hereroot=regopenkey(@regmachine,root) dir1=RegOpenKey(hereroot,who1) gosub copydadata sub%level%=RegQueryKeys(dir%level%) numdir%level% = ItemCount(sub%level%, @tab) index%level% = 0 :dsloop If index%level% == numdir%level% Then Goto upalevel nextlevel=level+1 index%level% = index%level% + 1 who%nextlevel%=ItemExtract(index%level%,sub%level%,@tab) dir%nextlevel%=RegOpenKey(dir%level%,who%nextlevel%) totdir=totdir+1 level = level + 1 gosub copydadata sub%level%=RegQueryKeys(dir%level%) numdir%level% = ItemCount(sub%level%, @tab) index%level% = 0 goto dsloop :upalevel RegCloseKey(dir%level%) drop(dir%level%,sub%level%,index%level%,numdir%level%) level=level-1 if level!=0 then goto dsloop ;set the restore flag on the backup server err=regsetdword(thereroot,"parameters[restoreflag]",1) ;locate the DHCP Backup Path for this server ; MUST BE FULLY DECLARED PATH backuppath%i%=regqueryexpsz(thereroot,"parameters[backupdatabasepath]") Backuppath%i%=strreplace(backuppath%i%,":","$") regclosekey(hereroot) regclosekey(theremachine) regclosekey(thereroot) return :xcopy ; XCOPY program using Searcher Extender. ; Here the source and target starting directories are defined topsrcdir=strcat(backupsource,"\") ; This directory MUST have a trailing \ !!! toptargdir=strcat("\\",pushtarget,"\",backuppath%i%,"\") ; This directory MUST have a trailing \ !!! ; Delete all files and Directories under the backuptarget deletepath=toptargdir gosub deltree ; Erase any error from deltree lasterror() ; Precompute a handy number ttslenplusone=strlen(topsrcdir)+1 ; Make top level target dir if !DirExist(toptargdir) then DirMake(toptargdir) ; Initialize our dir and file counters filcount=0 dircount=1 ; Define search criteria. Basically ; Start at topsrcdir ; File all files *.* ; Drill down (16) New Dir notify (32) 16+32=48 handle=srchInit(topsrcdir,"*.*","",0,48) ; Do the xcopy while 1 foundsrcitem=srchNext(handle) if foundsrcitem=="" then break targfile=StrCat(toptargdir,strsub(foundsrcitem,ttslenplusone,-1)) ; Check last character of foundsrcitem to see if it is a new directory if StrSub(foundsrcitem,strlen(foundsrcitem),1)=="\" ; New Dir dircount=dircount+1 if !DirExist(targfile) then DirMake(targfile) ; Make Dir else ; New File filcount=filcount+1 FileCopy(foundsrcitem,targfile,0) ; Copy File endif endwhile srchFree(handle) return :copydadata curkey=dir%level% ; current source key zork=who1 for xxx=2 to level zork=strcat(zork,"\",who%xxx%) next dataitems=RegQueryItem(curkey,"") ;message(zork,who%level%) grackle=RegCreateKey(there,zork) ;target key count=ItemCount(dataitems, @tab) For x = 1 to count data=ItemExtract(x, dataitems, @tab) type=RegEntryType(curkey,"[%data%]") a=RegQueryEx(curkey,"[%data%]", @tab, type) ;message(type,a) RegSetEx(grackle,"[%data%]", a, @tab, type) next ;copy dataitems here RegClosekey(grackle) tot=tot+ItemCount(dataitems,@tab) return :errchk ;subroutine to log errors to the Event Log err=lasterror() if err==0 then return else msg=strcat("Error Number ",err," detected") gosub logit endif return :deltree ; DELTREE program using Searcher Extender. ; Here the starting directory is defined dir0=deletepath ; This directory MUST have a trailing \ !!! ; Initialize our dir and file counters filcount=0 dircount=1 dirlevel=0 ; Define search criteria. Basically ; Start at topsrcdir ; File all files *.* ; Drill down (16) New Dir notify (32) 16+32=48 handle=srchInit(dir0,"*.*","",0,48) ; Delete files first while 1 foundsrcitem=srchNext(handle) if foundsrcitem=="" then break ; Check last character of foundsrcitem to see if it is a new directory if StrSub(foundsrcitem,strlen(foundsrcitem),1)=="\" ; New Dir dircount=dircount+1 dirlevel=dirlevel+1 dir%dirlevel%=foundsrcitem else ; New File filcount=filcount+1 ; You may possible want to remove read-only attributes here FileDelete(foundsrcitem) ; Delete File ;Message("Filerem",foundsrcitem) ; For debugging endif endwhile srchFree(handle) ;Now go back and remove directories for dd=dirlevel to 0 by -1 DirRemove(dir%dd%) ; Message("DirRem",dir%dd%) ; For Debugging next return
Article ID: W16213
File Created: 2014:07:18:09:51:38
Last Updated: 2014:07:18:09:51:38