Page 1 of 1 1
Topic Options
#191941 - 2009-01-28 12:53 PM Network printer moving from server to server
AvisKjetil Offline
Just in Town

Registered: 2009-01-28
Posts: 4
Loc: Norway
Hi.

I hope this is the place for this query...

I'm fairly new at KiXTart (have done quite a lot of other programming, though) and have inherited a script that maps network printers in our Citrix TS environment. It works fine, but now we have to make changes to our printer environment. We're moving printers from one server to three, based on driver, which kinda changes things.

Printer names are kept. I have a security group in my AD for each printer, printer name contained within the group name and user indirectly member of it - which is my current method of distribution.

The scope of this excercise is 600 users, 250 printers in 200 geographical locations.

On monday (yep - 5 days) I will have to have the following in working order and I hoped one of you unequalled gurus could give me a few pointers. The main goal is to remove the old printers and replace them with the new without the user noticing.

1. I (think I) need to obtain and keep (for the duration of the script) a list of the user's printers, making a note of which one is the default - and then remove (disconnect) them.

2. I need to ascertain which of my three new printservers the printers I found in bullet one is located on (without trying to add printer and wait for it to fail...). I know that I can query AD for published printers using VBScript - is that possible in KiX? Can I fire a VBScript and pass the list back to KiX?

We run KiXTart v. 4.6, Citrix PS 4.5 on Windows Server 2003, our AD is running in 2003 native mode.

In the following script the domain is called SD, a typical printer group PRT_NOA_OSI_HC and the corresponding printer object NOA_OSI_HC:

 Code:
$Index = 0
$PrintGroups = ""
$PrintName = ""
$HQServer = "\\NOPRTHQ02\"
$HCServer = "\\NOPRTHC02\"
$Server = ""
$Index = 0
$Index2 = 0
$ValueName = ""
$ValueName2 = ""
$Install = "YES"

;====================================
;	REMOVE PRINTERS NOT REGISTERED
;====================================

