Canon Printer Script

yurypanasyuk
New Contributor III

Hello,

Im looking for the best way to install printers via bash script. I download drivers from canon and it provides two options: PS driver with the size of 40mb and a UFRII pkg with the size of 71mb. We used to install using generic drivers but some docs dont print well. Im not to familiar with the differences between the two and was wondering if the entire pkg is needed to install for quality printing and have all printer options or can I just grab the PPD in /Library/Printers once installed and script it that way? The pkg's seem to have a ton more printers that i don't need and the largest file called canon_ps_core.pkg which I am not sure exactly it is. Any ideas or suggestions?

Script below fails right now with error: Permission denied
lpadmin: Unable to copy PPD file. (1)

#!/bin/bash

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
"${SCRIPTDIR}/CNMCIRAC5250S2.ppd.gz"

SysPrinter1="30th_North"
DispPrinter1="30th_North"
Addr1="lpd://10.71.30.17/"
Bldg1="Office"

sudo lpadmin -p $SysPrinter1 -v $Addr1 -D $DispPrinter1 -L $Bldg1 -m "$SCRIPTDIR" -E -o printer-is-shared=false
14 REPLIES 14

CapU
Contributor III

This is what we use on problem child printers that don't want to play nice:

!/bin/sh

(c) 2010 Walter Meyer SUNY Purchase College

Script to install and setup printers on a Mac OS X system in a "Munki-Friendly" way.

Make sure to install the required drivers first!

Variables. Edit these.

printername="BC334-P001"
location="BC334"
gui_display_name="BC334-P001"
address="lpd://print.server.here/printername"
driver_ppd="/Library/Printers/PPDs/Contents/Resources/HP LaserJet P2055d.gz"

Populate these options if you want to set specific options for the printer. E.g. duplexing installed, etc.

option_1="HPOption_Tray3=True"
option_2="PageSize=Letter"
option_3=""

Printer Install

In case we are making changes to a printer we need to remove an existing queue if it exists.

/usr/bin/lpstat -p $printername
if [ $? -eq 0 ]; then /usr/sbin/lpadmin -x $printername
fi

Now we can install the printer.

/usr/sbin/lpadmin -p "$printername" -L "$location" -D "$gui_display_name" -v "$address" -P "$driver_ppd" -o "$option_1" -o "$option_2" -o "$option_3" -o printer-is-shared=false -E

Enable and start the printers on the system (after adding the printer initially it is paused).

/usr/sbin/cupsenable $(lpstat -p | grep -w "printer" | awk '{print$2}')

exit 0

yurypanasyuk
New Contributor III

Awesome very helpful thank you! Could you search by IP rather then printer name if you wanted to remove existing printers?

CapU
Contributor III

yurypanasyuk
New Contributor III

My big question is if the entire package is good to install or is the single PPD file ok? What advantage does the 40mb package provide? I want to embed the driver inside my application bundle but a 69kb PPD vs a 40mb pkg is a little bizarre.

CapU
Contributor III

I just install the entire package. I'm not concerned about a 40mb file when I have applications that are more than 15GB in size.
My driver package from Ricoh is only 9.4mb

kerouak
Valued Contributor

I've had many issues mapping printers...
Best way I found was to use the CUPS web interface to add a printer, then add it via Casper Admin.

Seems to work fine..

CapU
Contributor III

I had a tech go around with a laptop to where the printer was, install and set up the printer on the laptop, then added them thru Casper Admin. Works good

yurypanasyuk
New Contributor III

Heres my completed script. I have a bash shell working with an AppleScript. The logic goes as follows:

  1. Check if printer driver already present. If not then install .pkg embedded within script (.app).
  2. If not present then run printer script. First checks if any duplicate printers are found by both IP and SMB protocols (our two ways of installing printers). If found then removes them first.
  3. Installs all printers and disables option for shared printing.
  4. Unlocks any printers that may be in a disabled state.
  5. Nice GUI touchups and reboot option.
set theAlertText to "Printer Installation"
set theAlertMessage to "This script will install printers to your machine. Any duplicate printers will be removed!
Would you like to continue?"
display alert theAlertText message theAlertMessage as critical buttons {"Don't Continue", "Continue"} default button "Continue" cancel button "Don't Continue"
--> Result: {button returned:"Continue"}

set progress description to "Script is in progress"
set progress additional description to "Preparing, please wait..."
set progress total steps to -1

