Page 1 of 2 12>
Topic Options
#207124 - 2013-04-19 10:26 PM Just Sharing - Adding Printers based on computer name via INI
syntax53 Offline
Fresh Scripter

Registered: 2004-11-17
Posts: 31
Loc: Pennsylvania
I work at a school district and our users need to have network printers loaded onto computers based on the location of the computer. Teachers can move around the building (and even to other buildings) and need to have access to the closest printer. I posted this thread awhile ago to get an initial feeler for how to go about it. So the deployment was this week and I got the bugs ironed out. Below is the final script.

EDITED 5/1/2013 to include some extra options for the INI and moving the global declaration out of the function as suggested below.


First the UDF's I'm using:

 Code:
;FROM http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Number=118766
function GetDefaultPrinter()
    $GetDefaultPrinter = join(split(readvalue("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows","Device"),',',1),'')
endfunction

;FROM http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Number=202790#Post202790
Function IniArray($_fSrcFile, OPTIONAL $_aDataWrite)
 
  Dim $_					; temp var 
  Dim $_Fp					; file pointer 
  Dim $_I, $_J					; index pointers 
  Dim $_Sect					; Section Name 
  Dim $_aDat					; Data pair 
  Dim $_aSect[1,0], $_aData[1, 0]		; Section & Data Arrays 
 
 
  ; Obtain a File Handle for Read or Write operations 
  ; ============================================================ 
  $_Fp = FreeFileHandle				; locate an available file handle 
  If Not $_Fp
    Exit 1					; none available - exit 
  EndIf
 
 
  ; WRITE: verify that we have properly formatted data 
  ; ============================================================ 
  If VarType($_aDataWrite)  > 0			; Write the array to the INI file and exit 
    If VarType($_aDataWrite) < 8192		; data but not an array - exit! 
      Exit 87
    EndIf
 
    Del $_fSrcFile				; delete any pre-existing file 
    $_ = Open($_Fp, $_fSrcFile, 5)		; open the file for write/create 
    If @ERROR Exit @ERROR EndIf			; exit if error opening 
 
    ; Write the section data. If no data exists in the section, do not write anything! 
    For $_I = 0 to UBound($_aDataWrite, 2)
      $_Sect  = $_aDataWrite[0, $_I]		; Section name to write 
      $_aData = $_aDataWrite[1, $_I]		; Data array 
      If UBound($_aData, 2) > -1		; create Sect and write data if data is present 
        $_ = '[' + $_Sect + ']' + @CRLF		; section name 
        For $_J = 0 to UBound($_aData, 2)	; key/data pairs 
          If $_aData[1, $_J]			; only write keys that have non-null data 
            $_ = $_ + $_aData[0, $_J] + '=' + $_aData[1, $_J] + @CRLF
          EndIf
        Next
        $_ = WriteLine($_Fp, $_)		; write the output line 
        If @ERROR Exit @ERROR EndIf		; exit if error writing 
      EndIf
    Next
 
    $_ = Close($_Fp)				; close the file 
    ReDim $_aData[1, 0]				; clear array 
 
    ; exit 0 ; do not exit here to force a re-read of the freshly written data 
 
  EndIf
 
 
  ; READ: Load the ini file into an array 
  ; ============================================================ 
  $_I = -1  $_J = -1				; Initialize index pointers 
  
  $_ = Open($_Fp, $_fSrcFile, 2)		; open the file for read 
  If @ERROR Exit @ERROR EndIf			; exit if error opening 
 
  Do						; loop through the file contents 
    $_ = Trim(ReadLine($_Fp))			; remove leading/trailing spaces 
 
    If Left($_, 1) = '['			; found a section 
 
      If $_I >= 0				; process prior section data, if any 
        $_aSect[1, $_I] = $_aData
        ReDim $_aData[1, 0]
        $_J = -1
      EndIf
 
      $_I = $_I + 1				; increment the section index 
      ReDim Preserve $_aSect[1, $_I]
      $_aSect[0, $_I] = Split(SubStr($_, 2), ']')[0]
    Else
      If Not Left($_, 1) = ';' And Not Left($_, 1) = '#' And Len($_) > 2
        $_aDat = Split($_, '=')			; break into array 
        $_J = $_J + 1				; increment the data index 
        ReDim Preserve $_aData[1, $_J]
        $_aData[0, $_J] = $_aDat[0]		; Store the data 
        $_aData[1, $_J] = $_aDat[1]		; Store the data 
      EndIf
    EndIf
 
  Until @ERROR					; done with input data 
 
  $_ = Close($_Fp)				; close the file 
 
  ; process the last/only section 
  If $_I >= 0
    $_aSect[1, $_I] = $_aData
  EndIf
 
  $IniArray = $_aSect				; return the array 
 
  Exit 0					; exit success 
 
EndFunction
 
 
Function ReadIniArray($_aIniFile, OPTIONAL $_Section, OPTIONAL $_Key)
 
  ; exit immediately if the data format is invalid 
  If VarType($_aIniFile) < 8192			; data but not an array - exit! 
    Exit 87
  EndIf
 
  Dim $_aSectIdx[UBound($_aIniFile, 2)]		; Section Index Array 
  Dim $_I, $_J					; Index pointers 
  Dim $_aData					; Array of Key/Data pairs 
 
  ; Create a section index array 
  For $_I = 0 to UBound($_aIniFile, 2)
    $_aSectIdx[$_I] = $_aIniFile[0, $_I]
  Next
 
  ; If the Section is null, return a delimited string of Sections [same as ReadProfileString(file)] 
  If Not $_Section
    $ReadIniArray = Join($_aSectIdx, Chr(10))
    Exit 0
  EndIf
 
  ; Search the index for a section 
  $_I = aScan($_aSectIdx, $_Section)
  If $_I < 0 Exit 2 EndIf			; section not found - Exit 
 
  $_aData = $_aIniFile[1, $_I]			; Extract the key/value array 
 
  ; Create a Key index for the requested section 
  Dim $_aKeyIdx[UBound($_aData, 2)]
  For $_J = 0 to UBound($_aData, 2)
    $_aKeyIdx[$_J] = $_aData[0, $_J] 
  Next
 
  ; If the Key is null, return a delimited string of Keys [same as ReadProfileString(file, section)] 
  If Not $_Key
    $ReadIniArray = Join($_aKeyIdx, Chr(10))
    Exit 0
  EndIf
 
  ; Search the index for a Key 
  $_J = aScan($_aKeyIdx, $_Key)
  If $_J < 0 Exit 2 EndIf			; Key not found 
 
  $ReadIniArray = $_aData[1, $_J]
 
  Exit 0
 
EndFunction
 


;Modified FROM http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Number=203126#Post203126
function INISections($array)
	$read = readiniarray($array)
	if LEN($read) > 0
		$INISections=split($read,chr(10))
	else
		$INISections = ""
	endif
endfunction

function INIKeys($array,$section)
	$read = readiniarray($array,$section)
	if LEN($read) > 0
		$INIKeys=split($read,chr(10))
	else
		$INIKeys = ""
	endif
endfunction


;FROM http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Number=84020
function mid($midstring,$midstart,optional $midend)
  if $midend<0
    $midend=abs($midend)
  else 
    if $midend>len($midstring)-abs($Midstart) or $midend=""
      $midend=0
    endif
  endif
  select
    case $midstart<0
      $midstart=abs($midstart)
      If $midend=0 
        $mid=left(right($midstring,len($midstring)),(len($midstring)-$midstart)+1)
      else
        $mid=left(right($midstring,($midstart+$midend)-1),$midend)
      endif
    case $midstart>0
      if $midend=0
        $mid= right(left($midstring,len($midstring)),(len($midstring)-$midstart)+1)
      else
        $mid=right(left($midstring,($midstart+$midend)-1),$midend)
      endif
  endselect
endfunction


And here is my script:
 Code:
$debug = 0