$Index = 0
:Loop1
$ValueName = ENUMVALUE("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts", $Index)
If @ERROR = 0
	$ValueName2 = Right ($ValueName, Len ($ValueName) - InStrRev($ValueName, "\"))
	If NOT InGroup ("SD\PRT_" + $ValueName2)
; 		Kommentert ut For NFRA pilot
; 		DelPrinterConnection($ValueName)
; 		? "Printer deleted: " + $ValueName
	EndIf
    $Index = $Index + 1
    Goto Loop1
EndIf

;====================================
;	ADD PRINTERS NOT ALREADY ADDED
;====================================

$Index = 0
Do
	$Group = EnumGroup($Index)
	If Mid($Group,4,4) = "PRT_"
		$PrintGroups = $PrintGroups + ", " + $Group
		$PrintName = Right($Group, Len($Group)-7)
		if Mid($PrintName,4,1) = "_"
			$Server = $HCServer
		else
			$Server = $HQServer
		EndIf
		;   Check Registry - finn alle installerte skriverobjekter
		$Index2 = 0
		:Loop2
		$ValueName = ENUMVALUE("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts", $Index2)
		If @ERROR = 0
			$ValueName2 = Right ($ValueName, Len ($ValueName) - InStrRev($ValueName, "\"))
			If $ValueName2 = $PrintName
				? "Printer already exist: " + $PrintName
				$Install = "NO"
			EndIf
		    $Index2 = $Index2 + 1
		    Goto Loop2
		EndIf
		If $Install = "YES"
			ADDPRINTERCONNECTION($Server + $PrintName)
			? "Printer added: " + $Server + $PrintName
		EndIf
		$Install = "YES"
	EndIf
	$Index = $Index + 1
Until Len($Group) = 0


;---------------;
; function: MID ;
;---------------;

Function MID($midstring,$midstart,optional $midend)
;SYNTAX mid($midstring,$midstart,optional $midend)
;
;PARAMETERS $Midstring         - String of characters to search
;           $Midstart          - Character Index number to start with.  
;                                Base 1 or -1:  Positve Number = Left, Negative Number = Right
;           $Midend (optional) - Number of Characters to include from $midstart
;
;
;Example
;
;  $string='Hello this is a test'
;
;?  Mid($string,7,4)   ;returns 'this'
;?  Mid($string,7)     ;returns 'this is a test'
;?  Mid($string,-6)    ;returns 'Hello this is a'
;?  Mid($string,-8,2)  ;returns 'is'

  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


Help?
_________________________
Share and enjoy - Kjetil

Top
#191944 - 2009-01-28 03:23 PM Re: Network printer moving from server to server [Re: AvisKjetil]
Mart Moderator Offline
KiX Supporter
*****

Registered: 2002-03-27
Posts: 4673
Loc: The Netherlands
Hi and welcome to the board.

Did not test it but this should work imho.
Some parts could be shortened (like combining the join/split on one line) but at least now it is still readable

 Code:
Break on

$printers = EnumPrinterConnections2()
$defaultprinter = GetDefaultPrinter()
$oldserver = "oldservername"
$newserver = "newservername"

For Each $printer in $printers
	If InStr($printer, $oldserver)
		$rc = DelPrinterConnection($printer)
		$newprinter = Split($printer, $oldserver)
		$newprinter = Join($newprinter, $newserver")
		$rc = AddPrinterConnection($newprinter)
		If $printer = $defaultprinter
			$rc = SetDefaultPrinter($newprinter)
		EndIf
	EndIf
Next


;=========================================================
;===== DOT NOT MODIFY ANYTHING BELOW THIS LINE ===========
;===== THIS ARE UDF"S AND THEY COME READY MADE ===========
;=========================================================
;FUNCTION         GetDefaultPrinter()
;
;AUTHOR           Jochen Polster
;
;VERSION          1.0
;
;VERSION HISTORY  1.0 2004/04/28 Initial release
;
;ACTION           Retrieves the current default Printer
;
;SYNTAX           GetDefaultPrinter()
;
;PARAMETERS       none
;
;REMARKS          won't work with 9x OS
;
;RETURNS          The current Users default Printer
;
;DEPENDENCIES     None !
;
;EXAMPLES         $default = GetDefaultPrinter

Function GetDefaultPrinter()
	$GetDefaultPrinter = Join(Split(ReadValue("HKU\" + @sid + "\Software\Microsoft\Windows NT\CurrentVersion\Windows", "Device"), ',', 1), '')
EndFunction

	

;Function		EnumPrinterConnections2() - Enumerates all connected printers 
;   
;Author			NTDOC 
;   
;Contributors		Bryce 
;   
;Action			Enumerates all of the installed / connected printers into an array  
;   
;Syntax			EnumPrinterConnections2()  
;   
;Version		1.0  
;   
;Date			2005-Apr-20   
;   
;Date Revised		xxxx-xxx-xx   
;   
;Revision Reason	  
;   
;Parameters		None 
;   
;Remarks		Based on the EnumPrinterConnections() UDF 
;			http://www.kixtart.org/ubbthreads/showflat.php?Cat=&Number=83545 
;			Which I believe was probably derived from here at Microsoft 
;              EnumPrinterConnections Method 
;			Minor modifications due to invalid array dim and array starts 
;			with a blank which can cause issues when trying to display or 
;			write to a log file.  This method should work a little better. 
;			 
;			Tested on 2000/XP/2003  
;   
;Returns		An array of all the installed / connected printers 
;   
;Dependencies		KiXtart v4.x, WSH 5.6  
;			Written and tested with KiXtart v4.23 
; 
;Example		NOTE! This example uses the QS UDF to sort the list 
;			http://www.kixtart.org/ubbthreads/showflat.php?Cat=&Number=82876 
; 
;			Dim $PrinterData, $PrinterMap, $Pi 
;			$PrinterData = QS(EnumPrinterConnections2()) 
;			If Ubound($PrinterData) <> -1 
;			  For $Pi = 0 To Ubound($PrinterData) 
;			    $PrinterMap = Split($PrinterData[$Pi],",",-1) 
;			    $PrinterMap[0]+CHR(9)+$PrinterMap[1] ? 
;			  Next 
;			Else 
;			  ? 'No printer mappings found.' 
;			EndIf 
; 
;Source  
 

Function EnumPrinterConnections2()
	Dim $WshNetwork, $oPrinters, $i, $PrintArray[0]
	$EnumPrinterConnections2 = ""
	$WshNetwork = CreateObject("WScript.Network")
	If Not @ERROR
		$oPrinters = $WshNetwork.EnumPrinterConnections
		For $i = 0 to $oPrinters.Count - 1 Step 2
			$PrintArray[UBound($PrintArray)] = $oPrinters.Item($i + 1) + ',' + $oPrinters.Item($i)
			ReDim Preserve $PrintArray[UBound($PrintArray) + 1]
		Next
		If UBound($PrintArray) > 0
			ReDim Preserve $PrintArray[UBound($PrintArray) - 1]
		Else
			$PrintArray = 0
		EndIf
	Else
		$EnumPrinterConnections2 = @ERROR
		Exit $EnumPrinterConnections2
	EndIf
	$EnumPrinterConnections2 = $PrintArray
EndFunction
_________________________
Mart

- Chuck Norris once sold ebay to ebay on ebay.

Top
#191946 - 2009-01-28 04:35 PM Re: Network printer moving from server to server [Re: Mart]
AvisKjetil Offline
Just in Town

Registered: 2009-01-28
Posts: 4
Loc: Norway
Thanks, Mart, I hope I can contribute in time, not only receive.

This looks like a very good start, but have you any idea how I can identify which of my three printservers the printer moved to? Since $newserver can be any one of them I'm still in something of a fix...
_________________________
Share and enjoy - Kjetil

Top
#191947 - 2009-01-28 05:07 PM Re: Network printer moving from server to server [Re: AvisKjetil]
Mart Moderator Offline
KiX Supporter
*****

Registered: 2002-03-27
Posts: 4673
Loc: The Netherlands
You could use an ini file that looks line this.

 Quote:

[newserver1]
Printers=printer1,printer2
[newserver2]
printers=printer3,printer4
[newserver3]
printers=printer5,printer6


Looping through all the newserver sections to find the printer (you now the new server all ready by then because of the section you are looking in) and do your magic when the printer is found in one of the sections.

Would like to hand over an example but I have to leave now. I have an appointment in 30 minutes and traffic seems to be a nightmare.

I hope I gave you a push into the right direction.
_________________________
Mart

- Chuck Norris once sold ebay to ebay on ebay.

Top
#191964 - 2009-01-29 09:45 AM Re: Network printer moving from server to server [Re: Mart]
AvisKjetil Offline
Just in Town

Registered: 2009-01-28
Posts: 4
Loc: Norway
Thank you very much for your time, Mart, I'll give your tips a shot.

I was a little concerned about keeping this ini-file updated, but I realised that if I set up a scheduled script that updates it overnight I would be more or less home safe - my environment isn't that dynamic anyway.

I'll post the end result here as soon as I have something working.
_________________________
Share and enjoy - Kjetil

Top
#192066 - 2009-02-05 01:42 PM Re: Network printer moving from server to server [Re: AvisKjetil]
AvisKjetil Offline
Just in Town

Registered: 2009-01-28
Posts: 4
Loc: Norway
The end result is below. I got seriously pressed for time and decided to forego elegance in favour of a more brute-force approach. The functionality in a nutshell:
- Find current network printers (don't touch local) from any of my three old servers
- Find current default printer
- (Try to) connect to the printername on one of the two new servers ($newserver). If that fails try the other server($altserver).
- If the current printer was default earlier - set it as default now.

 Code:
$printers = EnumPrinterConnections2()
$defaultprinter = GetDefaultPrinter()
$newserver = "novmprthp01"
$altserver = "novmprtdiv01"

For Each $printer in $printers
;	Handle only network printers
	If Left ($printer, 2) = '\\'
		$oldserver = Substr($printer, 3, 9)
		$printer = Substr ($printer, 1, InStr($printer, ',') - 1 )
;		Handle only printers on the old printservers		
		If ($oldserver = "NOPRTHQ02" OR $oldserver = "NOPRTHC02" OR $oldserver = "NOPRTHC03")
			$rc = DelPrinterConnection($printer)
			$newprinter = Split($printer, $oldserver)
			$newprinter = Join($newprinter, $newserver)
;			A quirk in the use of the Split + Join funtions above may return a backslash too many
			If Substr($newprinter, 3, 1) = '\'
				$newprinter = Substr($newprinter, 2, LEN($newprinter)-1)
			EndIf
 			$rc = AddPrinterConnection($newprinter)
			If $rc > 0
				$newprinter = '\\' + $altserver + '\' + Substr($newprinter, InStrRev($newprinter, '\')+1, LEN($newprinter)-1)
				$rc = AddPrinterConnection($newprinter)
			EndIf
			If $printer = $defaultprinter 				                        $rc = SetDefaultPrinter($newprinter)
			EndIf
		EndIf
	EndIf
Next

Exit


Thanks for your help - I hope this may be of help to someone else at some point.
_________________________
Share and enjoy - Kjetil

Top
Page 1 of 1 1


Moderator:  Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart 
Hop to:
Shout Box

Who's Online
0 registered and 787 anonymous users online.
Newest Members
Audio, Hoschi, Comet, rrosell, PatrickPinto
17880 Registered Users

Generated in 0.061 seconds in which 0.03 seconds were spent on a total of 13 queries. Zlib compression enabled.

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