Adam Crichton
(Fresh Scripter)
2003-03-17 04:28 AM
Mapping Printers by IP Subnet

Pardon what may be a very bad newbie question. I've never written a script before but I need to map printers based on subnet. After reading the boards and the FAQ I came up with this:

code:
$ipaddress=@IPADDRESS0
$iparray[0]='192.168.2.0/24'
if isiniprange($ipaddress,$iparray)
$S=AddPrinterConnection ("\\diction\Woodstock Front Desk02")
$S=AddPrinterConnection ("\\woodstock02\Woodstock Label Printer")
$S=AddPrinterConnection ("\\diction\OHIP")
$S=SetDefaultPrinter ("\\diction\Woodstock Front Desk02")
ENDIF
$ipaddress=@IPADDRESS0
$iparray[0]='192.168.3.0/24'
if isiniprange($ipaddress,$iparray)
$S=AddPrinterConnection ("\\diction\Stratford Front Desk02")
$S=AddPrinterConnection ("\\stratford01\Stratford Label Printer")
$S=AddPrinterConnection ("\\diction\OHIP")
$S=SetDefaultPrinter ("\\diction\Stratford Front Desk02")
ENDIF
$ipaddress=@IPADDRESS0
$iparray[0]='192.168.4.0/24'
if isiniprange($ipaddress,$iparray)
$S=AddPrinterConnection ("\\goderichfrndsk\Goderich Front Desk01")
$S=AddPrinterConnection ("\\goderichfrndsk\Goderich Label Printer")
$S=AddPrinterConnection ("\\diction\OHIP")
$S=SetDefaultPrinter ("\\goderichfrndsk\Goderich Front Desk01")
ENDIF

Naturally this doesn't work (first try after all). Any ideas why? Would appreciate a pointer if anyone has time.

Thanks a lot.

[ 17. March 2003, 04:52: Message edited by: Adam Crichton ]


Howard Bullock
(KiX Supporter)
2003-03-17 04:47 AM
Re: Mapping Printers by IP Subnet

What part doesn't work? Some of that detail would be useful. You are missing an "endif" at the end of your published script.

Adam Crichton
(Fresh Scripter)
2003-03-17 04:50 AM
Re: Mapping Printers by IP Subnet

Oh I'm sorry. The ENDIF is actually in the script, I made an error when I pasted it into the code.

The script does not map any printers from any of the IP ranges described. I apologize for being vague I thought I would be making a simple mistake someone would notice right away.

Thanks though.


Howard Bullock
(KiX Supporter)
2003-03-17 04:53 AM
Re: Mapping Printers by IP Subnet

Does your script include the code for the IsInIPrange() UDF?

Have you placed a print statement in each IF..EndIf to see if the IF condition worked? If so, then what are the return codes for the ADDPrinterConnection().

What OS is the client?

[ 17. March 2003, 04:54: Message edited by: Howard Bullock ]


Adam Crichton
(Fresh Scripter)
2003-03-17 04:59 AM
Re: Mapping Printers by IP Subnet

Ah ha. My script does not include the code for the IsInIPrange() UDF? What should that be? I'm sure that's what I'm missing.

