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. http://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