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