Migrating Printers On The End User Machine via VBScript
Greetings from Anchorage! In a former life I use to be a systems engineer just like you. One of my responsiblities was our print environment. One of the final things I had to do before I left was to migrate all the end users printers to the new printer environment. A disclaimer, this architecture design and script worked for that enviornment, your mileage may vary. Please test, test and test again.
Background
At my last job we didn't have a hard and fast rule of what printer types people or departments could purchase so we would have printer drivers from all walks of life. And those walks of life loved to crash the print spooler. One rouge driver could take the whole thing down (this was on Server 2003 before print driver isolation). The new printer environment was broken out into three different categories for printer drivers.
1.) Print drivers that shipped with the OS (Server 2008 and Server 2008 R2), these are called Inbox drivers. These are the most stable. Also to note we needed to install both 32-bit/64-bit drivers on the print servers. https://blogs.technet.com/b/askperf/archive/2010/06/04/installing-cross-architectural-print-drivers-32bit-on-64bit-and-vice-versa-from-the-server-locally.aspx
2.) Print drivers that were universal from a manufacture. Think of this as the HP Universal Print Driver, Xerox, Lexmark, etc.
3.) if you didn't fit into the first two, you went to the third print server. Here be dragons.
Printers would follow this order as well, we would first try to see if that printer model had an inbox driver for it, if not then did a universal print driver work and finally it would use its own driver on the last print server.
The Script
Alright don't get too excited it was written sort of hastily and print queue names were hardcoded as I had a very specific number of queues. Feel free to modify this for your own use though.
Function PrinterMigrated()
'Mark Morowcznski
'Migrates the current printers for the local user
On error resume next
'needed for first run if no regkey exists, will throw an error, need script to continue to run
Dim ojbFSO, shell, objNetwork, serialnumber, scriptrun, printername
Set ObjFSO = CreateObject("Scripting.FileSystemObject")
set shell =CreateObject("wscript.shell")
Set objNetwork = CreateObject("WScript.Network")
set shell =CreateObject("wscript.shell")
'Getting SID for current logged in user as printers are user specific
Set oUserAccount = GetObject("winmgmts://./root/cimv2") _
.Get("Win32_UserAccount.Domain='" & objNetwork.UserDomain & "'" _
& ",Name='" & objnetwork.UserName & "'")
sUserSID = oUserAccount.SID
'Debug
'msgbox sUserSID
'We write to a registry key for this script to run once
reglocation = "HKEY_USERS\" & sUserSID & "\Software\WhateverKey\PrintersMigrated"
'Debug
'Msgbox reglocation
'Current Version
serialnumber = "20101017"
'Registry Key Location
scriptrun = shell.regread(reglocation)
'Debug
'Msgbox ScriptRun
if scriptrun = serialnumber Then
'Current Version already run on machine, nothing left to do in this function
'Debug
'Msgbox "Script already ran, exiting function"
Exit Function
End if
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer")
strPrintServerOld = "\\print" 'old print server
strPrintServerPSPRD01 = "\\PSPRD01" 'inbox
strPrintServerPSPRD02 = "\\PSPRD02" 'universal
strPrintServerPSPRD03 = "\\PSPRD03" 'misc
strIsDefault = "False"
strUserName = objNetwork.UserName
strDirectory = "C:\Cabs"
strFile= "\Print_" & strUserName & ".txt"
strTotal = strDirectory & strFile
'output for logging
Set objFile =ObjFSO.CreateTextFile(strTotal)
'Set objTextFile = objFSO.OpenTextFile(strDirectory & strFile)
Dim psprd02Array (2) 'change this value for your queues
psprd02Array (0) = "printqueue1"
psprd02Array (1) = "printqueue2"
Dim psprd03Array (3)
psprd03Array (0) = "printqueue4"
psprd03Array (1) = "printqueue5"
psprd03Array (2) = "printqueue6"
For Each objPrinter in colInstalledPrinters
'Wscript.Echo "Name: " & objPrinter.Name
'Wscript.Echo "Location: " & objPrinter.Location
'Wscript.Echo "Default: " & objPrinter.Default
'Wscript.Echo "Server: " & objPrinter.Servername
'Wscript.Echo "Sharename: " & objPrinter.Sharename
If objPrinter.ServerName = strPrintServerOld Then
strPrintMoved = "False" 'used to jump out of current print queue if already moved.
strPrintShare = CStr(objPrinter.ShareName)
objFile.WriteLine("Current Printer is: " & strPrintShare)
if objPrinter.Default = True Then 'Checking for Default printer
strIsDefault ="True"
objFile.WriteLine(strPrintShare & " is the default Printer.")
'Msgbox "Default Printer: " & strPrintShare
End If
for x=0 to 2
if objPrinter.Sharename = psprd02Array(x) Then
objNetwork.AddWindowsPrinterConnection strPrintServerPsPRD02 & "\" & strPrintShare
strPrintMoved = "True"
objFile.WriteLine(strPrintShare & " added queue from PSPRD02")
if strIsDefault = "True" Then
objNetwork.SetDefaultPrinter(strPrintServerPSPRD02 & "\" & strPrintShare)
'Msgbox "PSPRD02 Default"
strisDefault = "False"
End if
objNetwork.RemovePrinterConnection strPrintServerOld & "\" & StrPrintShare
objFile.WriteLine(strPrintShare & " removed queue from PS01")
Exit for
End if
next
if strPrintMoved = "False" Then
for y=0 to 3
if objPrinter.Sharename = psprd03Array(y) Then
objNetwork.AddWindowsPrinterConnection strPrintServerPsPRD03 & "\" & strPrintShare
strPrintMoved = "True"
objFile.WriteLine(strPrintShare & " added queue from PSPRD03")
if strIsDefault = "True" Then
objNetwork.SetDefaultPrinter(strPrintServerPSPRD03 & "\" & strPrintShare)
'Msgbox "PSPRD03 Default"
strisDefault = "False"
End if
objNetwork.RemovePrinterConnection strPrintServerOld & "\" & StrPrintShare
objFile.WriteLine(strPrintShare & " removed queue from PS01")
Exit for
End if
next
End If
if strPrintMoved = "False" Then
objNetwork.AddWindowsPrinterConnection strPrintServerPsPRD01 & "\" & strPrintShare
objFile.WriteLine(strPrintShare & " added queue from PSPRD01")
'MsgBox strIsdefault
if strIsDefault = "True" Then
objNetwork.SetDefaultPrinter(strPrintServerPSPRD01 & "\" & strPrintShare)
'Msgbox "PSPRD01 Default"
strisDefault = "False"
End if
objNetwork.RemovePrinterConnection strPrintServerOld & "\" & StrPrintShare
objFile.WriteLine(strPrintShare & " removed queue from PS01")
End If
'WScript.Sleep(5000)
End If
Next
objTextFile.Close
shell.RegWrite reglocation,serialnumber, "REG_SZ"
End Function
Special thanks to Mike Barbush for helping with the migration and testing of this script. Alright that's all for now folks, happy scripting
Mark "Brian Zoucha Print Cluster Master in training" Morowczynski