Thoughts from the EPS Windows Server Performance Team
Today we’re going to go over a quick method to deploy print queues and printer drivers to multiple machines when other deployment methods, including deploying via GPO are not feasible. We’re going to use PsExec from Windows SysInternals in combination with some PrintUI.DLL commands. If you’re not familiar with PrintUI.DLL, it is the file that contains the different functions used by the printer configuration dialogs. So without further ado, let’s get started …
The first thing we need to do is determine what systems we want to push the printers and drivers to. In our example, we’re going to create a local folder on the C: drive called DEPLOY. Inside the C:\DEPLOY folder, we create a simple text file with a list of the machines – one per line. If you’re comfortable with scripting, the odds are that you’ve used a file like this in your scripting adventures. We save the file as COMPUTERS.TXT. The file itself looks like this:
COMPUTERNAME1 COMPUTERNAME2 COMPUTERNAME3 etc
Once we have our list of systems, we set it aside and compile our list of print queues and printer drivers that we want to create on our target machines. For this, we’re going to create a file called PRINTUI.CMD in our C:\DEPLOY folder. For each printer or driver we want to deploy, we create a corresponding line in our PRINTUI.CMD file – for example:
RUNDLL32 PRINTUI.DLL, PrintUIEntry /ia /f %windir%\inf\ntprint.inf /m “HP LaserJet 4”
Let’s break down this command and look at each piece of it:
Digressing for a moment, if we were going to use PrintUI.DLL to install a local printer, our syntax would look like this:
RUNDLL32 PRINTUI.DLL, PrintUIEntry /if /f %windir%\inf\ntprint.inf /b “Printer1” /m “HP LaserJet 4” /u /r “LPT1:” /Z
Let’s take a quick look at some of the differences in our syntax:
If we add the /y switch, we can specify that printer as the default printer
Getting back to our deployment scenario, we’re going to deploy a locally attached HP LaserJet 4 printer to each of our target machines with the following settings:
So, within our PRINTUI.CMD file we have the following entries:
rundll32 printui.dll,PrintUIEntry /ia /f %windir%\inf\ntprint.inf /m "HP LaserJet 4" rundll32 printui.dll PrintUIEntry /if /f %windir%\inf\ntprint.inf /b "Printer1" /m "HP LaserJet 4" /u /r "LPT1:" /Z rundll32 printui.dll,PrintUIEntry /y /n "printer1"
Note: The first line is not actually required in our example, but we left it in our example to demonstrate how you can use the command to deploy drivers. The printer driver itself is installed in the second line with the /m switch that looks inside the ntprint.inf file to find the HP LaserJet 4 driver.
Now that we have our list of computers, and we know what the requirements are for the remote machines, we’re ready to use PsExec to carry out our deployment. The syntax for this command is:
PSEXEC @C:\DEPLOY\COMPUTER.TXT –i –n 20 –u DOMAIN\USER –c C:\DEPLOY\PRINTUI.CMD
There are some new pieces of syntax here – let’s examine them:
The PsExec command copies our PRINTUI.CMD file to the remote systems and carries out the PrintUI.DLL commands. There are some caveats to this method. For example, the name of the printer driver may vary depending on which edition of Windows you are deploying the printers to. Thus you need to verify that the actual driver name is the correct one. Refer to the PsExec help and PrintUI.dll reference guide for more options on configuring the target printers.
Finally, PrintUI.DLL commands are flexible and can allow for some odd configurations that are rarely seen. Although it is possible to add per-machine printer connections using the /ga switch, this can result in some unpredictable printing behaviors and is not recommended. And with that, we have reached the end of our post. Thanks for stopping by!
Additional Resources:
- Sumesh P.
No support for CREATING a port!
Guys, thanks, that helps a lot!
@brian
prnport -a -s <computername> -r IP_172.24.96.139 -h 172.24.96.139 -o raw -n 9100 -me -y public -i 1
psexec \\<computername> -u %usr% -p %pwd% cmd.exe /c rundll32 printui.dll,PrintUIEntry /if /m "HP LaserJet 4350 PCL 6" /b "CWP3025 - HP LaserJet 4350 PCL 6" /n "CWP3025 - HP LaserJet 4350 PCL 6" /f <path_to_inf>\4350PCl.inf /u /r "IP_172.24.96.139" /z /Y /q
OK, so that work with inbox drivers. Here's my scenario:
Install a network printer which uses a driver which is not part of the inbox selection that comes with the o/s. This works like a charm using the /in switch.
Then install a local printer using the very same driver by passing the /u switch.
Here's the problem. As of Vista and Win7, printui only seems to "see" inbox drivers. Any drivers you add later are not available to use. For example the following works under XP but fails under Vista and Win7.
Assume I've already install a network printer that uses the SHARP AR-P450 PCL6 driver.
Now I want to install a local printer which uses that driver.
rundll32 printui.dll,PrintUIEntry /if /K /b "Legacy Printer" /f c:\windows\inf\ntprint.inf /r lpt2: /m "SHARP AR-P450 PCL6"
Fail. Put a /w on the end and you'll see that printui can't find the SHARP AR-P450 PCL6 driver at all.
So, how do we get around this? As I said we've been using this for ages on XP and now in Vista and more importantly Win7 it fails.
Print via remote desktop with TSPrint from TerminalWorks.com
Will this work also for scanner drivers?