delay 1
set progress total steps to 2
set progress completed steps to 0

set thePathToTheSourceFolder to (POSIX path of (path to me)) & "Contents/Resources/Printers/"
set PrinterInstall to quoted form of (POSIX path of (path to resource "PrinterInstall.sh"))

set theDestFolder to "/etc/cups"

tell application "Finder"
    set myFolder to (quoted form of (POSIX path of ((path to me) as string))) & "Contents/Resources/Drivers/"
end tell

set progress completed steps to 1
set progress additional description to "Installing Printer Driver"
delay 1

tell application "Finder"
    if POSIX file "/Library/Printers/PPDs/Contents/Resources/CNMCIRAC5550S2.ppd.gz" exists then
    else
        do shell script ¬
            "installer -allowUntrusted -pkg " & myFolder & ¬
            "Canon_PS_Installer.pkg -target /" with administrator privileges
    end if
end tell

set progress completed steps to 2
set progress additional description to "Configuring Printers"
delay 1

do shell script PrinterInstall with administrator privileges

delay 2


tell application "Finder"
    display dialog "Script has completed successfully!" buttons {"Restart", "Cancel"} default button "Cancel" with icon caution

    if button returned of result is "Restart" then
        do shell script "(sleep 5 ; shutdown -r now) &>/dev/null &" with administrator privileges

    end if
end tell
#!/bin/bash

###############################
#
# Variables
#
###############################

# Set the appropriate values below
# PPD is the location of the printer-specific PPD file *this should be installed locally prior to running the script
# SysPrinter is the printer name
# DispPrinter is the printer display name (this appears in the Printers list)
# Addr is the IPV4 Path to printer (http://xx.xx.xx.xx/) 
# Example: lpadmin -p 'ricoh4503copier' -v 'lpd://10.0.01/' -D 'Ricoh 4503 Copier' -L 'Main Office' -P '/Library/Printers/PPDs/Contents/Resources/RICOH MP C4503' -E -o printer-is-shared=false -o OptionTray=2Cassette -o LargeCapacityTray=Installed -o Finisher=FinAMUR -o Duplex=None -o PageSize=Letter -o ColorModel=Gray
# Bldg is the physical campus location of the printer

PPD1='/Library/Printers/PPDs/Contents/Resources/CNMCIRAC5550S2.ppd.gz'
SysPrinter1="17th_South"
DispPrinter1="17th South"
Addr1="lpd://10.18.26.17/"
Bldg1="Bell Office"

#PPD2=
SysPrinter2="18th_South"
DispPrinter2="18th South"
Addr2="lpd://10.18.28.17/"
Bldg2="Bell Office"

#PPD3=
SysPrinter3="19th_South"
DispPrinter3="19th South"
Addr3="lpd://10.18.28.18/"
Bldg3="Office"

###############################
#
# Script
#
###############################

# Printer Destroyer Script

# Get full list of printers & search for socket connection using IP
printer1=$(lpstat -s | grep '10.18.28.17' | awk -F'/' '{print $3}')
printer01=$(lpstat -s | grep 'smb://xxxxxxxxxxxxx' | awk -F'/' '{print $3}')


