A script to migrate user mapped network printers

A customer asked me today to write a script to migrate the user mappings to printers from one server to another.
Normally, this would be no cause for any problems and could be solved with a simple script (they didn’t want to use GPO/GPP to accomplish this).
However, they already did the migration of the printers to the new server themselves… and also changed all the printer names to the new naming convention!
This complicated things a little… normally you could simply edit the registry settings and change the server names. But since also the printer names were changed, they needed to be re-mapped also.
And just to keep things interesting, the “old” print server was Windows Server 2003 (x86) and the new one was Windows Server 2008 (x64).
And the last little bit of history was that the migration wasn’t only a migration, but also a consolidation. They used to have several print servers, and consolidated them to one.

Alright, so here are the demands which the script needs to comply with:

  • The printer server needs to be changed in the user mappings.
  • The old printer mapping must correspond with the new printer mapping (a.k.a. the prints need to come out of the correct printer.
  • Users only need to get the printers they already had in the old environment.
  • The default printer needs to be remembered and set correctly automatically.
  • Printer drivers need to be installed on the local machine from the printer server when none are present.

After spending my day in Notepad (yes, I know… but I still do my best scripting in a simple editor), I found that the default printer always kept returning to the “Microsoft Office Document Image Writer”, “Microsoft XPS Document Writer” or the “Jaws PDF ”. Both are local printers and the printers I change are network printers. In the end, I just deleted the local printers, run the migration script and re-create the local printers.

Script.bat
cscript %WINDIR%\System32\prnmngr.vbs -d -p “Microsoft Office Document Image Writer”
cscript %WINDIR%\System32\prnmngr.vbs -d -p “Microsoft XPS Document Writer”
cscript printermigrator.vbs
cscript %windir%\system32\prnmngr.vbs -a -p “Microsoft Office Document Image Writer” -m “Microsoft Office Document Image Writer Driver” -r “Microsoft Document Imaging Writer Port:”
cscript %windir%\system32\prnmngr.vbs -a -p “Microsoft XPS Document Writer” -m “Microsoft XPS Document Writer” -r “XPSPort:”

Printermigrator.vbs
‘Here comes a list with all printers identified by their old and new name.
‘The first item is the old name and the second item is the new name.
Dim OldPrinterName(200)
Dim NewPrinterName(200)
OldPrinterName(0) = “\\prtsrv1\prnt001”
NewPrinterName(0) = “\\printserver3\hq-printer-01”
OldPrinterName(1) = “\\printsrv01\bigprinter1”
NewPrinterName(1) = “\\printserver3\hq-printer-02”
OldPrinterName(2) = “\\prntsrvr\printer3”
NewPrinterName(2) = “\\printserver3\hq-printer-03”
OldPrinterName(3) = “\\prtsrv2\hplaserjet4”
NewPrinterName(3) = “\\printserver3\hq-printer-04”

‘Running
Set WshNetwork = WScript.CreateObject(“WScript.Network”)
Set Printers = WshNetwork.EnumPrinterConnections
dim printerIndex
printerIndex = 0

‘Walk through the printers
For each printer in printers

‘Determine the default printer
Dim objShell
Dim sPath
Dim sPrinter
Dim sPort
Dim sDriver
Dim ar_PrnInfo
Dim defaultPrinterName
Set objShell = CreateObject(“WScript.Shell”)
sPath = “HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device”
ar_PrnInfo = Split(objShell.RegRead(sPath), “,”)
If IsArray(ar_PrnInfo) Then
sPrinter = ar_PrnInfo(0)
sPort = ar_PrnInfo(2)
sDriver = ar_PrnInfo(1)
End If
defaultPrinterName = UCase(sPrinter)

‘Walk through the list of printers that need to be changed
For each ReplacePrinter in OldPrinterName
if UCase(printer) = UCase(ReplacePrinter) then
if Len(ReplacePrinter) then
WshNetwork.RemovePrinterConnection ReplacePrinter
WshNetwork.AddWindowsPrinterConnection NewPrinterName(printerIndex)
‘WScript.echo “WshNetwork.RemovePrinterConnection”  & ReplacePrinter
‘WScript.echo “WshNetwork.AddWindowsPrinterConnection”  & NewPrinterName(printerIndex)
end if
printerIndex = printerIndex + 1
end if
Next
‘The following sleep is to avoid timeouts with drivers that take a lot of time to install
WScript.Sleep 1000
objPrinter.SetDefaultPrinter(defaultPrinterName)
next

‘Set the default printer
Set WshNetwork = WScript.CreateObject(“WScript.Network”)
Set Printers2 = WshNetwork.EnumPrinterConnections
Dim printerNameWithoutServer
Dim tempArray
Dim printerNameWithoutServerNew
Dim tempArrayNew

‘Walk through all the printers
For each printer in printers2
If InStr(defaultPrinterName,”\”) <> 0  Then
tempArray = Split(defaultPrinterName, “\”)
printerNameWithoutServer = tempArray(UBound(tempArray))
Else
printerNameWithoutServer = “”
End If
if InStr(printer,”\”) <> 0 then
tempArrayNew = Split(printer,”\”)
printerNameWithoutServerNew = tempArrayNew(UBound(tempArrayNew) )
else
printerNameWithoutServerNew = “”
end if
if (printerNameWithoutServerNew <> “”) and (UCase(printerNameWithoutServer) = UCase(printerNameWithoutServerNew))Then
WshNetwork.SetDefaultPrinter(printer)
MsgBox “The network printers have been moved to a new server and printer ” + (printerNameWithoutServer)+ ” is still your default printer”
end if
Next

3 comments

  1. Nick Cooper says:

    Howdy, and thanks for the awewsome script! I am having an issue running it getting a runtime error though.

    Line: 60
    Char: 2
    Error: Object required: ‘objPrinter’
    Code: 800A01A8

    Line 60 is:

    objPrinter.SetDefaultPrinter(defaultPrinterName)

    Any ideas?

    Thanks again!

  2. Jeff Wouters says:

    Hi Nick,Glad you’ve found my post and that it can help you.I see that your line 60 my line 56 so I assume you’ve made some changes in the script? In that case it’s hard for me to guess what went wrong… but it sounds like you’re calling an illegal object.
    This could be because the object has not been defined yet or something like that… typo’s are always my pain.That part of my script I’ve based on the following script: http://blogs.technet.com/b/heyscriptingguy/archive/2006/07/19/how-can-i-set-the-default-printer-based-on-the-ip-address-of-the-computer.aspxAnd you may want to take a look at following post, which describes the 800A01A8 error: http://www.computerperformance.co.uk/Logon/code/code_800A01A8.htmJeff.

  3. Nick Cooper says:

    The only thing I’ve added is two additional printers at the top, hence the four extra lines. Should the line objPrinter.SetDefaultPrinter(defaultPrinterName) read instead:
    WshNetwork.SetDefaultPrinter(defaultPrinterName)
    I don’t get that error when I make this modification.

    On a separate note, would the script change at all if I was just migrating from one printer server to another instead of multiple as shown in the script?

Leave a Reply

Your email address will not be published. Required fields are marked *