User Tools

Site Tools


networking:windows:printer_shared

Shared Network Printers

See also Shared Network Printers Using GPP

FIXME This page is now just a collection of notes. For shared printers, we use GPP.

:!: 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

Group Policy Preferences

This is our current method for sharing networked Windows printers. See link above.

Group Policy

:!: We have not found publishing printers via GPO to be trouble free.

  • Can't set default printer

Windows Server 2008 with Multiple Drivers

  1. Add printer to server and confirm printing.
  2. Download additional drivers and extract if necessary. Note the location.
  3. Right click and select Printer Properties, Sharing tab, Share this printer.
  4. Edit Share name (name displayed to users) if desired
  5. Click Additional Drivers button. Select operating systems that would be using the printer.
  6. Click OK, browse to driver location and install printer.

When installing drivers for multiple architectures on a Windows Server, verify that the additional drivers are:

  • Same exact version
  • Same exact name

Per-Machine (Global) Network Printer Connections

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.

:!: You must use the CLI to manipulate global printers.

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"

Printer Tools

adprintx.exe

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.

Set Default Printer.exe

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.

PsExec.exe

https://technet.microsoft.com/en-us/sysinternals/bb897553.aspx

This tool is needed to clear out some protected registry keys.

Troubleshooting

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

  • Deletes local printer devices too? Like PDFCreator?

Print Spooler Diagnostic: https://support.microsoft.com/en-us/kb/2768706/en-us

:!: Use Winprint print processor for all shared printers.

:!: For RDS servers, disable CSR (client side rendering) for all shared printers.

Clear Out Print Queues

net stop spooler
del /q /f "%systemroot%\system32\spool\printers\*.*"
net start spooler

Delete Redirected Printers

Sometimes you'll get various redirected printers that you can't just delete…

  1. Stop the print spooler
  2. Use regedit to delete the problematic printer(s) from these keys:
    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers
    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\PrintServerName\PrinterName
    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\V4 Connections
  3. Reboot the machine

Phantom Printers That Won't Go Away

:!: 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.

Problems Setting Default Printer

Possible cause:

  • The printer name under the 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.

Scripts

PrintersReset.bat

:!: 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

PrintersClear.bat

:!: This is the script we usually use to let users reset their own printer configuration. It forces the user to log off. Printers are reinstalled via Group Policy Preferences when they log back in.

@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

PrintersClear - Global - Run as Admin.bat

@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

PrintersAdd - Global - Run as Admin.bat

:!: 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

PrintersAddRemote - Global - Run as Admin.bat

@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

'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

RemoveAllPrinters.vbs

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

UpdatePrintQueues.vbs

' =======================================================================
'
' 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
networking/windows/printer_shared.txt · Last modified: 2017/11/01 10:01 by gcooper