Recently we migrated our Printserver from Windows 2003 R2 (yes, it was time…) to Windows 2012R2 and needed a smart and easy way to migrate existing printer mappings from the old to the new server. While migrating the printerserver itself was a very easy and straighforward task using Printbrm (took only about 10 mins!), the question how to migrate the mappings remained open. Doing some research on the net showed that it seemed to be best practice to do this using a logon script. A little bit of more searching brought up a very helpfull and handy PowerShell script which should to the trick. Since all our clients are at least Windows 7, PowerShell was available on clients and we were able to go on with this.
The script was good, but needed some minor tweaks to work well in our environment. For exmaple the script lacked to set the default printer. If you remove the old printer and add a new one you have to set the default printer again, this has been fixed in the version below.
It was also not possible to have 2 different names for the printserver so e.g. some users may have user FQDN (prinserver.domain.com) and some only the simple Name (printserver). To catch all this cases you can now specify more than one name for a print server and all printers will be replaced.
To run the script, simple copy the source code to a file on your PC and change the following lines to your need.
1 2 |
$newPrintServer = "NewPrintServer", $oldPrintServers = @("OldPrintServer1", "OldPrintServer2") |
If you want a quite handy logfile where you can see how your migration is making progress. Change the following line to a path where all users can write.
1 |
$PrinterLog = "\\LogSVR\PrintMigration$\PrintMigration.csv" ) |
Remove <# and #> from the following lines and run the Script once, to create the logfile with a header line. After the file has been created, add <# and #> again to avoid overwriting the file each time the script is running.
1 |
<# Uncomment and run only once #Header for CSV log file: "COMPUTERNAME,USERNAME,PRINTERNAME,RETURNCODE-ERRORMESSAGE,DATETIME,STATUS" | Out-File -FilePath $PrinterLog -Encoding ASCII #> |
Here you can find the complete source code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
<# .SYNOPSIS Logon Script to migrate printer mapping .DESCRIPTION Logon Script to migrate printer mappings .NOTES Author: Boe Prox (https://learn-powershell.net/2012/11/15/use-powershell-logon-script-to-update-printer-mappings/) Editor: Felix (https://www.uc-world.com/?p=223) Create: 09 NOV 2012 Modified: 17 JUL 2017 Version 1.0 - Initial Script Creation 1.1 Added Header Text for CSV file 1.2 Added default printer and multiple source printservers (03 JUL 2017) #> Param ( $newPrintServer = "NewPrintServer", $oldPrintServers = @("OldPrintServer1", "OldPrintServer2"), $PrinterLog = "\\LogSVR\PrintMigration$\PrintMigration.csv" ) <# Uncomment and run only once #Header for CSV log file: "COMPUTERNAME,USERNAME,PRINTERNAME,RETURNCODE-ERRORMESSAGE,DATETIME,STATUS" | Out-File -FilePath $PrinterLog -Encoding ASCII #> #Pull the current default printer's name $defaultPrinter = gwmi win32_printer | where {$_.Default -eq $true} #Enable Verbose output (will be reverted at the end of script) $oldverbose = $VerbosePreference $VerbosePreference = "continue" #Change the printer from old to new function ChangePrinter { try{ ForEach ($printer in $printers) { Write-Verbose ("{0}: Replacing with new print server name: {1}" -f $Printer.Name,$newPrintServer) $newPrinter = $printer.Name -replace $oldPrintServer,$newPrintServer $returnValue = ([wmiclass]"Win32_Printer").AddPrinterConnection($newPrinter).ReturnValue If ($returnValue -eq 0) { "{0},{1},{2},{3},{4},{5}" -f $Env:COMPUTERNAME, $env:USERNAME, $newPrinter, $returnValue, (Get-Date), "Added Printer" | Out-File -FilePath $PrinterLog -Append -Encoding ASCII Write-Verbose ("{0}: Removing" -f $printer.name) $printer.Delete() "{0},{1},{2},{3},{4},{5}" -f $Env:COMPUTERNAME, $env:USERNAME, $printer.Name, $returnValue, (Get-Date), "Removed Printer" | Out-File -FilePath $PrinterLog -Append -Encoding ASCII } Else { Write-Verbose ("{0} returned error code: {1}" -f $newPrinter,$returnValue) -Verbose "{0},{1},{2},{3},{4},{5}" -f $Env:COMPUTERNAME, $env:USERNAME, $newPrinter, $returnValue, (Get-Date), "Error Adding Printer" | Out-File -FilePath $PrinterLog -Append -Encoding ASCII } } # Gets new list of printers that are pointed to newserver $newPrinterList = @(Get-WmiObject -Class Win32_Printer -Filter "SystemName='\\\\$newPrintServer'" -ErrorAction Stop) # iterates through each new printer and compares the ShareName to the old ShareName that was the user’s default printer and sets it ForEach ($printer in $newPrinterList) { If ($printer.ShareName -eq $defaultPrinter.ShareName) { $tmp = $printer.SetDefaultPrinter() Write-Verbose ("{0} Set as default printer" -f $printer.Name,$returnValue) -Verbose "{0},{1},{2},{3},{4},{5}" -f $Env:COMPUTERNAME, $env:USERNAME, $printer.Name, $returnValue, (Get-Date), "Set defaultPrinter" | Out-File -FilePath $PrinterLog -Append -Encoding ASCII } } }catch{ "{0},{1},{2},{3},{4},{5}" -f $Env:COMPUTERNAME, $env:USERNAME, "WMIERROR", $_.Exception.Message, (Get-Date), "Error Querying Printers" | Out-File -FilePath $PrinterLog -Append -Encoding ASCII } } #Main Code-Block Try { #ForEach Server in $oldPrintServers do ForEach ($oldPrintServer in $oldPrintServers) { Write-Verbose ("{0}: Checking for printers mapped to old print server {1}" -f $Env:USERNAME, $oldPrintServer) $printers = @(Get-WmiObject -Class Win32_Printer -Filter "SystemName='\\\\$oldPrintServer'" -ErrorAction Stop) #If we get back any mapped printer call ChangePrinter and do it If ($printers.count -gt 0) { ChangePrinter } } } Catch { "{0},{1},{2},{3},{4},{5}" -f $Env:COMPUTERNAME, $env:USERNAME, "WMIERROR", $_.Exception.Message, (Get-Date), "Error Querying Printers" | Out-File -FilePath $PrinterLog -Append -Encoding ASCII } $VerbosePreference = $oldverbose |