This is an old revision of the document!
This subject has changed a lot with the advent of version 4 (V4) printer drivers in Windows 8 and 2012.
V4 Printing Overview: http://www.computerperformance.co.uk/win8/windows8-v4-printer-driver.htm
Windows 8 Printing: http://blogs.msdn.com/b/b8/archive/2012/07/25/simplifying-printing-in-windows-8.aspx
We have not found publishing printers via GPO to be trouble free.
When installing drivers for multiple architectures on a Windows Server, verify that the additional drivers are:
HowTo: http://members.shaw.ca/bsanders/NetPrinterAllUsers.htm
User Guide: http://download.microsoft.com/download/8/2/c/82cffcfa-56f6-4fc3-bfa5-80cd84793871/PrintUIUsersGuide.doc
Reference: https://technet.microsoft.com/en-us/library/ee624057.aspx
Most network printer connections are only visible (usable) by the user that made the connection. Per-machine connections must be made by an administrator, but are available to all users of the machine.
Show per-machine (global) printer connections:
Rundll32.exe printui.dll,PrintUIEntry /ge
Delete per-machine (global) printer connection:
Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\hp6700-lab"
Add per-machine (global) printer connection:
Rundll32.exe printui.dll,PrintUIEntry /ga /q /n"\\jw-dc1\hp6700-lab"
Add per-machine (global) printer connection to a remote (workstation) computer:
Rundll32.exe printui.dll,PrintUIEntry /ga /q /c"\\remotepcname" /n"\\jw-dc1\hp6700-lab"
http://windowsitpro.com/content/content/77369/adprintx.zip
This is a simple commandline tool to add, delete and manipulate printers and is useful in scripts.
http://www.dabcc.com/downloadfile.aspx?id=214
This is a small tool that pops up a window so a user can select their desitred default printer from a list.
https://technet.microsoft.com/en-us/sysinternals/bb897553.aspx
This tool is needed to clear out some protected registry keys.
Important: http://digitalzombies.com/2014/07/03/print_issues_rds_2012/
Important: http://community.spiceworks.com/topic/post/3939859
Reset Printing (Lite and Full): http://blogs.technet.com/b/askperf/archive/2012/02/24/microsoft-fixit-for-printing.aspx
Print Spooler Diagnostic: https://support.microsoft.com/en-us/kb/2768706/en-us
net stop spooler del /q /f "%systemroot%\system32\spool\printers\*.*" net start spooler
Make a backup of your registry before doing anything!
You will need to launch regedit
as the System
user with PsExec
to be able to clean out these keys.
F:\Support\PsTools\PsExec -i -d -s c:\windows\regedit.exe
Delete all numbered subkeys:
HKLM\SYSTEM\CurrentControlSet\Control\Class\{1ed2bbf9-11f0-4084-b21f-ad83a8e6dcdc}
Delete all ##?#SWD#PRINTENUM#
keys:
HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{0ecef634-6ef0-472a-8085-5ad023ecbccd}
Delete all subkeys containing SWD\PRINTENUM
values under GUID\BaseContainers\GUID
:
HKLM\SYSTEM\CurrentControlSet\Control\DeviceContainers\
Delete all subkeys:
HKLM\SYSTEM\CurrentControlSet\Enum\SWD\PRINTENUM\
Then reboot the machine and check for 'phantom' printers in Add/Remove Printers
.
Also check in Device Manager after enabling Show hidden devices
.
Possible cause:
HKEY_CURRENT_USER\Printers\Connections
registry key does not match the case of the printer name under HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows:Device
registry key.
You might use this script if you use per-user (not global) printers.
@echo off Echo Resetting printers... REM Delete all network printers F:\Support\Printer\adprintx.exe /f REM Wait a few seconds timeout /t 5 /nobreak > NUL REM Delete all network printers again to be sure F:\Support\Printer\adprintx.exe /f REM We don't install printers as regular users when using global printers so REM comment these lines out if using global printers Rundll32.exe printui.dll,PrintUIEntry /in /q /n"\\jw-dc1\hp8600-ofc" Rundll32.exe printui.dll,PrintUIEntry /in /q /n"\\jw-dc1\hp6700-lab" Rundll32.exe printui.dll,PrintUIEntry /in /q /n"\\jw-dc1\hp8600-mav" Rundll32.exe printui.dll,PrintUIEntry /in /q /n"\\jw-dc1\mx350" REM Set a default printer, then let user choose a different one if desired Rundll32.exe printui.dll,PrintUIEntry /y /n"\\jw-dc1\hp8600-ofc" REM Let the user choose their default printer rem start "Select Your Default Printer" "F:\Support\Printer\Set Default Printer.exe" Echo. Echo The default printer has been reset to 'hp8600-ofc'. Echo. Echo Please reset your default printer if you want a different one. rem pause
@echo off echo Clearing network printers... Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp6700-lab" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-lab" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-mav" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-ofc" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\mx350" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\zm400-label" timeout /t 5 /nobreak Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp6700-lab" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-lab" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-mav" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-ofc" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\mx350" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\zm400-label" echo deleting some registry entries... echo. reg delete "HKEY_CURRENT_USER\Printers\DevModePerUser" /va /f reg delete "HKEY_CURRENT_USER\Printers\DevModes2" /va /f reg delete "HKEY_CURRENT_USER\Printers\Connections" /va /f reg delete "HKEY_CURRENT_USER\Printers\Defaults" /va /f reg delete "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices" /va /f reg delete "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts" /va /f echo. echo. echo You must now log off (sign out - not disconnect) and log back in. echo. echo You will need to reset your default printer after logging back in. echo. echo Hit any key to log out or press ctrl-c to cancel. pause start c:\windows\system32\logoff.exe
@echo off echo This script must be run as administrator and will clear all network printers. echo. echo This script must be edited for each site. echo Deleting network printers... Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp6700-lab" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-lab" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-mav" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-ofc" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\mx350" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\zm400-label" echo Deleting global network printers... Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\hp6700-lab" Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\hp8600-lab" Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\hp8600-mav" Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\hp8600-ofc" Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\mx350" Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\zm400-label" timeout /t 5 /nobreak echo Doing it again in case the printers reappear... Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp6700-lab" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-lab" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-mav" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\hp8600-ofc" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\mx350" Rundll32.exe printui.dll,PrintUIEntry /dn /q /n"\\jw-dc1\zm400-label" Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\hp6700-lab" Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\hp8600-lab" Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\hp8600-mav" Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\hp8600-ofc" Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\mx350" Rundll32.exe printui.dll,PrintUIEntry /gd /q /n"\\jw-dc1\zm400-label" echo Clearing out the registry... reg delete "HKEY_CURRENT_USER\Printers\DevModePerUser" /va /f reg delete "HKEY_CURRENT_USER\Printers\DevModes2" /va /f reg delete "HKEY_CURRENT_USER\Printers\Connections" /va /f reg delete "HKEY_CURRENT_USER\Printers\Defaults" /va /f reg delete "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts" /va /f reg delete "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices" /va /f reg delete "HKEY_USERS\.DEFAULT\Printers\DevModePerUser" /va /f reg delete "HKEY_USERS\.DEFAULT\Printers\DevModes2" /va /f reg delete "HKEY_USERS\S-1-5-18\Printers\DevModePerUser" /va /f reg delete "HKEY_USERS\S-1-5-18\Printers\DevModes2" /va /f reg delete "HKEY_USERS\S-1-5-19\Printers\DevModePerUser" /va /f reg delete "HKEY_USERS\S-1-5-20\Printers\DevModePerUser" /va /f reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Connections" /va /f reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\Client Side Rendering Print Provider" /f reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\V4 Connections" /f reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Print\Connections" /va /f reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Print\Providers\Client Side Rendering Print Provider" /f reg delete "HKEY_CURRENT_CONFIG\System\CurrentControlSet\Control\Print\Printers" /f reg delete "HKEY_CLASSES_ROOT\Local Settings\Printers\V4ConnectionCacheState" /va /f reg delete "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\RDPDR" /f echo Clearing out any old print jobs... net stop spooler del /q /f "%systemroot%\system32\spool\printers\*.*" del /q /f "%systemroot%\system32\spool\servers\*.*" net start spooler echo Hit any key to open Device Manager. echo. echo Then click "View -> Show hidden devices" and delete any leftover printers there. pause start /wait devmgmt.msc echo You should now reboot to automatically recreate some of the deleted registry keys. pause
Global printers are available to all users of a machine when they log in.
Global printers can only be added or deleted by an admin.
There is no GUI way to add or remove global printers.
REM Add global network printers for all users Rundll32.exe printui.dll,PrintUIEntry /ga /q /n"\\jw-dc1\hp8600-ofc" Rundll32.exe printui.dll,PrintUIEntry /ga /q /n"\\jw-dc1\hp6700-lab" Rundll32.exe printui.dll,PrintUIEntry /ga /q /n"\\jw-dc1\hp8600-mav" Rundll32.exe printui.dll,PrintUIEntry /ga /q /n"\\jw-dc1\mx350" REM Show global printers Rundll32.exe printui.dll,PrintUIEntry /ge
@Echo off Echo. REM This batch file could be used to add global network printers to a workstation PC from the domain controller REM Check that a computer name was given as an argument if [%1]==[/?] goto usage Echo Adding global printers to the specified computer (%1)... rundll32 printui.dll,PrintUIEntry /ga /q /c\\%1 /n"\\jw-dc1\hp8600-ofc" rundll32 printui.dll,PrintUIEntry /ga /q /c\\%1 /n"\\jw-dc1\hp6700-lab" rundll32 printui.dll,PrintUIEntry /ga /q /c\\%1 /n"\\jw-dc1\hp8600-mav" rundll32 printui.dll,PrintUIEntry /ga /q /c\\%1 /n"\\jw-dc1\mx350" Echo Stopping the print spooler on the specified computer (%1)... start /wait sc \\%1 stop spooler Echo Starting the print spooler on the specified computer (%1)... start /wait sc \\%1 start spooler Echo Done! goto end :usage Echo No computer name was given. Echo. Echo Specify the computer that you want the global printers to be added to. :end pause
'PrinterSetup.vbs ' 'Delete all network printers 'This will not delete local printers even if they are using TCP/IP ports On error resume next Set WshNetwork = WScript.CreateObject("WScript.Network") Set oPrinters = WshNetwork.EnumPrinterConnections For i = 0 to oPrinters.Count - 1 Step 2 WshNetwork.RemovePrinterConnection oPrinters.Item(i+1) Next 'Sleep period is in milliseconds WScript.Sleep(3000) 'Loop through and delete the network printers again For i = 0 to oPrinters.Count - 1 Step 2 WshNetwork.RemovePrinterConnection oPrinters.Item(i+1) Next
Const NETWORK = 22 Set objNetwork = CreateObject("WScript.Network") strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer") For Each objPrinter in colPrinters If objPrinter.Attributes And NETWORK Then strPrinter = objPrinter.Name objNetwork.RemovePrinterConnection strPrinter End If Next
' ======================================================================= ' ' NAME: UpdatePrintQueues-v1b.vbs ' ' AUTHOR: Paul S. Chapman ' DATE : 7-5-2006 ' ' COMMENT: This script was built to allow administrators to migrate print ' queues from one server to another with no disruption to the end user. ' Uses RegistryItemExists function FAQ'd by djhawthorne on tek-tips: ' FAQ329-5864: Checking if Registry Key's or Value's exist '========================================================================== Option Explicit Dim strFlagsOn, arrDefault, strDefaultPrinter Dim objShell, objNetwork, objDict ' This may have changed in newer Windows versions? Const strDPKey = "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device" ' Check if command line argument "1" is passed to script. Enable verbose ' mode if argument is present. If WScript.Arguments.Count = 0 Then strFlagsOn = False Elseif WScript.Arguments.Item(0) = "1" Then strFlagsOn = True End If Set objNetwork = CreateObject("WScript.Network") Set objShell = CreateObject("WScript.Shell") Set objDict = CreateObject("Scripting.Dictionary") ' Log script start time objShell.LogEvent 4,"Update Printers Script Starting" ' Check if Default printer registry key exists. If not then quit ' because this is the first time the user has logged in. If RegItmExist(strDPKey) = False Then If strFlagsOn = True Then WScript.Echo "New User Profile. Quitting..." End If WScript.Quit End If ' Read Registry key that contains default printer into an array arrDefault = Split(objShell.RegRead(strDPKey), ",") ' Verify that an array was returned, then check if default printer is network printer If IsArray(arrDefault) Then If Left(arrDefault(0), 2) = "\\" Then strDefaultPrinter = arrDefault(0) If strFlagsOn = True Then WScript.Echo "Default Printer: " & strDefaultPrinter End If End If End If ' Populate Dictionary object with old and new printer names. Old printer ' is the key, and new printer is the item (or definition). ' Syntax: ' .Add "\\<server>\<Old Queue Name>", "\\<server>\<New Queue Name>" ' ********** BEGIN EDIT AREA ********** With objDict .CompareMode = vbtextcompare .Add "\\OldServer\OldQueue1", "\\NewServer\NewQueue1" .Add "\\OldServer\OldQueue2", "\\NewServer\NewQueue2" End With [green]' ********** END EDIT AREA ********** ' Call sub to fix printers that are currently installed FixInstalled ' Reset Default printer, if it was replaced by "FixInstalled" sub. If objDict.Exists(strDefaultPrinter) Then objNetwork.SetDefaultPrinter objDict.Item(strDefaultPrinter) End If ' Log script end time objShell.LogEvent 4,"Update Printers Script Finished" Sub FixInstalled ' This sub enumerates the currently installed printers, then checks ' each one in turn against the Dictionary object to see if it has been ' replaced. If printer exists in dictionary, delete it and install the ' replacement printer. Dim ctr, objPrinters, strPrinter Set objPrinters = objNetwork.EnumPrinterConnections ' Check if printer is installed before attempting to delete. For Ctr = 0 To objPrinters.Count - 1 Step 2 If objDict.Exists(objPrinters.Item(ctr + 1)) Then strPrinter = objPrinters.Item(ctr + 1) If strFlagsOn = True Then WScript.Echo " Removing dead printer:" & strPrinter End If objNetwork.RemovePrinterConnection strPrinter If strFlagsOn = True Then WScript.Echo " Installing: " & objDict.Item(strPrinter) End If objNetwork.AddWindowsPrinterConnection objDict.Item(strPrinter) End If Next End Sub Function RegItmExist (RegistryItem) ' This function checks to see if registry key/value passed to it exists, ' and returns true if it does. If strFlagsOn = True Then WScript.Echo " Checking registry for: " & RegistryItem End If Dim ErrDescription On Error Resume Next 'Find out if we are looking for a key or a value If (Right(RegistryItem, 1) = "\") Then 'It's a registry key we are looking for. Try reading the key. objShell.RegRead RegistryItem Select Case Err Case 0: RegItmExist = True Case &h80070002: ErrDescription = Replace(Err.description, RegistryItem, "") Err.clear objShell.RegRead "HKEY_ERROR\" If (ErrDescription <> Replace(Err.description, "HKEY_ERROR\", "")) Then RegItmExist = True Else RegItmExist = False End If Case Else: RegItmExist = False End Select Else 'It's a registry value we are looking for. Try reading the value objShell.RegRead RegistryItem 'Catch the Error Select Case Err Case 0: RegItmExist = True Case Else RegItmExist = False End Select End If 'Turn error reporting back On On Error Goto 0 If strFlagsOn = True Then WScript.Echo " Item exists: " & RegItmExist End If End Function