none
Migrating a users printer from one print server to another while retaining users preferences RRS feed

  • Question

  • Our existing file server is also the print server. We brought up another dedicated print server and exported from one and imported to the other. The goal is to bring down print services on the first server after everyone is using the new one. We dont want to visit each user and we want the existing user print preferences to be retained. The following script is run as a user logoff script and preserves users print preferences while changing the printer path references to the new server. Any comments, suggestions and improvements are welcome. The script is not intended to modify local administratively installed or GPO deployed printers.

    On Error Resume Next
    
    Const HKEY_CURRENT_USER = &H80000001
    Const REG_BINARY = 3
    strComputer = "."
    strConnectionsKeyPath = "Printers\Connections"
    strDevModes2KeyPath = "Printers\DevModes2"
    strSettingsKeyPath = "Printers\Settings"
    
    strFs1 = "ord-pdxv-fs1"
    strLFs1 = lcase(strFs1)
    strUFs1 = ucase(strFs1)
    strMFs1 = ucase(left(strFs1, 1))&right(strFs1, len(strFs1)-1)
    arrstrFs1=array(strLFs1, strUFs1, strMFs1)
    j=0
    dim arrBinFs1()
    ReDim arrBinFs1(ubound(arrstrFs1))
    strBinPs1 = "111,0,114,0,100,0,45,0,112,0,100,0,120,0,118,0,45,0,112,0,115,0,49,0,"
    strPs1 = "ord-pdxv-ps1"
    
    
    ServerValue = "Server"
    ProviderValue = "Provider"
    LocalConnectionValue = "LocalConnection"
    GuidPrinterValue = "GuidPrinter"
    DevModeValue = "DevMode"
    
    for each str in arrstrFs1
    strBinFs1 = ""
    for i = 1 to len(str)
    strBinFs1 = strBinFs1 & asc(mid(str, i, 1))&",0,"
    next
    arrBinFs1(j) = strBinFs1
    j = j+1
    next
    
    Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
    
    objReg.GetStringValue HKEY_CURRENT_USER,"Software\Microsoft\Windows NT\CurrentVersion\Windows","Device", strDefPrinterKey
    
    If Instr(lcase(strDefPrinterKey), strFs1) <> 0 Then
    	objReg.SetStringValue HKEY_CURRENT_USER,"Software\Microsoft\Windows NT\CurrentVersion\Windows","Device",replace(lcase(strDefPrinterKey),strFs1, strPs1)
    End If
    
    objReg.EnumKey HKEY_CURRENT_USER, strConnectionsKeyPath, arrSubKeys
    
    For Each Printer in arrSubKeys
    	If Instr(lcase(Printer), strFs1) <> 0 Then
    
    	PrinterKey = strConnectionsKeyPath&"\"&Printer
    	NewPrinterKey = strConnectionsKeyPath&"\"&replace(lcase(Printer), strFs1, strPs1)
    
    		objReg.GetStringValue HKEY_CURRENT_USER,PrinterKey,ServerValue,strServerValue
    		objReg.GetStringValue HKEY_CURRENT_USER,PrinterKey,ProviderValue,strProviderValue
    		objReg.GetDWORDValue HKEY_CURRENT_USER,PrinterKey,LocalConnectionValue,dwLocalConnectionValue
    		objReg.GetStringValue HKEY_CURRENT_USER,PrinterKey,GuidPrinterValue,strGuidPrinterValue
    		objReg.GetBinaryValue HKEY_CURRENT_USER,PrinterKey,DevModeValue,arrDevModeValue
    
    		objReg.CreateKey HKEY_CURRENT_USER,NewPrinterKey
    
    		objReg.SetStringValue HKEY_CURRENT_USER,NewPrinterKey,ServerValue,replace(lcase(strServerValue), strFs1, strPs1)
    		objReg.SetStringValue HKEY_CURRENT_USER,NewPrinterKey,ProviderValue,strProviderValue
    		objReg.SetDWORDValue HKEY_CURRENT_USER,NewPrinterKey,LocalConnectionValue,dwLocalConnectionValue
    		objReg.SetStringValue HKEY_CURRENT_USER,NewPrinterKey,GuidPrinterValue,strGuidPrinterValue
    
    		for each strBinFs1 in arrBinFs1
    			strDevModeValue = Join(arrDevModeValue,",")
    			arrDevModeValue = split(replace(strDevModeValue,strBinFs1,strBinPs1),",")
    			objReg.SetBinaryValue HKEY_CURRENT_USER,NewPrinterKey,DevModeValue,arrDevModeValue
    		next
    		
    		objReg.DeleteKey HKEY_CURRENT_USER,PrinterKey
    
    	End If
    Next
    
    objReg.EnumValues HKEY_CURRENT_USER,strDevModes2KeyPath,arrEntryNames,arrValueTypes
    
    For i=0 To UBound(arrEntryNames)
    	Select Case arrValueTypes(i)
    		Case REG_BINARY
    			objReg.GetBinaryValue HKEY_CURRENT_USER, strDevModes2KeyPath, arrEntryNames(i),arrDevMode2Value
    			for each strBinFs1 in arrBinFs1
    			strDevMode2Value = Join(arrDevMode2Value,",")
    					arrDevMode2Value = split(replace(strDevMode2Value,strBinFs1,strBinPs1),",")
    					If instr(lcase(arrEntryNames(i)), strFs1) <> 0 Then
    						objReg.SetBinaryValue HKEY_CURRENT_USER,strDevModes2KeyPath,lcase(replace(arrEntryNames(i),strFs1,strPs1)),arrDevMode2Value
    						objReg.DeleteValue HKEY_CURRENT_USER,strDevModes2KeyPath,arrEntryNames(i)
    					Else
    						objReg.SetBinaryValue HKEY_CURRENT_USER,strDevModes2KeyPath,arrEntryNames(i),arrDevMode2Value
    					End If
    			next
    	End Select
    Next
    
    
    
    objReg.EnumValues HKEY_CURRENT_USER,strSettingsKeyPath,arrEntryNames,arrValueTypes
    
    For i=0 To UBound(arrEntryNames)
    	Select Case arrValueTypes(i)
    		Case REG_BINARY
    			objReg.GetBinaryValue HKEY_CURRENT_USER, strSettingsKeyPath, arrEntryNames(i),arrSettingsValue
    			for each strBinFs1 in arrBinFs1
    			strSettingsValue = Join(arrSettingsValue,",")
    					arrSettingsValue = split(replace(strSettingsValue,strBinFs1,strBinPs1),",")
    					If instr(lcase(arrEntryNames(i)), strFs1) <> 0 Then
    						objReg.SetBinaryValue HKEY_CURRENT_USER,strSettingsKeyPath,lcase(replace(arrEntryNames(i),strFs1,strPs1)),arrSettingsValue
    						objReg.DeleteValue HKEY_CURRENT_USER,strSettingsKeyPath,arrEntryNames(i)
    					Else
    						objReg.SetBinaryValue HKEY_CURRENT_USER,strDevModes2KeyPath,arrEntryNames(i),arrSettingsValue
    					End If
    			Next
    	End Select
    Next
    


    • Edited by havealoha Saturday, July 26, 2014 12:31 AM Clarify intent of script and post.
    Friday, July 25, 2014 3:28 PM