IF NOT InStr(UCase(@PRODUCTTYPE), 'SERVER') AND NOT InStr(UCase(@PRODUCTTYPE), 'DOMAIN') ;DONT TOUCH SERVERS
	
	$userid = Ucase(@USERID)
	$workstation = Ucase(@WKSTA)
	$domain = Ucase(@DOMAIN)
	
	;IF $debug = 1 $workstation = "aj324-3" ENDIF
	
	$school=Left($workstation, 2)
	$netprint_ini = ""
	SELECT
		case $school = "AJ" OR $domain = "JUNIOR"
			$netprint_ini = "script_netprint_JUNIOR.ini"
		case $school = "AS" OR $domain = "SENIOR"
			$netprint_ini = "script_netprint_SENIOR.ini"
		case $school = "CB" OR $domain = "COPPER"
		case $school = "HI" OR $domain = "HIGHLAND"
		case $school = "MK" OR $domain = "MCKINLEY"
		case $school = "OV" OR $domain = "OVERLOOK"
		case $school = "RO" OR $domain = "ROSLYN"
		case $school = "RW" OR $school = "RY" OR $school = "RE" OR $domain = "RYDAL"
		case $school = "WH" OR $domain = "WILLOW_HILL"
		case $school = "AA" OR $domain = "ADMIN" ;must be last
			$netprint_ini = "script_netprint_ADMIN.ini"
			
	ENDSELECT
	
	IF NOT $netprint_ini = ""
		SELECT
			case EXIST(@ScriptDir + "\" + $netprint_ini)
				IF $debug = 1 ? @Time + ": NP: INI found in script dir" ENDIF
				$netprint_ini = @ScriptDir + "\" + $netprint_ini
			case EXIST(@LSERVER + "\NETLOGON\" +  $netprint_ini)
				IF $debug = 1 ? @Time + ": NP: INI found at logon server" ENDIF
				$netprint_ini = @LSERVER + "\NETLOGON\" +  $netprint_ini
			case EXIST(@LDRIVE + $netprint_ini)
				IF $debug = 1 ? @Time + ": NP: INI found at logon drive" ENDIF
				$netprint_ini = @LDRIVE + $netprint_ini
		ENDSELECT
		
		IF $debug = 1 ? @Time + ": NP: ini: " + $netprint_ini ENDIF

		$network_printers = IniArray($netprint_ini)
		IF NOT @ERROR = 0
			IF $debug = 1 ? "Error opening file: " + @ERROR + ": " + @SERROR ENDIF
		ELSE
			$current_default_printer = GetDefaultPrinter
			
			GLOBAL $prefix
			GLOBAL $roomnumber
			GLOBAL $beforedash
			GLOBAL $afterdash
			GLOBAL $pcnumber
			$prefix = ""
			$roomnumber = ""
			$beforedash = ""
			$afterdash = ""
			$pcnumber = ""
			
			$ret = DecipherComputerName($workstation)
			
			IF $debug = 1
				? @Time + ": NP: prefix: '" + $prefix + "'"
				? @Time + ": NP: room: '" + $roomnumber + "'"
				? @Time + ": NP: beforedash: '" + $beforedash + "'"
				? @Time + ": NP: afterdash: '" + $afterdash + "'"
				? @Time + ": NP: pcnum: '" + $pcnumber + "'"
			ENDIF
	
			GLOBAL $building_printers
			GLOBAL $new_default_printer
			$building_printers = 1
			$new_default_printer = ""
			
			$printers_added = 0
			
			;[COMPUTERNAME\USERNAME]
			IF $printers_added = 0
				$section = $workstation + '\' + $userid
				$printers_added = ProcessSection($network_printers, $section)
			ENDIF
			
			;[COMPUTERNAME-*\USERNAME]
			IF $printers_added = 0
				IF NOT $beforedash = ""
					$section = $beforedash
				ELSE
					$section = $prefix + CSTR($roomnumber)
				ENDIF
				$section = $section + '-*\' + $userid
				$printers_added = ProcessSection($network_printers, $section)
			ENDIF
			
			;[COMPUTERNAME]
			IF $printers_added = 0
				$section = $workstation
				$printers_added = ProcessSection($network_printers, $section)
			ENDIF
			
			;[COMPUTERNAME-*]
			IF $printers_added = 0
				IF NOT $beforedash = ""
					$section = $beforedash
				ELSE
					$section = $prefix + CSTR($roomnumber)
				ENDIF
				$section = $section + '-*'
				$printers_added = ProcessSection($network_printers, $section)
			ENDIF
			
			IF $printers_added = 0
				IF $debug = 1 ? @Time + ": NP: Iterating sections..." ENDIF
				$sections = INISections($network_printers)
				For Each $section in $sections
					IF $printers_added = 0
					
						;   [PREFIX_LOWRM#-LOWPC# through PREFIX_HIGHRM#-HIGHPC#]
						;OR [PREFIX-LOWPC# through PREFIX-HIGHPC#]
						$t = INSTR($section, " through ")
						IF $t > 0 AND NOT $pcnumber = "" AND $pcnumber = $afterdash AND (IsNumeric($roomnumber) = 1 OR $roomnumber = "")
							IF $debug = 1 ? @Time + ": NP: Processing section '" + $section + "' ..." ENDIF
							$section_prefix = ""
							$room_low = ""
							$room_high = ""
							$pc_low = ""
							$pc_high = ""
							$dash = ""
							For $i = 1 to $t
								$char = MID($section, $i, 1)
								SELECT
									CASE $char = "*"
										$pc_low = "0"
									CASE $char = "-"
										$dash = $char
									CASE $char = " "
										$i = 99999
									CASE IsNumeric($char) = 1
										IF $dash = ""
											$room_low = $room_low + $char
										ELSE
											$pc_low = $pc_low + $char
										ENDIF
									CASE 1
										IF $room_low = "" $section_prefix = $section_prefix + $char ENDIF
								ENDSELECT
							Next
							
							IF $debug = 1 ? @Time + ": NP: 1st prefix: " + $section_prefix ENDIF
							
							IF $section_prefix = $prefix AND NOT $pc_low = ""
								$dash = ""
								$section_prefix = ""
								For $i = ($t+LEN(" through ")) to LEN($section)
									$char = MID($section, $i, 1)
									SELECT
										CASE $char = "*"
											$pc_high = "32768"
										CASE $char = "-"
											$dash = $char
										CASE $char = " "
											$i = 99999
										CASE IsNumeric($char) = 1
											IF $dash = ""
												$room_high = $room_high + $char
											ELSE
												$pc_high = $pc_high + $char
											ENDIF
										CASE 1
											IF $room_high = "" $section_prefix = $section_prefix + $char ENDIF
									ENDSELECT
								Next
								
								IF $debug = 1 ? @Time + ": NP: 2nd prefix: " + $section_prefix ENDIF
								
								IF $section_prefix = $prefix AND NOT $pc_high = ""
									$room_low = VAL($room_low)
									$room_high = VAL($room_high)
									$pc_low = VAL($pc_low)
									$pc_high = VAL($pc_high)
									
									IF $debug = 1
										? @Time + ": NP: room low: " + $room_low
										? @Time + ": NP: room high: " + $room_high
										? @Time + ": NP: pc low: " + $pc_low
										? @Time + ": NP: pc high: " + $pc_high
									ENDIF
									
									IF VAL($pcnumber) >= $pc_low AND VAL($pcnumber) <= $pc_high
										IF ((VAL($roomnumber) >= $room_low AND VAL($roomnumber) <= $room_high) OR ($roomnumer = "" AND $room_low = 0 AND $room_high = 0))
											IF $debug = 1 ? @Time + ": NP: section matched." ENDIF
											$printers_added = ProcessSection($network_printers, $section)
										ELSE
											IF $debug = 1 ? @Time + ": NP: Machine out of room number range." ENDIF
										ENDIF
									ELSE
										IF $debug = 1 ? @Time + ": NP: Machine out of section's PC number range." ENDIF
									ENDIF
								ELSE
									IF $debug = 1 ? @Time + ": NP: Section prefix doesn't match OR pc_high not found." ENDIF
								ENDIF
							ELSE
								IF $debug = 1 ? @Time + ": NP: Section prefix doesn't match OR pc_low not found." ENDIF
							ENDIF
						ELSE
							;[BEFOREDASH-PC1,PC2,PC3]
							$c = INSTR($section, ",")
							$d = INSTR($section, "-")
							IF $d > 0 AND $c > $d
								IF $debug = 1 ? @Time + ": NP: Processing section '" + $section + "' ..." ENDIF
								$section_beforedash = MID($section, 1, $d-1)
								IF $debug = 1 ? @Time + ": NP: section beforedash: '" + $section_beforedash + "'" ENDIF
								IF $section_beforedash = $beforedash
									$postfixes = SPLIT(MID($section, $d+1), ",")
									For Each $section_afterdash in $postfixes
										IF $printers_added = 0
											IF $debug = 1 ? @Time + ": NP: section afterdash: '" + $section_afterdash + "'" ENDIF
											IF $section_afterdash = $afterdash
												IF $debug = 1 ? @Time + ": NP: section matched." ENDIF
												$printers_added = ProcessSection($network_printers, $section)
											ENDIF
										ENDIF
									Next
								ELSE
									IF $debug = 1 ? @Time + ": NP: Section before dash doesn't match." ENDIF
								ENDIF
							ENDIF
						ENDIF
					ENDIF
				Next
			ENDIF
			
			
			IF $printers_added = 1
				IF $building_printers = 1
					IF ContainsNumbers($userid) < 2 AND INGROUP("Students") = 0 ;NON-STUDENTS
						COLOR w/n
						? " Adding Printers, please wait..."
						IF NOT $debug = 1 COLOR n/n ENDIF
						$ret = ProcessSection($network_printers, "BUILDING_PRINTERS", 1)
					ENDIF
				ENDIF
				
				IF NOT $new_default_printer = ""
					$ret = SETDEFAULTPRINTER($new_default_printer)
					IF $debug = 1 ? @Time + ": NP: " + "SETDEFAULT( $new_default_printer ) -- RETURN: " + $ret ENDIF
				ELSE
					IF NOT $current_default_printer = ""
						$ret = SETDEFAULTPRINTER($current_default_printer)
						IF $debug = 1 ? @Time + ": NP: " + "SETDEFAULT( $current_default_printer ) -- RETURN: " + $ret ENDIF
					ENDIF
				ENDIF
			ENDIF
		ENDIF
	ENDIF
ENDIF

function ProcessSection($iniarray, $section, OPTIONAL $ignoredefault)
	$ProcessSection = 0
	IF $debug = 1 ? @Time + ": NP: Processing section '" + $section + "' ..." ENDIF
	
	$keylist = INIKeys($iniarray, $section)
	IF UBOUND($keylist) >= 0
		IF $debug = 1 ? @Time + ": NP: Section Found..." ENDIF
		$ProcessSection = 1
		For $i = 0 to UBOUND($keylist)
			$value = ReadIniArray($iniarray, $section, $keylist[$i])
			IF $keylist[$i] = "printer1" AND LEFT($value, 2) = "\\" AND NOT $ignoredefault = 1
				$new_default_printer = $value
			ENDIF
			IF $keylist[$i] = "building_printers" AND $value = "false"
				IF $debug = 1 ? @Time + ": NP: building_printers=false Found..." ENDIF
				$building_printers = 0
			ENDIF
			
			IF LEFT($keylist[$i], 7) = "printer" AND LEFT($value, 2) = "\\"
				$ret = ADDPRINTERCONNECTION($value) ;
				IF $debug = 1 ? @Time + ": NP: " + "ADDPRINTER( $value ) -- RETURN: " + $ret ENDIF
			ENDIF
		Next
	ENDIF
endfunction

;This takes a computer name like AS123-4 and breaks it down into variables
;$prefix is characters from the start of the string until the first number OR the first dash
;$roomnumber is the first sequence of numbers before the dash
;$beforedash is everything before the dash
;$afterdash is everything after the dash
;$pcnumber is the numbers after the dash unless there are letters in the mix
;$pcnumber would be blank on AS123-B4 and on AS123-4B5 $pcnumber would stop after the 4
function DecipherComputerName($pcname)
	$dash = ""
	
	For $i = 1 to LEN($pcname)
		$char = MID($pcname, $i, 1)
		
		SELECT
			CASE $char = "-"
				$dash = "-"
				
			CASE IsNumeric($char) = 1
				IF $dash = ""
					$roomnumber = $roomnumber + $char
				ELSE
					$pcnumber = $pcnumber + $char
				ENDIF
			
			CASE 1
				SELECT
					CASE $dash = "" AND $roomnumber = ""
						$prefix = $prefix + $char
					CASE $dash = "" AND NOT $roomnumber = ""
						$roomnumber = $roomnumber + $char
					CASE $dash = "-"
						;$i = LEN($pcname)+1
				ENDSELECT
		ENDSELECT
		
		IF $dash = ""
			$beforedash = $beforedash + $char
		ELSE
			IF NOT $char = "-"
				$afterdash = $afterdash + $char
			ENDIF
		ENDIF
	Next
endfunction

;this just counts the number of numbers in a string
;our student logons are all numbers so this is basically
;another way to detect a student logon
function ContainsNumbers($teststr)
    $ContainsNumbers = 0
    FOR $pos = 1 TO LEN($teststr)
        $char = SUBSTR($teststr, $pos, 1)
        SELECT
            case $char = "0"
		$ContainsNumbers = $ContainsNumbers+1
            case $char = "1"
		$ContainsNumbers = $ContainsNumbers+1
            case $char = "2"
		$ContainsNumbers = $ContainsNumbers+1
            case $char = "3"
		$ContainsNumbers = $ContainsNumbers+1
            case $char = "4"
		$ContainsNumbers = $ContainsNumbers+1
            case $char = "5"
		$ContainsNumbers = $ContainsNumbers+1
            case $char = "6"
		$ContainsNumbers = $ContainsNumbers+1
            case $char = "7"
		$ContainsNumbers = $ContainsNumbers+1
            case $char = "8"
		$ContainsNumbers = $ContainsNumbers+1
            case $char = "9"
		$ContainsNumbers = $ContainsNumbers+1
        ENDSELECT
    NEXT
endfunction


And here is a sample of the INI file I made up
 Code:
; ========================================================
;                       FORMAT OF FILE
; ========================================================
;
; [computername-1]
; printer1=\\server\printer name     ;printer1 = Default Printer.  If you don't want to set (or change) their default printer then start with printer2.
; printer2=\\server\printer name     ;OPTIONAL: Extra network printers to add for all users (students included).  Add more with printer3, printer4, etc.
; building_printers=false            ;OPTIONAL: With this flag it will not add any printers from the [BUILDING_PRINTERS] section (applies to non-students only)
;
; [computername-1\username]          ;User Name Override -- This user will only read this section and not the regular section for the computer
; printer1=\\server\printer name
;
; [computername-*]                   ;Printer Settings apply to all machines with the prefix (* must be preceeded by the first dash)
; printer1=\\server\mono printer 1   ;NOTE: You can override this for a single machine by specifying the actual computer name in another section.
; printer2=\\server\mono printer 2
; printer3=\\server\color printer
;
; [BEFOREDASH-PC1,PC2,PC3]           ;Match beforedash to after dash options.  e.g. AJGUID-A,B,D  or  AJLIB-CIRC,OFFICE1,OFFICE2
;
; [ABC100-1 through ABC120-1]        ;Range such as [AJ100-1 through AJ120-1] or [AJLIB-1 through AJLIB-15] or [AJP14-* through AJP18-*].
;
; The script checks for priority in the most specific to least:
; [computername\username] > [computername-*\username] > [computername] > [computername-*] > [ABC100-1 through ABC120-1]
;
; ========================================================

[BUILDING_PRINTERS]
;Printers that get added to all NON-Students unless building_printers=false is specified.
printer1=\\AJH2\Library HPM551 (Color)
printer2=\\AJH2\Library HPP3010#1 (Mono)
printer3=\\AJH2\Library HPP3010#2 (Mono)
printer4=\\AJH2\RICOH Copier Guidance
printer5=\\AJH2\RICOH Copier Library
printer6=\\AJH2\RICOH Copier Mail Rm
printer7=\\AJH2\RICOH Special Ed
printer8=\\AJH2\Rm 116 Office
printer9=\\AJH2\Rm 136 Learning Center
printer10=\\AJH2\Rm 215 Office
printer11=\\AJH2\Rm 224 DE5100 (Color)
printer12=\\AJH2\Rm 224 DE5300 (Mono)
printer13=\\AJH2\Rm 230 DE5130cdn (Color)
printer14=\\AJH2\Rm 230 DE5350dn (Mono)
printer15=\\AJH2\Rm 242 Soc Studies Office
printer16=\\AJH2\Rm 253 HP 4050 (Mono)
printer17=\\AJH2\Rm 310 Office
printer18=\\AJH2\Rm 324 DE5100 (Color)
printer19=\\AJH2\Rm 324 DE5200 (Mono)
printer20=\\AJH2\Rm 342 English Office
printer21=\\AJH2\Rm C58 Classroom
printer22=\\AJH2\Rm C58 DE3010cn (Color)
printer23=\\AJH2\Rm P18 DE5350dn (Mono)
printer24=\\AJH2\Rm S102B Science Office


;RANGES
;=================

[AJ108-1 through AJ126-1]
printer1=\\ajh2\Rm 116 Office

[AJ136-*]
printer1=\\ajh2\Rm 136 Learning Center

[AJ128-1 through AJ157-1]
printer1=\\ajh2\Rm 136 Learning Center

[AJ208-1 through AJ227-1]
printer1=\\ajh2\Rm 215 Office

[AJ215-*]
printer1=\\ajh2\Rm 215 Office

[AJ228-1 through AJ265-1]
printer1=\\ajh2\Rm 242 Soc Studies Office

[AJ310-*]
printer1=\\ajh2\Rm 310 Office

[AJ308-1 through AJ329-1]
printer1=\\ajh2\Rm 310 Office

[AJ324-*]
building_printers=false
printer1=\\ajh2\Rm 324 DE5200 (Mono)
printer2=\\AJH2\Rm 324 DE5100 (Color)

[AJ330-1 through AJ363-1]
printer1=\\ajh2\Rm 342 English Office

[AJ351-*]
printer1=\\ajh2\Rm 351 DE2330dn (Mono)

[AJC51-1 through AJC60-1]
printer1=\\ajh2\Rm C58 Classroom

[AJC58-*]
printer1=\\ajh2\Rm C58 Classroom
printer2=\\AJH2\Rm C58 DE3010cn (Color)

[AJGUID-1 through AJGUID-2]
building_printers=false
printer1=\\ajh2\RICOH Copier Guidance
printer2=\\asd11\AJ Guid Dell 2330dn
printer3=\\asd11\AJ Guid HP 1300n
printer4=\\AJH2\RICOH Copier Mail Rm

[AJGUID-C,B,J]
building_printers=false
printer1=\\asd11\AJ Guid HP 1300n
printer2=\\ajh2\RICOH Copier Guidance
printer3=\\asd11\AJ Guid Dell 2330dn
printer4=\\AJH2\RICOH Copier Mail Rm

[AJGUID-F,G,H]
building_printers=false
printer1=\\asd11\AJ Guid Dell 2330dn
printer2=\\ajh2\RICOH Copier Guidance
printer3=\\asd11\AJ Guid HP 1300n
printer4=\\AJH2\RICOH Copier Mail Rm

[AJHEALTH-*]
printer1=\\asd11\JR Health Suite Dell 2330dn

[AJLIB-1 through AJLIB-15]
building_printers=false
printer1=\\AJH2\Library HPP3010#1 (Mono)
printer2=\\AJH2\Library HPP3010#2 (Mono)
printer3=\\AJH2\Library HPM551 (Color)

[AJLIB-16 through AJLIB-29]
building_printers=false
printer1=\\AJH2\Library HPP3010#2 (Mono)
printer2=\\AJH2\Library HPP3010#1 (Mono)
printer3=\\AJH2\Library HPM551 (Color)

[AJLIB-30 through AJLIB-33]
;teacher computers in back
printer1=\\AJH2\Library HPP3010#2 (Mono)

[AJLIB-CIRC,OFFICE1,OFFICE2]
building_printers=false
printer1=\\AJH2\Library HPP3010#1 (Mono)
printer2=\\AJH2\Library HPP3010#2 (Mono)
printer3=\\AJH2\Library HPM551 (Color)
printer4=\\AJH2\Library Lab DE2330

[AJM2-1 through AJM5-1]
printer1=\\ajh2\Rm C58 Classroom

[AJP14-* through AJP18-*]
printer1=\\ajh2\Rm P18 DE5350dn (Mono)

[AJS6-1 through AJS106-1]
printer1=\\ajh2\Rm S102B Science Office


;SPECIFIC MACHINES
;=================

[AJ111-1]
;guidance (has local)
building_printers=true

[AJ114-1]
;guidance (has local)
building_printers=true

[AJ210-1]
;reading chair (has local)
building_printers=true

[AJ216-1]
;guidance (has local)
building_printers=true

[AJ253-1]
;special ed room with printer in back
printer1=\\ajh2\Rm 253 HP 4050 (Mono)

[AJ316-1]
;guidance (has local)
building_printers=true

[AJ359-2]
;second computer in speech room
printer1=\\ajh2\Rm 342 English Office

[AJATTENDANCE]
printer1=\\asd11\AJ Records Dell 2330dn

[AJC59-1]
;art room (has local printer)
building_printers=true

[AJC100-1]
printer1=\\ajh2\Rm 116 Office

[AJC100-6]
printer1=\\ajh2\Rm 116 Office

[AJC300-1]
printer1=\\ajh2\Rm 215 Office

[AJRECEP]
printer1=\\asd11\AJ Reception

[AJRECORDS]
printer1=\\asd11\AJ Records Dell 2330dn

[AJS3-1]
;ISS - has local
building_printers=true

[AJS102B-1]
printer1=\\AJH2\Rm S102B Science Office


Edited by syntax53 (2013-05-01 03:20 PM)

Top
#207125 - 2013-04-20 12:38 AM Re: Just Sharing - Adding Printers based on computer name via INI [Re: syntax53]
Lonkero Administrator Offline
KiX Master Guru
*****

Registered: 2001-06-05
Posts: 22303
Loc: OK
so, you are not actually giving them the closest printers, but the printers from their "home" building?
_________________________
!

download KiXnet

Top
#207128 - 2013-04-20 03:24 AM Re: Just Sharing - Adding Printers based on computer name via INI [Re: Lonkero]
syntax53 Offline
Fresh Scripter

Registered: 2004-11-17
Posts: 31
Loc: Pennsylvania
Giving them the printer that is closest to the computer they are logging on to. As in "\\ash2\Rm 220B English Office" is the closest network printer to computer "AS220B-1".

Edited my original post to include 2 UDFs I forgot to include.

edit: The "building printers" section could be throwing you off-- every network printer in the building gets added to every teacher's computer so that they can print anywhere they want. The sections below that basically define the default printer (printer1) and any additional printers that students should get (as building printers aren't added for the students).


Edited by syntax53 (2013-04-20 03:28 AM)

Top
#207129 - 2013-04-20 03:28 AM Re: Just Sharing - Adding Printers based on computer name via INI [Re: syntax53]
Lonkero Administrator Offline
KiX Master Guru
*****

Registered: 2001-06-05
Posts: 22303
Loc: OK
ok... your ini-functions are rather complex for that purpose, given that simple few lines would do the logic in my opinion.

thanks for sharing anyways... there might very well be something of use even for me in the future.
_________________________
!

download KiXnet

Top
#207130 - 2013-04-20 03:47 AM Re: Just Sharing - Adding Printers based on computer name via INI [Re: syntax53]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4273
Loc: New Jersey
If you're using my IniArray UDF, then the IniSections and IniKeys UDFs are redundant - you already have all of the data in the master array that was loaded. By using these extra UDFs, you're losing efficiency by loading the INI file into the array, then enumerating the INI file to locate data that's in your array.
 Code:
$aData = IniArray('.\file.ini')
; List of sections
For $S = 0 to UBound($aData, 2)
 'Section: ' $aData[0, $S] ?
 ; list of keys in the current section
 $aKeyData = $aData[1, $S]        ; put keys array into local var
 For $K = 0 to UBound($aKeyData, 2]
  'Key / Data: ' $aKeyData[0, $K] ' / ' $aKeyData[1, $K]
 Next
Next
This keeps all references in the array. This UDF might be overkill for a simple INI lookup, though.

This UDF was updated just today, so you should pull the latest copy after 10pm EST tonight when it gets uploaded to our web site. The update improves performance for larger files and resoves a recently discovered bug that will appear when a section is defined in the file without any keys associated with it.

You shouldn't have to do all the "UCase" commands as text comparisons are case insensitive unless you use a SetOption call to enable case sensitivity.

It's generally good practice to leave the headers in the UDFs as they contain important reference material.

You should never declare a GLOBAL var inside a function. Doing so will cause the var to be declared each time the function is called causing a Duplicate Definition error.

I haven't reviewed the code in depth, but first blush it seems more complicated than necessary. If your computer name identifies the school and classroom along with a unique PC identifier, then a single config file could be used with one section per location and one key per classroom. If a classroom has multiple computers, then reverse the logic - Printer\share=room instead of room=Printer\Share. Search the values for DATA matching the room and the KEY will represent the printer share. You can then determine which preter was preferred.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#207135 - 2013-04-20 04:35 AM Re: Just Sharing - Adding Printers based on computer name via INI [Re: Lonkero]
syntax53 Offline
Fresh Scripter

Registered: 2004-11-17
Posts: 31
Loc: Pennsylvania
 Originally Posted By: Lonkero
ok... your ini-functions are rather complex for that purpose, given that simple few lines would do the logic in my opinion.

There are over 400 computers in each school that the ini files takes are of, without having to specify 400 sections for 400 machines in each ini. The goal was to have as few sections as possible in the INI. The part of the ini I pasted was only a sample. Here are the two main INIs in their entirety, for the junior and senior high--

junior high...
 Code:
; ========================================================
;                       FORMAT OF FILE
; ========================================================
;
; [computername-1]
; printer1=\\server\printer name     ;printer1 = Default Printer.  If you don't want to set (or change) their default printer then start with printer2.
; printer2=\\server\printer name     ;OPTIONAL: Extra network printers to add for all users (students included).  Add more with printer3, printer4, etc.
; building_printers=false            ;OPTIONAL: With this flag it will not add any printers from the [BUILDING_PRINTERS] section (applies to non-students only)
;
; [computername-1\username]          ;User Name Override -- This user will only read this section and not the regular section for the computer
; printer1=\\server\printer name
;
; [computername-*]                   ;Printer Settings apply to all machines with the prefix (* must be preceeded by the first dash)
; printer1=\\server\mono printer 1   ;NOTE: You can override this for a single machine by specifying the actual computer name in another section.
; printer2=\\server\mono printer 2
; printer3=\\server\color printer
;
; [ABC100-1 through ABC120-1]        ;Range such as [AJ100-1 through AJ120-1] or [AJLIB-1 through AJLIB-15] or [AJP14-* through AJP18-*].
;
; The script checks for priority in the most specific to least:
; [computername\username] > [computername-*\username] > [computername] > [computername-*] > [ABC100-1 through ABC120-1]
;
; ========================================================

[BUILDING_PRINTERS]
;Printers that get added to all NON-Students unless building_printers=false is specified.
printer1=\\AJH2\Library HPM551 (Color)
printer2=\\AJH2\Library HPP3010#1 (Mono)
printer3=\\AJH2\Library HPP3010#2 (Mono)
printer4=\\AJH2\RICOH Copier Guidance
printer5=\\AJH2\RICOH Copier Library
printer6=\\AJH2\RICOH Copier Mail Rm
printer7=\\AJH2\RICOH Special Ed
printer8=\\AJH2\Rm 116 Office
printer9=\\AJH2\Rm 136 Learning Center
printer10=\\AJH2\Rm 215 Office
printer11=\\AJH2\Rm 224 DE5100 (Color)
printer12=\\AJH2\Rm 224 DE5300 (Mono)
printer13=\\AJH2\Rm 230 DE5130cdn (Color)
printer14=\\AJH2\Rm 230 DE5350dn (Mono)
printer15=\\AJH2\Rm 242 Soc Studies Office
printer16=\\AJH2\Rm 253 HP 4050 (Mono)
printer17=\\AJH2\Rm 310 Office
printer18=\\AJH2\Rm 324 DE5100 (Color)
printer19=\\AJH2\Rm 324 DE5200 (Mono)
printer20=\\AJH2\Rm 342 English Office
printer21=\\AJH2\Rm C58 Classroom
printer22=\\AJH2\Rm C58 DE3010cn (Color)
printer23=\\AJH2\Rm P18 DE5350dn (Mono)
printer24=\\AJH2\Rm S102B Science Office


;RANGES
;=================

[AJ108-1 through AJ125-1]
printer1=\\ajh2\Rm 116 Office

[AJ136-*]
printer1=\\ajh2\Rm 136 Learning Center

[AJ128-1 through AJ157-1]
printer1=\\ajh2\Rm 136 Learning Center

[AJ208-1 through AJ225-1]
printer1=\\ajh2\Rm 215 Office

[AJ215-*]
printer1=\\ajh2\Rm 215 Office

[AJ234-1 through AJ265-1]
printer1=\\ajh2\Rm 242 Soc Studies Office

[AJ310-*]
printer1=\\ajh2\Rm 310 Office

[AJ308-1 through AJ325-1]
printer1=\\ajh2\Rm 310 Office

[AJ324-*]
building_printers=false
printer1=\\ajh2\Rm 324 DE5200 (Mono)
printer2=\\AJH2\Rm 324 DE5100 (Color)

[AJ330-1 through AJ363-1]
printer1=\\ajh2\Rm 342 English Office

[AJ351-*]
printer1=\\ajh2\Rm 351 DE2330dn (Mono)

[AJC51-1 through AJC60-1]
printer1=\\ajh2\Rm C58 Classroom

[AJC58-*]
printer1=\\ajh2\Rm C58 Classroom
printer2=\\AJH2\Rm C58 DE3010cn (Color)

[AJHEALTH-*]
printer1=\\asd11\JR Health Suite Dell 2330dn

[AJLIB-1 through AJLIB-15]
building_printers=false
printer1=\\AJH2\Library HPP3010#1 (Mono)
printer2=\\AJH2\Library HPP3010#2 (Mono)
printer3=\\AJH2\Library HPM551 (Color)

[AJLIB-16 through AJLIB-29]
building_printers=false
printer1=\\AJH2\Library HPP3010#2 (Mono)
printer2=\\AJH2\Library HPP3010#1 (Mono)
printer3=\\AJH2\Library HPM551 (Color)

[AJLIB-30 through AJLIB-33]
;teacher computers in back
printer1=\\AJH2\Library HPP3010#2 (Mono)

[AJM2-1 through AJM5-1]
printer1=\\ajh2\Rm C58 Classroom

[AJP14-* through AJP18-*]
printer1=\\ajh2\Rm P18 DE5350dn (Mono)

[AJS6-1 through AJS106-1]
printer1=\\ajh2\Rm S102B Science Office


;SPECIFIC MACHINES
;=================

[AJ111-1]
;guidance
building_printers=true

[AJ114-1]
;guidance
building_printers=true

[AJ210-1]
;reading chair
building_printers=true

[AJ216-1]
;guidance
building_printers=true

[AJ253-1]
;special ed room with printer in back
printer1=\\ajh2\Rm 253 HP 4050 (Mono)

[AJ316-1]
;guidance
building_printers=true

[AJ359-2]
;second computer in speech room
printer1=\\ajh2\Rm 342 English Office

[AJATTENDANCE]
printer1=\\asd11\AJ Records Dell 2330dn

[AJC59-1]
;art room (has local printer)
building_printers=true

[AJC100-1]
printer1=\\ajh2\Rm 116 Office

[AJC100-6]
printer1=\\ajh2\Rm 116 Office

[AJGUID-1]
;has local printer
building_printers=false
printer2=\\ajh2\RICOH Copier Guidance
printer3=\\asd11\AJ Guid HP 1300n
printer4=\\asd11\AJ Guid Dell 2330dn
printer5=\\AJH2\RICOH Copier Mail Rm

[AJGUID-2]
building_printers=false
printer1=\\ajh2\RICOH Copier Guidance
printer2=\\asd11\AJ Guid HP 1300n
printer3=\\asd11\AJ Guid Dell 2330dn
printer4=\\AJH2\RICOH Copier Mail Rm

[AJGUID-B]
building_printers=false
printer1=\\asd11\AJ Guid HP 1300n
printer2=\\ajh2\RICOH Copier Guidance
printer3=\\asd11\AJ Guid Dell 2330dn
printer4=\\AJH2\RICOH Copier Mail Rm

[AJGUID-C]
building_printers=false
printer1=\\ajh2\RICOH Copier Guidance
printer2=\\asd11\AJ Guid HP 1300n
printer3=\\asd11\AJ Guid Dell 2330dn
printer4=\\AJH2\RICOH Copier Mail Rm

[AJGUID-F]
building_printers=false
printer1=\\asd11\AJ Guid Dell 2330dn
printer2=\\ajh2\RICOH Copier Guidance
printer3=\\asd11\AJ Guid HP 1300n
printer4=\\AJH2\RICOH Copier Mail Rm

[AJGUID-G]
building_printers=false
printer1=\\asd11\AJ Guid Dell 2330dn
printer2=\\ajh2\RICOH Copier Guidance
printer3=\\asd11\AJ Guid HP 1300n
printer4=\\AJH2\RICOH Copier Mail Rm

[AJGUID-H]
building_printers=false
printer1=\\asd11\AJ Guid Dell 2330dn
printer2=\\ajh2\RICOH Copier Guidance
printer3=\\asd11\AJ Guid HP 1300n
printer4=\\AJH2\RICOH Copier Mail Rm

[AJGUID-J]
building_printers=false
printer1=\\asd11\AJ Guid HP 1300n
printer2=\\ajh2\RICOH Copier Guidance
printer3=\\asd11\AJ Guid Dell 2330dn
printer4=\\AJH2\RICOH Copier Mail Rm

[AJC300-1]
printer1=\\ajh2\Rm 215 Office

[AJLIB-CIRC]
building_printers=false
printer1=\\AJH2\Library HPP3010#1 (Mono)
printer2=\\AJH2\Library HPP3010#2 (Mono)
printer3=\\AJH2\Library HPM551 (Color)
printer4=\\AJH2\Library Lab DE2330

[AJLIB-OFFICE1]
building_printers=false
printer1=\\AJH2\Library HPP3010#1 (Mono)
printer2=\\AJH2\Library HPP3010#2 (Mono)
printer3=\\AJH2\Library HPM551 (Color)
printer4=\\AJH2\Library Lab DE2330

[AJLIB-OFFICE2]
building_printers=false
printer1=\\AJH2\Library HPP3010#1 (Mono)
printer2=\\AJH2\Library HPP3010#2 (Mono)
printer3=\\AJH2\Library HPM551 (Color)
printer4=\\AJH2\Library Lab DE2330

[AJRECEP]
printer1=\\asd11\AJ Reception

[AJRECORDS]
printer1=\\asd11\AJ Records Dell 2330dn

[AJS3-1]
;ISS - has local
building_printers=true


senior high...
 Code:
; ========================================================
;                       FORMAT OF FILE
; ========================================================
;
; [computername-1]
; printer1=\\server\printer name     ;printer1 = Default Printer.  If you don't want to set (or change) their default printer then start with printer2.
; printer2=\\server\printer name     ;OPTIONAL: Extra network printers to add for all users (students included).  Add more with printer3, printer4, etc.
; building_printers=false            ;OPTIONAL: With this flag it will not add any printers from the [BUILDING_PRINTERS] section (applies to non-students only)
;
; [computername-1\username]          ;User Name Override -- This user will only read this section and not the regular section for the computer
; printer1=\\server\printer name
;
; [computername-*]                   ;Printer Settings apply to all machines with the prefix (* must be preceeded by the first dash)
; printer1=\\server\mono printer 1   ;NOTE: You can override this for a single machine by specifying the actual computer name in another section.
; printer2=\\server\mono printer 2
; printer3=\\server\color printer
;
; [ABC100-1 through ABC120-1]        ;Range such as [AJ100-1 through AJ120-1] or [AJLIB-1 through AJLIB-15] or [AJP14-* through AJP18-*].
;
; The script checks for priority in the most specific to least:
; [computername\username] > [computername-*\username] > [computername] > [computername-*] > [ABC100-1 through ABC120-1]
;
; ========================================================

[BUILDING_PRINTERS]
;Printers that get added to all NON-Students unless building_printers=false is specified.
printer1=\\ASH2\Library#1 DE5310 (Mono)
printer2=\\ASH2\Library#2 DE5310 (Mono)
printer3=\\ASH2\Library DE5100 (Color)
printer5=\\ASH2\Ricoh Copier Faculity Rm
printer6=\\ASH2\Ricoh Copier Mail Rm
printer7=\\ASH2\Rm 110 DE5100 (Color)
printer8=\\ASH2\Rm 110 HP4200 (Mono)
printer9=\\ASH2\Rm 121 HP4600 (Color)
printer10=\\ASH2\Rm 129C Science Office
printer11=\\ASH2\Rm 158 Classroom
printer12=\\ASH2\Rm 159 DE3000
printer13=\\ASH2\Rm 209 Math Office
printer14=\\ASH2\Rm 220 DE5100 (Color)
printer15=\\ASH2\Rm 220 DE5300 (Mono)
printer16=\\ASH2\Rm 220B English Office
printer18=\\ASH2\Rm 222#1 DE5300 (Mono)
printer19=\\ASH2\Rm 222#2 DE5300 (Mono)
printer20=\\ASH2\Rm 224 DE5310 (Mono)
printer21=\\ASH2\Rm 235 DE3000
printer22=\\ASH2\Rm 235 Special Ed Office
printer23=\\ASH2\Rm 256 World Lang Office
printer24=\\ASH2\Rm L4 DE5300 (Mono)
printer25=\\ASH2\Rm M106 Music
printer26=\\ASH2\Rm P215 Health
printer27=\\ASH2\Rm S10 Classroom
printer28=\\ASH2\Rm S101A Classroom
printer29=\\ASH2\Rm S106 DE3000


;RANGES
;=================

[AS113-1 through AS118-1]
printer1=\\ash2\Library#1 DE5310 (Mono)

[AS124-1 through AS140-1]
printer1=\\ash2\Rm 129C Science Office

[AS129C-*]
printer1=\\ash2\Rm 129C Science Office

[AS150-1 through AS165-1]
printer1=\\ash2\Rm 158 Classroom

[AS159-*]
printer1=\\ash2\Rm 159 DE3000

[AS201-1 through AS213-1]
printer1=\\ash2\Rm 209 Math Office

[AS219-1 through AS230-1]
printer1=\\ash2\Rm 220B English Office

[AS235-1 through AS239-1]
printer1=\\ash2\Rm 235 Special Ed Office

[AS243-1 through AS256-1]
printer1=\\ash2\Rm 256 World Lang Office

[ASA112-*]
printer1=\\asd11\AS Lower Guid DE5300

[ASA115-*]
printer1=\\asd11\AS Lower Guid Dell 2330dn

[ASL4-*]
building_printers=false
printer1=\\ash2\Rm L4 DE5300 (Mono)
printer2=\\ASH2\Library#1 DE5310 (Mono)
printer3=\\ASH2\Library#2 DE5310 (Mono)
printer4=\\ASH2\Library DE5100 (Color)

[ASLIB-1 through ASLIB-25]
building_printers=false
printer1=\\ash2\Library#1 DE5310 (Mono)
printer2=\\ASH2\Library#2 DE5310 (Mono)
printer3=\\ASH2\Library DE5100 (Color)

[ASLIB-26 through ASLIB-49]
building_printers=false
printer1=\\ASH2\Library#2 DE5310 (Mono)
printer2=\\ash2\Library#1 DE5310 (Mono)
printer3=\\ASH2\Library DE5100 (Color)

[ASM100-1 through ASM106-1]
printer1=\\ash2\Rm M106 Music

[ASP212-1 through ASP217-1]
printer1=\\ash2\Rm P215 Health

[ASP215-*]
printer1=\\ash2\Rm P215 Health

[ASS3-1 through ASS10-1]
printer1=\\ash2\Rm S10 Classroom

[ASS101-1 through ASS113-1]
printer1=\\ash2\Rm S101A Classroom

[ASS101A-*]
printer1=\\ash2\Rm S101A Classroom


;SPECIFIC MACHINES
;=================

[AS120-1]
printer1=\\AS119-1\Dell Open Print Driver (PCL XL)

[AS121-1]
printer1=\\ash2\Rm 121 HP4600 (Color)

[AS209-2]
printer1=\\ash2\Rm 209 Math Office

[AS220B-1]
printer1=\\ash2\Rm 220B English Office

[AS222C-1]
printer1=\\ash2\Rm 222#2 DE5300 (Mono)

[AS233A-1]
printer1=\\ASH2\Rm 235 Special Ed Office

[AS233B-1]
printer1=\\ASH2\Rm 235 Special Ed Office

[ASA103-1]
printer1=\\asd11\AS Upper Guid DE5300

[ASA118-1]
printer1=\\ash2\Rm M106 Music

[ASLIB-CIRC1]
building_printers=false
printer1=\\ash2\Library#1 DE5310 (Mono)
printer2=\\ash2\Rm L4 DE5300 (Mono)
printer3=\\ASH2\Library#2 DE5310 (Mono)
printer4=\\ASH2\Library DE5100 (Color)

[ASLIB-CIRC2]
building_printers=false
printer1=\\ash2\Library#1 DE5310 (Mono)
printer2=\\ash2\Rm L4 DE5300 (Mono)
printer3=\\ASH2\Library#2 DE5310 (Mono)
printer4=\\ASH2\Library DE5100 (Color)

[ASLIB-CIRC3]
building_printers=false
printer1=\\ash2\Library#1 DE5310 (Mono)
printer2=\\ash2\Rm L4 DE5300 (Mono)
printer3=\\ASH2\Library#2 DE5310 (Mono)
printer4=\\ASH2\Library DE5100 (Color)

[ASLIB-OFFICE1]
building_printers=false
printer1=\\ash2\Library#1 DE5310 (Mono)
printer2=\\ash2\Rm L4 DE5300 (Mono)
printer3=\\ASH2\Library#2 DE5310 (Mono)
printer4=\\ASH2\Library DE5100 (Color)

[ASLIB-OFFICE2]
building_printers=false
printer1=\\ash2\Library#1 DE5310 (Mono)
printer2=\\ash2\Rm L4 DE5300 (Mono)
printer3=\\ASH2\Library#2 DE5310 (Mono)
printer4=\\ASH2\Library DE5100 (Color)

[ASRECORDS-1]
printer1=\\asd11\AS Records Hp 4200

[ASRECORDS-2]
printer1=\\asd11\AS Upper Guid DE5300

[ASS4A-1]
printer1=\\ash2\Rm S10 Classroom

[ASS4B-1]
printer1=\\ash2\Rm S10 Classroom

[ASS10C-1]
printer1=\\ash2\Rm S10 Classroom

[ASS10-C]
printer1=\\ash2\Rm S10 Classroom

[ASS101A-1]
building_printers=true

[ASSEC-1]
printer1=\\asd11\Sr Prin Dell 2330dn

[AS107-1]
building_printers=false
printer2=\\ASH2\Ricoh Copier Mail Rm

[ASA109-1]
building_printers=true

Top
#207136 - 2013-04-20 04:49 AM Re: Just Sharing - Adding Printers based on computer name via INI [Re: Glenn Barnas]
syntax53 Offline
Fresh Scripter

Registered: 2004-11-17
Posts: 31
Loc: Pennsylvania
 Originally Posted By: Glenn Barnas
If you're using my IniArray UDF, then the IniSections and IniKeys UDFs are redundant - you already have all of the data in the master array that was loaded. By using these extra UDFs, you're losing efficiency by loading the INI file into the array, then enumerating the INI file to locate data that's in your array.

I'm not sure what you mean here. I'm only reading the file once. Those two functions just take the default delimited string return from readiniarray function and puts it back into an array.


 Quote:
This UDF was updated just today, so you should pull the latest copy after 10pm EST tonight when it gets uploaded to our web site. The update improves performance for larger files and resoves a recently discovered bug that will appear when a section is defined in the file without any keys associated with it.

I put a link in my post the the UDF I'm using. It says it hasn't been updated since 8-2011.


 Quote:
You shouldn't have to do all the "UCase" commands as text comparisons are case insensitive unless you use a SetOption call to enable case sensitivity.

Yea, there are a lot of little things I do that are unnecessary, I know. Sometimes it's just for readability, but often it's because I write code primarily in PHP where it does matter a lot and it's just habit.


 Quote:
It's generally good practice to leave the headers in the UDFs as they contain important reference material.

I left links to all the UDFs in my post. The headers are quite long and I was already making a pretty lengthy post \:\)


 Quote:
You should never declare a GLOBAL var inside a function. Doing so will cause the var to be declared each time the function is called causing a Duplicate Definition error.

Good to know, I'll move it out.


 Quote:
I haven't reviewed the code in depth, but first blush it seems more complicated than necessary. If your computer name identifies the school and classroom along with a unique PC identifier, then a single config file could be used with one section per location and one key per classroom.

See my my reply to Lonkero above. I had only pasted a snipit of my full INI. The goal was to have as few sections in the INI as possible.

Top
#207140 - 2013-04-20 03:49 PM Re: Just Sharing - Adding Printers based on computer name via INI [Re: syntax53]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4273
Loc: New Jersey
OK - I misread the source of those two functions.. they're fine.

Most of my UDF posts reference this and many of the older farts around here know, but my web site always hosts the most current copy of the UDFs we use in production coding. I rewrote the PostPrep utility to run from a command line, and it has the ability to convert an entire folder's worth of UDFs to HTML format. Our web management server runs a task at 10pm nightly that converts all of our UDFs to HTM, so any updates will appear nightly. I do give a heads-up on KORG for some of the more popular UDFs and even update some of them here, but it's a good idea to always check our site for the most current versions.. Click the IT Resources menu, then Kixtart. The UDF Library link is in the middle of that page. There are 141 items on that link, including 4 "libraries" - collections of related UDFs for database access, WSUS management, task scheduler control, an MS Excel manipulation. The version string for IniArray() is
 Code:
;;VERSION        1.0 / 2011-08-02
;;		 1.1 / 2013-04-17 - improve file load on large files, bugfix

My reference to UCase didn't indicate it was wrong or bad form, just that it was unnecessary in Kix.

Before you just move the global declaration out of your UDF, take a look at the tcLib UDF Library, specifically the tcInit() function for an alternate method. This function declares global vars only if they don't already exist, allowing the first call to tcInit to initialize the environment and preload the arrays, following calls only preload the arrays.

I still think your method is complex. Tell me how your computer naming scheme works and I might be able to offer some ways to simplify. Right off the bat, with computer/user definitions, you might be able to do something like
 Code:
; configuration for a specific computer, with user-specific default printers. Unlisted users default to Printer1
[computer 1]
fred=Printer2
mary=Printer3
; printers map for all users, printer1 is set default unless a user-specific override is defined
Printer1=printer UNC
Printer2=printer UNC
Printer3=printer UNC
; disable mapping of all printers - default is to map
Building_Printers=No
to handle both generic and user-specific defaults with one record. Look at the Bool() UDF so your setting values can be Yes/No, True/False, On/Off, or 1/0.

Think about the data before the code.. realize that an INI value can hold many data items:
 Code:
[SECTION]
Value=D1,d2,"last, first",d5
Use the CSV() UDF to read a CSV data set:
 Code:
$aRecordData=CSV(ReadIniArray($Array, $Section, $Value))
This will create an array of the related data from just one read of the INI file or INI_Array. Packing data like this might simplify your code significantly. You might also consider a two-layer approach.. create a section for the school that defines the classrooms, this would point to sections that define the specific mappings. A slight increase in data complexity can result in sigificant reduction in code complexity. This is important with scripts like this that touch your entire user population. Simplicity = reliability.

Tell us more about the layout of the district and we'll be able to offer some specific ideas to make this nearly bullet-proof for you.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#207141 - 2013-04-20 04:19 PM Re: Just Sharing - Adding Printers based on computer name via INI [Re: Glenn Barnas]
Allen Administrator Online   shocked
KiX Supporter
*****

Registered: 2003-04-19
Posts: 4414
Loc: USA
I was about to ask how the INISections and INIKeys UDFs were inefficient (certainly they are redundant) but it seems that it got sorted out.

I think it's a matter of scripting preference regarding the UDFs. Personally I don't like dealing with multidimension arrays. Using the functions allows you to "See and Say" what is happening with all those values. Here is Glenn's example using the UDFs, done on the fly, untested.

 Code:
$aData = IniArray('.\file.ini')
For each $S in INISections($aData)
 'Section: ' + $S ?
 For each $K in INIKeys($aData,$S)
  'Key / Data: ' + $K + ' / ' +  ReadINIArray($aData,$S, $K) ?
 Next
Next





Top
#207142 - 2013-04-20 05:21 PM Re: Just Sharing - Adding Printers based on computer name via INI [Re: Allen]
ShaneEP Moderator Offline
MM club member
*****

Registered: 2002-11-29
Posts: 2078
Loc: Tulsa, OK
Wow has it already been almost 2 years since you wrote those INIArray functions?
Top
#207143 - 2013-04-20 06:05 PM Re: Just Sharing - Adding Printers based on computer name via INI [Re: ShaneEP]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4273
Loc: New Jersey
Allen - yeah, it was a crazy day and I thought I saw ReadProfileString in those functions, which would have performed duplicate INI reads.. my mistake.

Shane - time flies, whether you're having fun or not!

Note the recent code update on this UDF.. I'm getting slightly better performance loading the array with LARGE files and ironically slightly worse performance with tiny (1-2K) files, but we're talking 32-48ms worst on small files, but 100-500+ ms gains on larger files. Also, the worst-case is an estimate because the resolution of Kix @MSECS macro I used for timing is 16ms.

More importantly, the new version corrects a bug that can occur when your INI file contains a section with no keys. Technically, not valid, but possible with hand-written INI files. The old version loaded the section with no keys and threw an error when you asked for a key. The new code ignores empty sections on read.

I just updated the Universal Login Script to use IniArray and shaved 600ms off of a typical config, bringing production execution time for the script to under 2 seconds! Script overhead is just 750ms - the time it takes to load and process an empty config.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#207152 - 2013-04-21 08:02 PM Re: Just Sharing - Adding Printers based on computer name via INI [Re: Glenn Barnas]
ChristopheM Offline
Hey THIS is FUN
*****

Registered: 2002-05-13
Posts: 304
Loc: STRASBOURG, France
Just a remark about performance with ini file :
personnally, i am still using ReadProfileString but if i know the file to read is on a network share (like netlogon), i copy the file in a temporary local file and all following actions are done on the local file.

Why i do like that ?
the windows api is quite efficient but it is a monolithic operation. The ini file is read in memory, list of section, list of keyword or values are read and then, the file is closed and memory freed.

when this is done on a local file, the first time, the file is loaded in the local disk cache and next actions are done with the copy in the cache. This is very fast.
When the same thing is done on a network file, there is no cache. for each action, the all file is read through the network. Even if the network is very fast, this is slower than a local read.

Suppose you have to read 10 sections with 10 keys in a 10 kb file.
- locally, you read 10kb one time on disk
- from the network, you read 10 x 10 x 10kb (1 Mb). This is much more slower !!!

initially, in my login script, i read network file. it was really slow specially for WAN workstation. When i changed the script to create a temporay local file and, performances increased significantly.
_________________________
Christophe

Top
#207153 - 2013-04-21 11:01 PM Re: Just Sharing - Adding Printers based on computer name via INI [Re: ChristopheM]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4273
Loc: New Jersey
Christophe,

That's part of the point of the IniArray UDF suite. It uses standard File I/O to load the entire INI file into an array once rather than using multiple Read/WriteProfileString functions. The other purpose of this UDF is that it removes the 32/64K size limit of INI files. My earlier reference of a 600ms performance improvement was moving from ReadProfileString on a locally cached file to loading the same local file into IniArray and using ReadIniArray calls instead.

On a WAN, local caching of a 12K file before loading into IniArray will save between 0.4 and 1.3 seconds, depending on WAN speed. Directly reading the INI on the server with ReadProfileString is much worse and local caching has been known to knock off 15-20 seconds! This is why our Universal Login Script has been caching the INI file on local disk since 2006. The IniArray UDFs just take it to the next level, managing all INI functions in RAM.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#207154 - 2013-04-21 11:06 PM Re: Just Sharing - Adding Printers based on computer name via INI [Re: Glenn Barnas]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4273
Loc: New Jersey
FYI - Allen reported a bug in the IniArray package that occurs when you delete a key two or more times. This is an unusual situation (likely due to some wacky stuff Allen's doing \:D ) That bug's been fixed, but the problem brough to light some other issues with potentially invalid situations (empty section in INI, for example). I've run some significant tests on the current version and should have an update tonight or tomorrow. I'm waiting for Allen to test in his large INI app.

Bottom line, if you use IniArray and the related functions, please be on the lookout for the newest version (1.2) in the next 48 hours or so.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#207155 - 2013-04-22 12:04 AM Re: Just Sharing - Adding Printers based on computer name via INI [Re: Glenn Barnas]
Allen Administrator Online   shocked
KiX Supporter
*****

Registered: 2003-04-19
Posts: 4414
Loc: USA
I only found the bug in INIArray because I had a bug in my code. Nothing wacky going on.
Top
#207163 - 2013-04-22 04:41 PM Re: Just Sharing - Adding Printers based on computer name via INI [Re: Allen]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4273
Loc: New Jersey
Aren't bugs wacky? \:D
_________________________
Actually I am a Rocket Scientist! \:D

Top
#207171 - 2013-04-23 12:14 AM Re: Just Sharing - Adding Printers based on computer name via INI [Re: Glenn Barnas]
ChristopheM Offline
Hey THIS is FUN
*****

Registered: 2002-05-13
Posts: 304
Loc: STRASBOURG, France
Glenn,

i agree that it is a very bad idea to use readprofilestring with a network file. This is why I first copy network file to a local temp file and use the local file.

i have made a test of performance with your functions and with ReadProfileString on local files of several size. Here is my code :
 Code:
break on

dim $inifile, $tmpfile, $ini, $arrSections, $arrKeys, $section, $key, $d1, $d2

$arrInifiles =
  @scriptdir+"\test\file000.ini",
  @scriptdir+"\test\file001.ini",
  @scriptdir+"\test\file002.ini",
  @scriptdir+"\test\file003.ini",
  @scriptdir+"\test\file004.ini",
  @scriptdir+"\test\file005.ini",
  @scriptdir+"\test\file006.ini",
  ""

right( "        size",8 )
right( "        time1",8 )
right( "        time2",8 )
"  filename"
?
for each $inifile in $arrInifiles
  if $inifile
    $tmpfile = @scriptdir+"\"+@ScriptName+".tmp"
    COPY $inifile $tmpfile

    $size = GetFileSize($tmpfile)

    ;-- read with ini functions --
    $start = @TICKS
    $ini = IniArray( $tmpfile )
    $arrSections = IniSections($ini)
    for each $section in $arrSections
      $arrKeys = IniKeys( $ini, $section )
      for each $key in $arrKeys
        $value = ReadIniArray( $ini, $section, $key )
      next
    next
    $d1 = @TICKS - $start

    ;-- read with ReadProfileString --
    $start = @TICKS
    $arrSections = ReadProfileString( $tmpfile, "", "" )
    $arrSections = split($arrSections, chr(10) )
    for each $section in $arrSections
      if $section
        $arrKeys = ReadProfileString( $tmpfile, $section, "" )
        $arrKeys = split($arrKeys, chr(10) )
        for each $key in $arrKeys
          if $key
            $value = ReadProfileString( $tmpfile, $section, $key )
          endif
        next
      endif
    next
    $d2 = @TICKS - $start

    right( "        "+$size,8 )
    right( "        "+$d1,8 )
    right( "        "+$d2,8 )
    "  "
    $inifile
    ?

    DEL $tmpfile
  endif
next

;-- insert your ini functions here

I have been very surprised because on my workstation, code with ReadProfileString is always faster (Windows XP SP3 and never constated problem of file size) !!!
 Code:
    size   time1   time2  filename
      91       0       0  .\test\file000.ini
    2019       0       0  .\test\file001.ini
    7553      47      15  .\test\file002.ini
   34527     485      47  .\test\file003.ini
   69058    1078     140  .\test\file004.ini
  103587    1844     219  .\test\file005.ini
  138116    2735     344  .\test\file006.ini

First, i copy the ini file in a temp file. so, ini file is the local cache disk.
I think the difference of speed is due to many calls to functions with array that can be large. As variables are passed by value, each call duplicates the array in memory. With large ini file this can be much slower than call to ReadProfileString.

One of the first steps of my login script is to do a robocopy from \\netlogon to a local temp directory. Next, all scripts are executed from local directory.

We have the same login script for about 6000 users. At the first connection, the netlogon is copied locally. At the following connection, a new robocopy copies only changed files (not often). This is fast and efficient, specially for WAN workstations.

I will make other tests tomorrow at the office on several types of workstations to see if results are reproductible...

Now, it's time to sleep in France ;\)
_________________________
Christophe

Top
#207175 - 2013-04-23 03:16 PM Re: Just Sharing - Adding Printers based on computer name via INI [Re: ChristopheM]
Lonkero Administrator Offline
KiX Master Guru
*****

Registered: 2001-06-05
Posts: 22303
Loc: OK
the difference most likely comes from the fact that the first read is done from the disk and AV is possibly interfering with it too.
you should do a simple:
 Code:
$trash=open(1,$tmpfile) do $trash=readline() until @error $trash=close(1)


to make sure the file is indeed cached before timing the difference.
_________________________
!

download KiXnet

Top
#207176 - 2013-04-23 07:12 PM Re: Just Sharing - Adding Printers based on computer name via INI [Re: Lonkero]
ChristopheM Offline
Hey THIS is FUN
*****

Registered: 2002-05-13
Posts: 304
Loc: STRASBOURG, France
may be AV is impacting the result but i start by a COPY to tmpfile so this file should already be in the cache and should have been scanned by the AV.

i tried to add your line in my code. the result is
 Code:
    size   time1   time2  filename
      91       0       0  .\test\file000.ini
    2019       0       0  .\test\file001.ini
    7553      47      16  .\test\file002.ini
   34527     484      47  .\test\file003.ini
   69058    1094     141  .\test\file004.ini
  103587    1859     250  .\test\file005.ini
  138116    2796     375  .\test\file006.ini

This is very near from the previous results !!!

if i have free time, i'll try to test a new version of ini functions based on a "ini handle" in spite of array of strings. The idea is that IniArray loads data in a global internal array and returns a handle. Next calls to ReadIniArray, IniSections or IniKeys just used this handle. I hope duplicating of an integer is much more faster than duplicating an array.

Theorically, impact is null on functions but navigation in the inifile with access to the 3D array becomes impossible (this should not be used).
This solution also needs to add an IniClose function to free memory array and handle.
_________________________
Christophe

Top
#207177 - 2013-04-23 09:13 PM Re: Just Sharing - Adding Printers based on computer name via INI [Re: ChristopheM]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4273
Loc: New Jersey
I have a version that does indirect references to global arrays..

I had several people using this version so wanted to address some of the issues they had before updating/releasing the other version. The interface is the same, except you pass the name of the array, not the array itself.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
Page 1 of 2 12>


Moderator:  Glenn Barnas, NTDOC, Arend_, Jochen, Radimus, Allen, ShaneEP, Mart 
Hop to:
Shout Box

Who's Online
1 registered (Allen) and 20 anonymous users online.
Newest Members
Hadfevfegrt477a, Hdrthtsr19956, Kylie99, msmile042, rayd8
17598 Registered Users

Generated in 0.094 seconds in which 0.032 seconds were spent on a total of 14 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org