The clients are all XP (I notice the addprinterconnection doesn't work in 9x).

The error is:
Script error: expected expression!
if isiniprage($ipaddress,$iparray)

Thanks for your help.


Howard Bullock
(KiX Supporter)
2003-03-17 05:02 AM
Re: Mapping Printers by IP Subnet

Go get the code for "isiniprage". You can find it by looking in the UDF Library or better yet follow the UDF Collection link in my signature line.

Adam Crichton
(Fresh Scripter)
2003-03-17 05:09 AM
Re: Mapping Printers by IP Subnet

OK - progress - pasted that into my script - different error now:

Script Error: error in expression!
$iparray[0]='192.168.3.0/24'

The FAQ seemed to indicate I could use the bit subnet identifier. Could that be the problem? Or am I missing something still.

Really appreciate the help.


Howard Bullock
(KiX Supporter)
2003-03-17 05:12 AM
Re: Mapping Printers by IP Subnet

Try adding "Dim $iparray[0]" at the top of your script.

Also you do not need to get the IP address multiple times.

[ 17. March 2003, 05:13: Message edited by: Howard Bullock ]


Adam Crichton
(Fresh Scripter)
2003-03-17 05:18 AM
Re: Mapping Printers by IP Subnet

More progress (again thanks for the help), still no luck, new error:

Script Error: expected expression!
if isinsubnet($ipaddresss,$networkid,$subnetmask)

So close [Confused]


Howard Bullock
(KiX Supporter)
2003-03-17 05:20 AM
Re: Mapping Printers by IP Subnet

Now that you have had some fun trouble shooting...

This is how I would format it:

Dim $iparray[2]
$ipaddress=@IPADDRESS0
$iparray[0]='192.168.2.0/24'
$iparray[1]='192.168.3.0/24'
$iparray[2]='192.168.4.0/24'

call "isiniprange.udf"

Select
   case isiniprange($ipaddress,$iparray[0])
      $S=AddPrinterConnection ("\\diction\Woodstock Front Desk02")
      $S=AddPrinterConnection ("\\woodstock02\Woodstock Label Printer")
      $S=AddPrinterConnection ("\\diction\OHIP")
      $S=SetDefaultPrinter ("\\diction\Woodstock Front Desk02")

   case isiniprange($ipaddress,$iparray[1])
      $S=AddPrinterConnection ("\\diction\Stratford Front Desk02")
      $S=AddPrinterConnection ("\\stratford01\Stratford Label Printer")
      $S=AddPrinterConnection ("\\diction\OHIP")
      $S=SetDefaultPrinter ("\\diction\Stratford Front Desk02")

   case isiniprange($ipaddress,$iparray[2])
      $S=AddPrinterConnection ("\\goderichfrndsk\Goderich Front Desk01")
      $S=AddPrinterConnection ("\\goderichfrndsk\Goderich Label Printer")
      $S=AddPrinterConnection ("\\diction\OHIP")
      $S=SetDefaultPrinter ("\\goderichfrndsk\Goderich Front Desk01")
EndSelect



{edit} used PostPrep so that one could copy/paste directly to your text editor.

Also check the dependencies of IsInIPrange().

[ 17. March 2003, 05:49: Message edited by: Howard Bullock ]


Howard Bullock
(KiX Supporter)
2003-03-17 05:22 AM
Re: Mapping Printers by IP Subnet

When and why did you change from "isiniprange" to "isinsubnet"? Did you place that code in your program?

Howard Bullock
(KiX Supporter)
2003-03-17 05:25 AM
Re: Mapping Printers by IP Subnet

Did you read the dependencies of IsInIPrange()? It requires additional code.

code:
;DEPENDENCIES  BINARYIP() 
; ISINSUBNET()



[ 17. March 2003, 05:32: Message edited by: Howard Bullock ]


Howard Bullock
(KiX Supporter)
2003-03-17 05:29 AM
Re: Mapping Printers by IP Subnet

You could also look into:

$LogicalSubnet = CalcLogicalSubnet (EnumIpInfo(0), EnumIpInfo(1))

[ 17. March 2003, 05:30: Message edited by: Howard Bullock ]


Adam Crichton
(Fresh Scripter)
2003-03-17 05:36 AM
Re: Mapping Printers by IP Subnet

OK first I like your method better for selecting the IP's it's much cleaner (my way is what happens when people with Arts degrees try to write code). And I didn't see the dependencies so those are now in.

So now we have what I think might be our last error:

Script Error: array reference out of bounds!
$iparray[1]='192.168.3.0/24'


Howard Bullock
(KiX Supporter)
2003-03-17 05:40 AM
Re: Mapping Printers by IP Subnet

Do you have the "DIM $iparray[2]" statement in your code?

Did you copy the code from the post, paste it into WORD.exe, and then copy/paste it to you text editor?

[ 17. March 2003, 05:40: Message edited by: Howard Bullock ]


Adam Crichton
(Fresh Scripter)
2003-03-17 05:44 AM
Re: Mapping Printers by IP Subnet

Yes, I noticed that I needed to add that DIM statment (actually added all three), so that's fine now, and I also worked out about pasting into word first so it formats correctly before I paste it into the text editor.

Anyway, still the same error message. Sigh.

Thanks.


Howard Bullock
(KiX Supporter)
2003-03-17 05:46 AM
Re: Mapping Printers by IP Subnet

Please post your code. What do you mean
quote:
I noticed that I needed to add that DIM statment (actually added all three)


Howard Bullock
(KiX Supporter)
2003-03-17 05:50 AM
Re: Mapping Printers by IP Subnet

Go back and recopy the code. I missed a QUOTE. You can now copy it directly into your text editor.

Adam Crichton
(Fresh Scripter)
2003-03-17 05:51 AM
Re: Mapping Printers by IP Subnet

OK here's where it's at now; the paste is botching it a little bit (in the printer add area) and I'm sorry but I really have been working on this all day and it's driving me crazy. I included the UDF's to make it easier.

Thanks so much for your help:

code:
function ipmask($ipaddress1, $ipaddress2)
Dim $bit if instr($ipaddress1,'.') or instr($ipaddress2,'.') or len($ipaddress1)<>32 or len($ipaddress2)<>32
exit 87
endif $ipmask=''
for $bit=1 to 32
$ipmask=$ipmask+(val(substr($ipaddress1,$bit,1)) & val(substr($ipaddress2,$bit,1)))
next
endfunction


function BinaryIP($IP)
DIM $item, $bitsize, $octet $bitsize = 128
$ip = split($IP,".") select
case UBOUND($ip) <> 3
$BinaryIP = 0
exit(87)
case 1
for each $octet in $ip
if VAL($octet) <0 OR VAL($octet) > 255
$BinaryIP = 0
exit(87)
endif
while $bitsize > 0
if val($octet) & $bitsize
$Binary = $Binary + "1"
else
$Binary = $Binary + "0"
endif
$bitsize = $bitsize / 2
loop
$binaryIP = $binaryIP + "$binary"
$bitsize = 128
$binary = ""
next
endselect
exit(0)
endfunction

function isinsubnet($ipaddress,$networkid,$subnetmask)
Dim $maskedip, $bit

if instr($ipaddress,'.')
$ipaddress=binaryip($ipaddress)
endif
if instr($networkid,'.')
$networkid=binaryip($networkid)
endif
if instr($subnetmask,'.')
$subnetmask=binaryip($subnetmask)
endif

$maskedip=ipmask($ipaddress,$subnetmask)
if $maskedip=$networkid
$isinsubnet = 1
else
$isinsubnet = 0
endif
endfunction

function isiniprange($ipaddress,$iprangearray)
Dim $iprange, $networkid, $subnetmask, $bit

if $ipaddress=''
exit 87
endif

$ipaddress=binaryip($ipaddress)

for each $iprange in $iprangearray

if instr($iprange,'/')
$iprange=split($iprange,'/')
$networkid=binaryip($iprange[0])

if instr($iprange[1],'.')
$subnetmask=binaryip($iprange[1])
else
$subnetmask=''
for $bit=1 to val($iprange[1])
$subnetmask=$subnetmask+'1'
next
for $bit=(val($iprange[1])+1) to 32
$subnetmask=$subnetmask+'0'
next
endif

if isinsubnet($ipaddress,$networkid,$subnetmask)
$isiniprange=1
return
else
$isiniprange=0
endif
endif
next

endfunction

DIM $iparray[0]
DIM $iparray[1]
DIM $iparray[2]
$ipaddress=@IPADDRESS0
$iparray[0]='192.168.2.0/24'
$iparray[1]='192.168.3.0/24'
$iparray[2]='192.168.4.0/24
call "isiniprange.udf"
Select
case isiniprange($ipaddress,$iparray[0])
$S=AddPrinterConnection ("\\diction\Woodstock Front Desk02") $S=AddPrinterConnection ("\\woodstock02\Woodstock Label Printer") $S=AddPrinterConnection ("\\diction\OHIP")
$S=SetDefaultPrinter ("\\diction\Woodstock Front Desk02")

case isiniprange($ipaddress,$iparray[1])
$S=AddPrinterConnection ("\\diction\Stratford Front Desk02")
$S=AddPrinterConnection ("\\stratford01\Stratford Label Printer") $S=AddPrinterConnection ("\\diction\OHIP")
$S=SetDefaultPrinter ("\\diction\Stratford Front Desk02")

case isiniprange($ipaddress,$iparray[2])
$S=AddPrinterConnection ("\\goderichfrndsk\Goderich Front Desk01") $S=AddPrinterConnection ("\\goderichfrndsk\Goderich Label Printer") $S=AddPrinterConnection ("\\diction\OHIP")
$S=SetDefaultPrinter ("\\goderichfrndsk\Goderich Front Desk01")
EndSelect
:END



Howard Bullock
(KiX Supporter)
2003-03-17 05:54 AM
Re: Mapping Printers by IP Subnet

Remove the following lines:

DIM $iparray[0]
DIM $iparray[1]
call "isiniprange.udf"

Add single-quote to end of:
$iparray[2]='192.168.4.0/24


Adam Crichton
(Fresh Scripter)
2003-03-17 06:02 AM
Re: Mapping Printers by IP Subnet

OK looking good - nearly there I'm sure. No errors from the scripts, but also no printers on the client.

Checked Printer and Queue names are the same in this case, so that can't be it.

Why isn't anything ever easy . . .

Thanks.


LonkeroAdministrator
(KiX Master Guru)
2003-03-17 06:06 AM
Re: Mapping Printers by IP Subnet

one minor.
you must use printer's sharename when doing addprinterconnection() and printername when doing setdefaultprinter.

and these names look not like sharenames [Wink]


Howard Bullock
(KiX Supporter)
2003-03-17 06:07 AM
Re: Mapping Printers by IP Subnet

You will have to add code to verify you are getting into the proper case statement. You should also evaluate the return code from the AddPrinterConnection function.

code:
AddPrinterConnection( )

Action: Adds a connection to the specified printer for the current user.

Syntax: ADDPRINTERCONNECTION ("printer name")

Parameters: Printer name

The (share)name of the printer to which to connect.

Remarks: This function is available only on Windows NT family,
and can be used only to connect to printers on a server running the
Windows NT/2000/XP operating system.

When Windows NT connects to the printer, it may copy printer driver
files to the local computer. If the user does not have permission to copy
files to the appropriate location, ADDPRINTERCONNECTION fails, and
@ERROR returns ERROR_ACCESS_DENIED.


Returns: 0 Printer connection established
Error code Function failed


See Also: DelPrinterConnection( ), SetDefaultPrinter( )

Example: If ADDPRINTERCONNECTION ("\\vleerbeer\hp laserjet 4") = 0
? "Added printer connection...."
else
? "@error @serror"
Endif




[ 17. March 2003, 06:08: Message edited by: Howard Bullock ]


Adam Crichton
(Fresh Scripter)
2003-03-17 06:18 AM
Re: Mapping Printers by IP Subnet

Printername and Sharename in this case are the same (I set them up purposefully this way) so that's OK in this case.

I put in the a bit of code to output errors and trace where in the add printer component of the kix script it is and I get no output. That leads me to believe it's skipping the entire process. I'll keep checking.


Howard Bullock
(KiX Supporter)
2003-03-17 06:25 AM
Re: Mapping Printers by IP Subnet

Add a catchall case to the select...endselect block.

Add as the last case:
code:
case 1
? "Failed to find IP range"

You may also wnat to add the following code to see what each IsInIPrange() returns:
code:
? "isiniprange($ipaddress,$iparray[0]) = " + isiniprange($ipaddress,$iparray[0])
? "isiniprange($ipaddress,$iparray[1]) = " + isiniprange($ipaddress,$iparray[1])
? "isiniprange($ipaddress,$iparray[2]) = " + isiniprange($ipaddress,$iparray[2])



LonkeroAdministrator
(KiX Master Guru)
2003-03-17 06:25 AM
Re: Mapping Printers by IP Subnet

so, did you already remove the suggested lines?
the call-line will crash as the udf is already defined in main-script.


Adam Crichton
(Fresh Scripter)
2003-03-17 06:32 AM
Re: Mapping Printers by IP Subnet

Yes, the suggested lines have been removed - everything on the script looks good. I added in the code to check for errors and the following output appears:

Failed to find IP range
isiniprange(192.168.3.14,$iparray[0]) =
isiniprange(192.168.3.14,$iparray[1]) =
isiniprange(192.168.3.14,$iparray[2]) =

So it's correctly reading the IP (ie 192.168.3.14 is the client IP) but it's not actually executing the add printer functions based on that.


Howard Bullock
(KiX Supporter)
2003-03-17 06:36 AM
Re: Mapping Printers by IP Subnet

I am headed to bed now. Based on your output, I would have to say that isiniprange is not returning a value. You may have to dig a little deeper.

I will check on your progress in the morning. Some of the Europeans may be able to continue working with you,


Adam Crichton
(Fresh Scripter)
2003-03-17 06:41 AM
Re: Mapping Printers by IP Subnet

OK thanks hopefully I can keep working with some people on it appreciate the help.

Adam Crichton
(Fresh Scripter)
2003-03-17 06:52 AM
Re: Mapping Printers by IP Subnet

OK I got it - thanks everyone for your help.

As it happened something about the select case methodlogy was the problem. When I switched it back to way I had it orginally, but with all the necessary prerequises and UDF's it worked perfectly. Is it appropriate for me to repost the code in its entirity?

Thanks so much for the help.


LonkeroAdministrator
(KiX Master Guru)
2003-03-17 06:58 AM
Re: Mapping Printers by IP Subnet

please do so.
this way we may study the problem too [Wink]


Howard Bullock
(KiX Supporter)
2003-03-17 07:00 AM
Re: Mapping Printers by IP Subnet

I don't understand why the select...case...endselect would be any different than the IF statements in their ability to function. I suspect something else in your code.

I am glad your code is functional though.

Feel free to post your good code as well as your non-functional code so that we can possibly determine what was wrong.


Adam Crichton
(Fresh Scripter)
2003-03-17 07:23 AM
Re: Mapping Printers by IP Subnet

Here is the code that works. I have cut out all the misc. required UDF's; we'll assume those have been added. As you can see I have added another subnet on. Of course the select code is already in the earlier post so that's what I used; I won't reprint that here.

code:
Dim $iparray[3]

$ipaddress=@IPADDRESS0
$iparray[0]='192.168.2.0/24'
if isiniprange($ipaddress,$iparray)
$S=AddPrinterConnection ("\\diction\Woodstock Front Desk02")
$S=AddPrinterConnection ("\\woodstock02\Woodstock Label Printer")
$S=AddPrinterConnection ("\\diction\OHIP")
$S=SetDefaultPrinter ("\\diction\Woodstock Front Desk02")
ENDIF
$iparray[1]='192.168.3.0/24'
if isiniprange($ipaddress,$iparray)
$S=AddPrinterConnection ("\\diction\Stratford Front Desk02")
$S=AddPrinterConnection ("\\stratford01\Stratford Label Printer")
$S=AddPrinterConnection ("\\diction\OHIP")
$S=SetDefaultPrinter ("\\diction\Stratford Front Desk02")
ENDIF
$iparray[2]='192.168.4.0/24'
if isiniprange($ipaddress,$iparray)
$S=AddPrinterConnection ("\\goderichfrndsk\Goderich Front Desk01")
$S=AddPrinterConnection ("\\goderichfrndsk\Goderich Label Printer")
$S=AddPrinterConnection ("\\diction\OHIP")
$S=SetDefaultPrinter ("\\goderichfrndsk\Goderich Front Desk01")
ENDIF
$iparray[3]='192.168.1.0/24'
if isiniprange($ipaddress,$iparray)
$S=AddPrinterConnection ("\\diction\Cambridge Front Desk01")
$S=AddPrinterConnection ("\\diction\Cambridge Front Desk02")
$S=AddPrinterConnection ("\\diction\transcription")
$S=AddPrinterConnection ("\\diction\Mbryant Office")
$S=AddPrinterConnection ("\\diction\OHIP")
$S=AddPrinterConnection ("\\cambridge03\Clabel")
$S=SetDefaultPrinter ("\\diction\Cambridge Front Desk01")
ENDIF



Howard Bullock
(KiX Supporter)
2003-03-18 12:39 AM
Re: Mapping Printers by IP Subnet

The only thing that concerns me with this implementation passes the completed array of subnets for each IF statement. Since you add the subnet being checked right before each IF the code should work but does not sit well with me.

Maybe Sealeopard can shed some light on why the previous code did not work.


LonkeroAdministrator
(KiX Master Guru)
2003-03-17 01:25 PM
Re: Mapping Printers by IP Subnet

I indeed would like to see also that non-working code...
I bet that there is some little quotation or similar error...


Sealeopard
(KiX Master)
2003-03-17 03:23 PM
Re: Mapping Printers by IP Subnet

!@#$, I just lost the answer I posted. So, now here's the short version. There was a bug in the IsInIPRange where it didn't work with a string as second parameter. The reasonwas that FOR EACH $b IN $a won't work if $a is a string. This has now beeen corrected in the UDF and an updated UDF is available at IsInIPRange() - Checks if IP address is part of a network (network ID/subnet mask) .

Adam: Please read How to use UDFs

[ 17. March 2003, 15:24: Message edited by: sealeopard ]


Adam Crichton
(Fresh Scripter)
2003-03-18 11:21 PM
Re: Mapping Printers by IP Subnet

Thanks all for your help on this - sorry for the delay in posting an update. The code that didn't work was cut and paste from the earlier message in the thread so I don't see any reason to repost it here. Still glad to see everything was straightened around and really appreciate the help. It saved a LOT of manual work.

Regards.


LonkeroAdministrator
(KiX Master Guru)
2003-03-18 11:32 PM
Re: Mapping Printers by IP Subnet

actually, the non-working code would still be good.
as the good that you said worked is actually a wicked way to make it work.

you can use that but it's a lot harder to keep up to date than proper setup.