Suggestions on how to migrate Per Machine Printers?

N

neobiont

I have several machines that are set up with per-machine printers.

We are now retiring one of the print servers and need to change the
clients that were printing to the old server to the new server.

In the past, I have used the chgprint utility to move printers set up
by users from one print server to another, but what do I do about per
machine printers.

Does CHGPRINT detect that a printer is set up as per machine and change
that printer also, or is its use limited to per user printers? If it
needs to change Per machine printers, I would assume it needs to be run
as an admin rather than a normal user. Could I run it with the machine
account in the machine's startup scripts?

So I have a number of machine that have a per machine network printer
setup, \\Server1\Printer45 and I want to change all those machines so
that the per machine printer is set up as \\server2\Printer45. This
change should be made the next time the machine boots.
 
B

Bruce Sanderson

I'm not familiar with chngprint per se - this appears to be a tool from the
NT 4 Resource Kit, but is not in the Windows 2003 Resource Kit.

Apart from writing a script that modifies the relevant registry entries
(e.g. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers), deleting
the existing "global" connection and adding a new one is probably what is
required.

Per machine (global) printer connections can be deleted and added using
rundll32 printui.dll,PrintUIEntry - see
http://members.shaw.ca/bsanders/NetPrinterAllUsers.htm.
 
N

neobiont

Here is the VB Script I ended up writing.
It reads the registry to find out what Per-Machine printers are
installed. It reads a text file containing a tab delimited list of
printers Old Printer Path on the left and New Printer Path on the
right. It then looks to see if there is a match between a currently
installed printer and an old printer path. If a match is found, it
deletes the old printer and adds the new one using the rundll.exe
thing. The translateprinters.txt file is assumed to be in the same
path as the VBS. I have added this file to the GPO startup scripts and
printers are migrating correctly. My script only changes per machine
printers. The CHGPrint.exe utility from microsoft only changes
per-user printers. I placed the chgprint.exe script in the users logon
script. So the first tool runs at startup for the machine, and the
second tool runs at logon. Both of them use the same list of printers
so you only have to maintain one list.

I'm not expert in VBScripting, so if someone wants to fix the problems
in this script, by all means have at it.
I don't know how to do open ended arrays so I had to hard code in doing
up to 30 printers per machine and 1000 printers per change list. If a
machine has more than 30 printers or you are migrating more than 1000
printers, this script would need to be modified.


Dim LocalPrinters(30,4)
Dim PrinterChange(1000,2)
Const HKEY_LOCAL_MACHINE = &H80000002


'Read in all the per-machine printers installed on this computer
strComputer = "."
Set objRegistry=GetObject("winmgmts:\\" & _
strComputer & "\root\default:StdRegProv")
strKeyPath = "SYSTEM\CurrentControlSet\Control\Print\Connections"
objRegistry.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubkeys
numLocalPrinters = 0
For Each objSubkey In arrSubkeys
strValueName = "Server"
strSubPath = strKeyPath & "\" & objSubkey
objRegistry.GetExpandedStringValue
HKEY_LOCAL_MACHINE,strSubPath,strValueName,strValue
position = InStrRev(objSubkey,",")
strServer = Mid(objSubkey,3,position-3)
strPrinter = Right(objSubkey,Len(objSubkey)-position)
LocalPrinters(count,0)=strServer
LocalPrinters(count,1)=strPrinter
LocalPrinters(count,2)=objSubkey
LocalPrinters(count,3)=strValue
count = count + 1
Next
numLocalPrinters=count
'wscript.echo "Found " & numLocalPrinters & " local printers."



'Read in the list of printers to move from TranslatePrinter.txt
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("Translateprinter.txt", 1)
count = 0
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
values = Split(strLine,CHR(09))
'wscript.Echo values(0)
'wscript.Echo values(1)
PrinterChange(count,0) = values(0)
PrinterChange(count,1) = values(1)
count=count+1
Loop

objFile.Close
numTranslatePrinters = count
'wscript.Echo "Translate Printers contains " & count & " Lines."


'For each printer installed - See if it is listed int TranslatePrinter
and if so move it.
For i = 0 to numLocalPrinters-1
'WSCRIPT.Echo "Looking for " & LocalPrinters(i,1)
For j = 0 to numTranslatePrinters - 1
strTranslateFrom = PrinterChange(j,0)
position = InStrRev(strTranslateFrom,"\")
strServer = Mid(strTranslateFrom,3,position-3)
strPrinter =
Right(strTranslateFrom,Len(strTranslateFrom)-position)
'wscript.echo "Comparing " & LCase(strPrinter) & " to " &
Lcase(LocalPrinters(i,1))
if LCase(strServer) = Lcase(LocalPrinters(i,0)) and
LCase(strPrinter) = LCase(LocalPrinters(i,1)) Then
'wscript.Echo "Found a printer to change."
'wscript.Echo "Changing " & PrinterChange(j,0) & " to " &
PrinterChange(j,1)
set oShell = CreateObject("WScript.Shell")
strCmd = "rundll32.exe PRINTUI.DLL, PrintUIEntry /gd /q /n" &
PrinterChange(j,0)
'wscript.Echo "Running " & strCmd
oShell.run strCmd
strCmd = "rundll32.exe PRINTUI.DLL, PrintUIEntry /ga /q /n" &
PrinterChange(j,1)
'wscript.Echo "Running " & strCmd
oShell.run strCmd
end if
next
next
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top