Answers

  • What we are doing is working, we are seeking comments, suggestions and improvements.

    In that case, go ahead and use what you have if it works.

    As noted, there are other ways to accomplish what you want without writing code, so it's sort of pointless for us to offer code suggestions for code you don't need.


    -- Bill Stewart [Bill_Stewart]

    Friday, July 25, 2014 4:12 PM
    Moderator

All replies

  • User print preferences are not stored on the server they are stored in the users hive.  If you change the pronter location the users preferences will be lost.  Yuu must export each user at the user prompt using utilities.

    The VBS utilities are designed to do this because they know how to export from one printer and load into the new printer from a file.

    What you are doing will not work.

    Printers that are deployed via a Print Server are not registered in a users registry.  The only thing registered is the net attachment.

    Each program in Windows retains a set of preferences by printer.  Older programs use the defaults.

    One way to do this is to use the USMT and just dump the printers then create a script that can edit the XML in the USMT config file.  You should only have to change the server name if you gave all of the printers an identical share name.


    ¯\_(ツ)_/¯

    Friday, July 25, 2014 4:01 PM
  • If you really want to try and debug your script then start by removing this line: "On Error Resume Next"

    After removing it fix all of the errors until you aer sure the script runs correctly.


    ¯\_(ツ)_/¯

    Friday, July 25, 2014 4:02 PM
  • What we are doing is working, we are seeking comments, suggestions and improvements.

    In that case, go ahead and use what you have if it works.

    As noted, there are other ways to accomplish what you want without writing code, so it's sort of pointless for us to offer code suggestions for code you don't need.


    -- Bill Stewart [Bill_Stewart]

    Friday, July 25, 2014 4:12 PM
    Moderator
  • If you really want to try and debug your script then start by removing this line: "On Error Resume Next"

    After removing it fix all of the errors until you aer sure the script runs correctly.


    ¯\_(ツ)_/¯

    Again - remove the On Error Resume Next and fix the errors as they come up.  With that in place there is no way to know what is failing.

    This is what happens when you try to reinvent the wheel and when you do not have sufficient experience scripting difficult tasks.

    I would just use REG to export the settings.  Edit the REG file with a script and reapply it.  The will leverage the Windows system to update and manage the registry and can be easily done in a logon script.

    If you insist on your script then you will have to find the hidden errors.


    ¯\_(ツ)_/¯

    Friday, July 25, 2014 4:37 PM
  • Note also that you cannot change printers deployed via a GPO.  The GPO will just rewrite them.  You can edit the GPO and have it rename the prionter for you.

    A locally installed printer cannot be managed in a user script period.

    You need to rethink what you are trying to do.  You seem to be backed into a corner because history has likely set the systems up incorrectly.

    User settings can best be moved via USMT and an edit.

    Again - remove On Erro and test until it works then realize that half of  your problems cannot be fixed in a logoff script.


    ¯\_(ツ)_/¯

    Friday, July 25, 2014 4:40 PM
  • Well, its a little late and was created after my initial search but here is a script from Microsoft:

    http://blogs.technet.com/b/deploymentguys/archive/2013/02/12/printer-remapping-in-windows-7-deployments.aspx

    I just tried this and it did not preserve users preferences but it did create a new print queue for the new server.

    Well that is not what you are trying to do.  It moves only mapped printers from a different registry key.

    The script is more than a year old and is part of the USMT toolkit now.  I recommend getting the 2012 MDT and get the latest migration tools as the newer version of this script is likely included.


    ¯\_(ツ)_/¯

    Friday, July 25, 2014 5:48 PM