# If Printer variable is empty, then don't act. Else. Try to remove
if [ -z $printer1 ]; then
# I didn't find anything. End it here.
echo "[INFO] Printer Not Found. No removal necessary."
else
# Printer IP was found. Lets try to remove it.
echo "[INFO] $printer1 Printer Found. Attempting to remove."
# Use lpstat command to find that printer again and get the name,
# then clean up the string by removing the trailing colon.
# After that, use the lpadmin -x command to remove the printer.
remove_printer=$(lpstat -s | grep '10.18.28.17' | awk -F ' ' '{print $3}' | sed s/://g)
lpadmin -x $remove_printer

# Check if what we did actually worked.
printer_check=$(lpstat -s | grep '10.18.28.17' | awk -F'/' '{print $3}')

if [ -z $printer_check ]; then
echo "[INFO] Success! Old Printer Removed."
else
echo "[ERROR] Something went wrong. Likely two printers with 1 IP. Otherwise, I'm all out of ideas"
fi
fi

if [ -z $printer01 ]; then
echo "[INFO] Printer Not Found. No removal necessary."
else
echo "[INFO] $printer1 Printer Found. Attempting to remove."
remove_printer=$(lpstat -s | grep 'smb://xxxxxxxxxxx' | awk -F ' ' '{print $3}' | sed s/://g)
lpadmin -x $remove_printer
printer_check=$(lpstat -s | grep 'smb://xxxxxxxxxxx' | awk -F'/' '{print $3}')
if [ -z $printer_check ]; then
echo "[INFO] Success! Old Printer Removed."
else
echo "[ERROR] Something went wrong. Likly two printers with 1 IP. Otherwise, I'm all out of ideas"
fi
fi

#---------------------------------------------------------------------------------------------------------

printer2=$(lpstat -s | grep '10.18.26.17' | awk -F'/' '{print $3}')
printer02=$(lpstat -s | grep 'smb://xxxxxxxxxxxxx' | awk -F'/' '{print $3}')

if [ -z $printer2 ]; then
echo "[INFO] Printer Not Found. No removal necessary."
else
echo "[INFO] $printer2 Printer Found. Attempting to remove."
remove_printer=$(lpstat -s | grep '10.18.26.17' | awk -F ' ' '{print $3}' | sed s/://g)
lpadmin -x $remove_printer
printer_check=$(lpstat -s | grep '10.18.26.17' | awk -F'/' '{print $3}')
if [ -z $printer_check ]; then
echo "[INFO] Success! Old Printer Removed."
else
echo "[ERROR] Something went wrong. Likly two printers with 1 IP. Otherwise, I'm all out of ideas"
fi
fi

if [ -z $printer02 ]; then
echo "[INFO] Printer Not Found. No removal necessary."
else
echo "[INFO] $printer2 Printer Found. Attempting to remove."
remove_printer=$(lpstat -s | grep 'smb://xxxxxxxxxxx' | awk -F ' ' '{print $3}' | sed s/://g)
lpadmin -x $remove_printer
printer_check=$(lpstat -s | grep 'smb:xxxxxxxxxxxx' | awk -F'/' '{print $3}')
if [ -z $printer_check ]; then
echo "[INFO] Success! Old Printer Removed."
else
echo "[ERROR] Something went wrong. Likly two printers with 1 IP. Otherwise, I'm all out of ideas"
fi
fi

#----------------------------------------------------------------------------------------------------------

printer3=$(lpstat -s | grep '10.18.28.18' | awk -F'/' '{print $3}')
printer03=$(lpstat -s | grep 'xxxxxxxxxxxxxx' | awk -F'/' '{print $3}')

if [ -z $printer3 ]; then
echo "[INFO] Printer Not Found. No removal necessary."
else
echo "[INFO] $printer3 Printer Found. Attempting to remove."
remove_printer=$(lpstat -s | grep '10.18.28.18' | awk -F ' ' '{print $3}' | sed s/://g)
lpadmin -x $remove_printer
printer_check=$(lpstat -s | grep '10.18.28.18' | awk -F'/' '{print $3}')
if [ -z $printer_check ]; then
echo "[INFO] Success! Old Printer Removed."
else
echo "[ERROR] Something went wrong. Likly two printers with 1 IP. Otherwise, I'm all out of ideas"
fi
fi


if [ -z $printer03 ]; then
echo "[INFO] Printer Not Found. No removal necessary."
else
echo "[INFO] $printer3 Printer Found. Attempting to remove."
remove_printer=$(lpstat -s | grep 'smb://xxxxxxxxxxxx' | awk -F ' ' '{print $3}' | sed s/://g)
lpadmin -x $remove_printer
printer_check=$(lpstat -s | grep 'smb://xxxxxxxxxxxxx' | awk -F'/' '{print $3}')
if [ -z $printer_check ]; then
echo "[INFO] Success! Old Printer Removed."
else
echo "[ERROR] Something went wrong. Likly two printers with 1 IP. Otherwise, I'm all out of ideas"
fi
fi

#----------------------------------------------------------------------------------------------------------
sleep 2
#----------------------------------------------------------------------------------------------------------

sudo lpadmin -p "$SysPrinter1" -v $Addr1 -D "$DispPrinter1" -L "$Bldg1" -m "$PPD1" -E -o printer-is-shared=false

sudo lpadmin -p "$SysPrinter2" -v $Addr2 -D "$DispPrinter2" -L "$Bldg2" -m "$PPD1" -E -o printer-is-shared=false

sudo lpadmin -p "$SysPrinter3" -v $Addr3 -D "$DispPrinter3" -L "$Bldg3" -m "$PPD1" -E -o printer-is-shared=false

#Clears every print job and then reenables every printer that currently has a status of disabled.
sudo /usr/sbin/cupsenable -c `/usr/bin/lpstat -p | /usr/bin/grep disabled | /usr/bin/awk '{print $2}'`

# man lpadmin
# -p = Named printer or class
# -v = device URI
# -D = textual description of destination
# -L = location of destination
# -m = model (ppd)
# -E (at end) enables device

# CUPS Options
# man lptoptions
# -o printer-is-shared=false disables sharing
# -o Duplex=None disables two-sided printing 
# -o Duplex=DuplexNoTumble enables two-sided printing long edge
# -o Duplex=DuplexTumble enables two-sided printing short edge

# Printer has Large Capacity Tray
# lpadmin -p $cupsName -o LargeCapacityTray=Installed

# The following options must be manually commented in/out
# If a Ricoh SP4100 then do not uncomment any options

# If a Ricoh C5502 then uncomment the following line
# lpadmin -p $SysPrinter -o LargeCapacityTray=Installed -o PageSize=Letter -o Duplex=DuplexNoTumble -o ColorModel=Gray -o Finisher=FinKINGB

# If a Ricoh MP6002 then uncomment the following line
# lpadmin -p $SysPrinter -o PageSize=Letter -o Duplex=DuplexNoTumble -o Finisher=FinEUPHRATESE

exit

yurypanasyuk
New Contributor III

The only thing I CANNOT figure out is why duplex printing is enabled by default. I cant find the setting by searching using this command and output below:

lpoptions -p 34th Floor -l | grep -i duplex
Output: CNDuplex/Print Style: None *DuplexFront Booklet

Could it be the option above? If so how do view options to change them?

Here is the duplex section in the PPD:

*OpenUI *CNDuplex/Print Style: PickOne
*DefaultCNDuplex: DuplexFront
*CNDuplex None/1-sided Printing: "<< >>setpagedevice"
*CNDuplex DuplexFront/2-sided Printing: "<< >>setpagedevice"
*CNDuplex Booklet/Booklet Printing: "<< >>setpagedevice"
*CloseUI: *CNDuplex

neilmartin83
Contributor II

Regarding UFRII or PS - that's the language used to communicate with the printer. PS is PostScript and UFRII is Canon's native proprietary language.

What you use would depend on what your specific printers support and perhaps whether you're using a managed print system in between your Macs and your printers. PostScript arguably gives higher quality output but your printers will have to be able to support it. When we were setting up our managed print system, uniFLOW, the PostScript drivers were recommended for the Macs. However, the Canon MFDs we have required extra licensed firmware to support PostScript and this had a cost implication per unit.

If your printers do have PostScript support, use that driver IMO. There are accounts of more accurate colour rendering output with PostScript drivers vs UFRII as well if you do a quick web search - UFRII compresses the data sent to the printer which is more efficient for your network etc but at the expense of quality.

bentoms
Release Candidate Programs Tester

@yurypanasyuk I ran into this before, have a look at this

yurypanasyuk
New Contributor III

Thanks Neil! I thought UFRII was the choice primarily if you were using a fiery controller. Good to know PS is the way to go.

Bentoms: I saw this post too and figured out how to do it. Fairly simple just a bunch of testing. Except no need to use lpoptions. I strictly added another option to my current lpadmin command:

sudo lpadmin -p "$SysPrinter1" -v $Addr1 -D "$DispPrinter1" -L "$Bldg1" -m "$PPD1" -E -o printer-is-shared=false -o CNDuplex=None

donmontalvo
Esteemed Contributor III

FYI, formatting doesn't work when adding text as code in a prompt.

**-o CNDuplex=None**
--
https://donmontalvo.com

yurypanasyuk
New Contributor III

Thanks Neil! I thought UFRII was the choice primarily if you were using a fiery controller. Good to know PS is the way to go.

Bentoms: I saw this post too and figured out how to do it. Fairly simple just a bunch of testing. Except no need to use lpoptions. I strictly added another option to my current lpadmin command:

sudo lpadmin -p "$SysPrinter1" -v $Addr1 -D "$DispPrinter1" -L "$Bldg1" -m "$PPD1" -E -o printer-is-shared=false -o CNDuplex=None