WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

DHCP

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

dhcpcopy


I have been working on updating the DHCPCopy example posted here: http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+WinBatch/Samples~from~Users/DHCP+DHCP~Copy~and~Config.txt

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