bash script --> package

ianmb
Contributor

I have a bash script that creates printer queues for users if they run it under an Admin account.

I'd like to make that an easy installable package in Composer if I can, is that possible and how would I go about it?

24 REPLIES 24

stevewood
Honored Contributor II
Honored Contributor II

Do you use Self Service in your environment? If so, why not just upload the script to your JSS and the script out in a Self Service Policy on the JSS? Self Service will run the script as root, which will install the printer for your user. No need to package using Composer.

This is how I deploy printers here. I use a script to create the printer with lpadmin and then set any options.

RaulSantos
Contributor

@stevewood Can you post your script here.

stevewood
Honored Contributor II
Honored Contributor II

Sure. This is to add a Xerox 560 with Fiery RIP:

#!/bin/sh


lpadmin -p FreshPrints -L "Studio" -E -o printer-is-shared=false -v lpd://10.x.x.x -P /Library/Printers/PPDs/Contents/Resources/en.lproj/Xerox Color EX 550-560
lpadmin -p FreshPrints_HOLD -L "Studio" -E -o printer-is-shared=false -v lpd://10.x.x.x/HOLD -P /Library/Printers/PPDs/Contents/Resources/en.lproj/Xerox Color EX 550-560

# set options
lpadmin -p FreshPrints -o EFOutputBin=middle
lpadmin -p FreshPrints -o EFOpt_Input_HCFTray=1Tray
lpadmin -p FreshPrints -o EFDuplex=False
lpadmin -p FreshPrints -o EFManualDuplex=False
lpadmin -p FreshPrints -o EFGAFeaturesOpt=GA2


lpadmin -p FreshPrints_HOLD -o EFOutputBin=middle
lpadmin -p FreshPrints_HOLD -o EFOpt_Input_HCFTray=1Tray
lpadmin -p FreshPrints_HOLD -o EFDuplex=False
lpadmin -p FreshPrints_HOLD -o EFManualDuplex=False
lpadmin -p FreshPrints_HOLD -o EFGAFeaturesOpt=GA2

You can find out what options to set using "lpoptions" and a little testing. You can list out all of the options a printer has this way:

lpoptions -p <printername> -l

Then using a little grep fu you can find the specific option you need to set. Test it and then set it in the script.

Hope that helps.

ianmb
Contributor

I do use Self Service with managed clients, but I'd like to create a package for those standalone systems that are not enrolled in the JSS (yet).

jhalvorson
Valued Contributor

We recently started using Papercut, but our clients know it as OurCompanyName Green Print. Here is an example for an Samsung multi function printer. (I also commented all of the options at the end of the script so that I had a record of which options were available.)

#!/bin/bash

##########################################################################################
# Created by JHalvorson
# Created on 10/02/2013
# reference http://techjournal.318.com/tag/lpoptions/
##########################################################################################
## Checks if the PPD exists
## Adds the following printer but is not capable of setting it as the default.
##########################################################################################

printerDriver="/Library/Printers/PPDs/Contents/Resources/Samsung CLX-9250 9350 Series.gz"
#HINT - remove any back slashes from the path above
printerQueueName="GreenPrint_Samsung_CLX-9252_9352_Series"
printerURL="lpd://greenprint.company.edu/GreenPrint_Samsung_CLX-9252_9352_Series"
printerDescription="Samsung CLX 9252 9352 (Green Print)"
printerLocation="Green Print Queue"
prntDrvPackage="tbd"

#### Check for the PPD, if missing exit this script
if [ ! -f "$printerDriver" ]
then
    echo "The printer driver is missing.  Exited the setup of the Printer."
    exit 1
fi
echo ""
lpadmin -p "$printerQueueName" -v "$printerURL" -D "$printerDescription" -L "$printerLocation" -P "$printerDriver" -E -o OptionalTray=Tray34 -o Duplex=DuplexNoTumble -o Finisher=2BinFinisher -o ColorModel=Gray -o printer-is-shared="False"
echo "Added $printerQueueName to the Mac with preferred options."
exit 0


# MACDEV:~ joeuser$ lpoptions -p "_xxx_ipaddress_here_242" -l
# OptionalTray/Optional Tray: None *Tray34
# OptInnerOutBin/Optional Inner Output Bin: *False True
# Finisher/Finisher: *None 2BinFinisher
# PSDataEncryption/Job Encryption: *False True
# JobSetting/Print Mode: *Normal Confidential Store StoreNPrint
# StoreCheck/Store to HDD: *Off On
# StorePublic/Store to Public HDD: *Off On
# PrivateCheck/Store as Confidential: Off *On
# PrintAt/Print At:
# USERID/User ID:
# JOBNAME/Job Name:
# EnterPassword/Enter Password:
# ConfirmPassword/Confirm Password:
# AccountType/Accounting type: *Accounting Pincode
# AccountID/User ID:
# Permission/ : *Personal Group
# AccountPassword/Enter Password:
# ConfirmAcctPassword/Confirm Password:
# PINCode/ID Only:
# Collate/Collate: False *True
# Duplex/Double-sided Printing: *None DuplexNoTumble DuplexTumble
# SECResolution/Quality: Best Normal *Draft
# ColorModel/Color Mode: *RGBA Gray
# BlackOptimization/Black Optimization: *Off On
# InputSlot/Paper Source: *Auto Upper Middle Lower Tray3 Tray4
# PageSize/Page Size: *Letter Legal Executive A4 A5 B5-JIS US-Folio Env10 EnvDL EnvC5 EnvC6 B5-ISO EnvMonarch A6 Oficio_S Statement Postcard_S A3 Env9 C4 B4 8K 16K TabloidSamsung Custom.WIDTHxHEIGHT
# MediaType/Paper Type: *None Plain Thick Thin Bond Color Labels Envelope Preprinted Recycled Cotton Archive Punched Letterhead HeavyWeight ExtraHeavyWeight1 ThinCardstock ThinGlossy
# DocType/Document Type: *Standard Photo Business Cad Browser
# EdgeEnhance/Edge Enhancement: Off *Normal Maximum
# Trapping/Trapping: Off *Normal Maximum
# SECSimulator/RGB Color Simulator: *PrinterDefault DefaultSimulation SimulationA SimulationB SimulationC SimulationD
# SECRGBColor/Intent: *Standard Vivid Device CoImaging
# SECCMYKBypass/CMYK Bypass: *False True
# Screen/Screen: None Normal *Enhanced Detailed
# DarkenText/Clear Text: *False Medium Maximum
# SkipBlankPages/Skip Blank Pages: *False True
# n_Brightness/Brightness: 0 10 20 30 40 *50 60 70 80 90 100
# n_Contrast/Contrast: 0 10 20 30 40 *50 60 70 80 90 100
# n_Saturation/Saturation: 0 10 20 30 40 *50 60 70 80 90 100
# n_RCBalance/Cyan-Red: 0 10 20 30 40 *50 60 70 80 90 100
# n_GMBalance/Magenta-Green: 0 10 20 30 40 *50 60 70 80 90 100
# n_BYBalance/Yellow-Blue: 0 10 20 30 40 *50 60 70 80 90 100
# SortOptions/Sort Options: *None Offset Rotate
# StapleLocation/Staple: *None 1Staple_P 1Staple_L
# OutputBin/Output Bin: *None Bin1 Bin2 Bin3 Bin4
# Booklet/Booklet: *Off On
# BookletOutputsize/Output Size: *Off Letter Legal Executive A4 A5 B5-JIS US-Folio Env10 EnvDL EnvC5 EnvC6 B5-ISO EnvMonarch A6 Oficio_S Statement Postcard_S A3 Env9 C4 B4 8K 16K TabloidSamsung
# BookletGutter/Booklet Gutter: *0 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
# BookletOrder/Right Binding: *False True
# FrontCoverOption/Front Cover Option: *None BlankPreprinted 1SidedPrinted 2SidedPrinted
# FrontCoverSource/Front Cover Source: *None Auto Upper Middle Lower Tray3 Tray4
# FrontCoverType/Front Cover Type: *None PrinterDefault Plain Thick Thin Bond Color Labels Envelope Preprinted Cotton Recycled Archive Punched Letterhead HeavyWeight ExtraHeavyWeight1 ThinCardStock ThinGlossy
# BackCoverOption/Back Cover Option: *None BlankPreprinted 1SidedPrinted 2SidedPrinted
# BackCoverSource/Back Cover Source: *None Auto Upper Middle Lower Tray3 Tray4
# BackCoverType/Back Cover Type: *None PrinterDefault Plain Thick Thin Bond Color Labels Envelope Preprinted Cotton Recycled Archive Punched Letterhead HeavyWeight ExtraHeavyWeight1 ThinCardStock ThinGlossy
# FrontBackCoverOption/Front and Back Cover Option: *None BlankPreprinted 1SidedPrinted 2SidedPrinted
# FrontBackCoverSource/Front and Back Cover Source: *None Auto Upper Middle Lower Tray3 Tray4
# FrontBackCoverType/Front and Back Cover Type: *None PrinterDefault Plain Thick Thin Bond Color Labels Envelope Preprinted Cotton Recycled Archive Punched Letterhead HeavyWeight ExtraHeavyWeight1 ThinCardStock ThinGlossy

My policy, which is available through Self Services, includes the both the SamsungPrinterDrivers2.6.pkg and the script. It's scoped to all computer with OS X 10.9 - through - 10.6.

stevewood
Honored Contributor II
Honored Contributor II

Well, I'd probably use the preinstall or postinstall scripts in a package to do it then. In Composer I don't think you can do this easily without installing something else or doing a snapshot and then deleting anything it finds so that you have an empty package.

If you were to do the snapshot and leave it empty, click on the disclosure triangle next to the package name, then right click on Scripts, you can add whatever script you want. I would probably add a postinstall script. Click on postinstall in the pane and then enter the script in the window.

Your other option would be to use the program Packages, create a new package and load in a postinstall script that you create in your favorite code editor (TextWrangler, TextMate, etc).

Hope that helps.

alexjdale
Valued Contributor III

I would make it the pre/postflight script in a package (I use Iceberg to build packages like this, personally). Pre/postinstall scripts will only run the first time the package is installed, and users may want to run it again later (if they have to reset the printing system, for example).

gregneagle
Valued Contributor

https://managingosx.wordpress.com/2010/02/18/payload-free-package-template/

JPDyson
Valued Contributor

A second vote for Packages.app (http://s.sudre.free.fr/Software/Packages/about.html). We've got a couple of cases where we use this to package a script.

rtrouton
Release Candidate Programs Tester

I do this occasionally and use pkgbuild to create the package. I have a post that describes my process:

http://derflounder.wordpress.com/2012/08/15/creating-payload-free-packages-with-pkgbuild/

Kaltsas
Contributor III

Third vote for Packages. I used this to package up the McAfee agent script.

Lotusshaney
Contributor II

Packages is brilliant. I use it all the time, in fact I rarely use composer for any of my packaging as I find it lacking features I need

McNeil
New Contributor

I see so many references to people using lpadmin with the JSS to add/remove printers. We attempted to deploy Papercut last spring at our school and have been halted for over half a year while trying to devise a plan to add/remove queues with the JSS that uses Kerberos authentication. The easiest way seems to be using lpadmin to add the queues with the Operation Policy Authenticated (-o printer-op-policy=Authenticated) and tell the CUPS server to authenticate to our Windows print queues with Kerberos using "cupsctl DefaultAuthType=Negotiate". I can make it work when entering the commands through Terminal as root on each machine individually, but for the life of me, I can't get the commands to run without needing to pass the root password with the JSS. It's not consistent, but I almost always get "Unauthorized" when running cupsctl or lpadmin through the JSS. Can anyone please explain how you're running lpadmin commands through the JSS?

stevewood
Honored Contributor II
Honored Contributor II

The script that I posted toward the top of this thread is how I am adding printers via the JSS. Any script that is run as part of a policy or from Casper Remote is run as the root user, so I'm not sure why you would be receiving "Unauthorized" when running your commands.

Can you elaborate on how you have tried to run these commands? Perhaps post the script that you are using to do this with? And how you are running the script (policy, Self Service, Casper Remote).

McNeil
New Contributor

Thanks for the reply! I've tried way too many scripts to count, but here is the most basic of command that I can't pass through the JSS without failing Unauthorized:

  1. #!/bin/bash
  2. lpadmin -p US_BW_SHARP_Copiers_SMB -P "/Library/Printers/PPDs/Contents/Resources/SHARP MX-M950.PPD.gz" -o printer-op-policy='Authenticated' -v "smb://usdomainr2.sssas.school/US_B&W_SHARP_Copiers" -E
  3. exit

I've run this command every way under the sun. I've also read numerous places that the lpadmin command won't execute without being required to enter the root password, so I've attempted to use the Security command to change the AuthorizationDB to allow it to run without a root password. Numerous times I've thought I had it right, but eventually during testing, it falls apart somewhere and starts returning Unauthorized again. Here's an example of the log when it fails with Unauthorized:

Executing Policy !RM - TEST - 8_18...
[STEP 1 of 1]
Running script !RM - TEST - AddTestPrinter8_18...
Script exit code: 1
Script result: lpadmin: Unauthorized

I've run it directly as a script entered into the JSS, uploaded the .sh file into Casper, through Self Service, using Composer to put a pkg/dmg together, etc. I've also run it through ARD and got Unauthorized, and ARD runs scripts as the root user too? It seems like the command is getting blocked by a permissions thing somewhere, I'm just dumbfounded as to how so many people on JAMFNation run it seemingly without issue?

This is by far the most frustrating thing I've had to deal with in my 15 years as a network administrator, and I'm just kind of boggle brained and burnt out at this point! :-( Initially I thought "I'm so close, I'm just missing something very simple".... more than half a year later (granted not devoting every minute to this as I have plenty of other responsibilities), I still have not found an answer as to why I can't run lpadmin commands... at least consistently. It has worked a dozen times or so, but always mysteriously stops working for some reason in my testing. Any insight you could provide would be enormously appreciated!

donmontalvo
Esteemed Contributor III

@McNeil][/url wrote:

I've also read numerous places that the lpadmin command won't execute without being required to enter the root password

JSS runs scripts as root. Did you try changing exit to exit 0...if you're running JSS 9.x you don't need to have an exit code.

Running Scripts
https://jamfnation.jamfsoftware.com/article.html?id=145

--
https://donmontalvo.com

stevewood
Honored Contributor II
Honored Contributor II

When you try to run those commands from the terminal, not via Casper, do they fail? So if you take the one you posted above and run it from the terminal:

sudo lpadmin -p US_BW_SHARP_Copiers_SMB -P "/Library/Printers/PPDs/Contents/Resources/SHARP MX-M950.PPD.gz" -o printer-op-policy='Authenticated' -v "smb://usdomainr2.sssas.school/US_B&W_SHARP_Copiers" -E

Does that fail? Or if there's one that fails all the time, does it fail from the terminal?

I don't use Windows print servers here, nor do we do authenticated printing, so I'm a little out of my element there, however if it works from the terminal, it *should* work from the JSS. I tried setting up an HP LaserJet 2430 using an AD Print Server and your code, and it worked from the terminal. I even put it into the JSS and ran it from a Self Service policy.

So, do your scripts work from the Terminal?

mscottblake
Valued Contributor

@stevewood Can you elaborate on why you didn't add the options with the original lpadmin call?

McNeil
New Contributor

Thanks so much guys for getting back to me! As far as running the scripts as the root user, that's exactly what I said the first time it failed with Unauthorized. I said to myself "the JSS runs them as root, right? So how am I not authorized to run lpadmin commands, but I can run pretty much any other command out there?". I believe I've used the "exit 0" remark, but I'll try again tomorrow when I get to the office just in case. And yes, when I run the commands through the CLI at each terminal I get exactly what I'm looking for, correct print queue with Operation Policy and all, but it prompts me for the root password about 90% of the time (yes, I said 90%, not 100%). And if I don't enter the root password, it says Unauthorized. Only faculty at our Upper School, about 40 or 50 computers, are actually using Papercut for accounting because I went to each computer individually and entered those lpadamin commands in the Terminal app. But I can't touch over a thousand computes with a couple copy/paste lpadmin commands.... I need to be able to add/remove the queues with driver settings per printer through the JSS (as far as I can tell).

Also, and it probably doesn't matter, but our JSS is a Windows 2008 R2 server. I've been told that does not matter, but it seems most people are running the JSS on a Mac and have no issue. I have yet to built another JSS on Mac and test! Thanks again!

stevewood
Honored Contributor II
Honored Contributor II

Okay, instead of looking at the script itself, I'd start looking at the machines. Are they all the same OS? Are they all bound to AD or OD?

As far as your JSS, it does not matter what OS the JSS is on. Mine is running on Ubuntu 12.04 and I've had no problems like this. It sounds more like an end user machine issue.

donmontalvo
Esteemed Contributor III

Can you copy/paste your script into a new post, this time first hit the Script tag button then paste the script (5th button in the edit window):

>_

Wondering if there's some kind of syntax issue?

Don

--
https://donmontalvo.com

McNeil
New Contributor

Hey Guys! I was just brainstorming with my colleague for two hours and had an epiphany. I feel like an idiot as this has been right in front of my nose for months now and just finally "clicked". I've been using SMB to send jobs to our Windows print queues, which require the "Use Kerberos Authentication" attribute to be set in CUPS. I wasn't aware this included making changes to CUPS in general, which I somehow missed. @donmontalvo, you're of course absolutely right scripts run as root, but I had CUPS looking for Kerberos authentication rather than Basic authentication, which is why it kept prompting me for the root password when I tried to run lpadmin through the JSS. I thought it was only for print job submission and not actually authenticating into CUPS. I haven't tested this thoroughly, but I'm pretty sure that's whats happening. And if that is whats happening, how do I now get all my clients to switch back to Basic CUPS authentication? I could reset the printing systems all together, which would definitely work, but would create a whole other set of issues! How do I change CUPS default authentication back to Basic if I can't authenticate into it in the first place? Offending command: "cupsctl DefaultAuthType=Negotiate" Needs to be ....=Basic.

stevewood
Honored Contributor II
Honored Contributor II

Well, you'll want to test this out, but I was able to mimic what you'll need to do using an shell script with expect.

#!/bin/bash

# Script to reset cups authetication type
# requires Casper JSS

# set variables
PASSWORD=$4

expect <<- DONE
    set timeout -1
    spawn su root -c "cupsctl DefaultAuthType=Basic"
    expect "Password:"
    send "$PASSWORD
"
    expect "*?localhost?"
    send "$PASSWORD
"
    expect EOF
DONE

I can't take full credit for that, I have to give the hat tip to Andrina Kelly and her presentation last year at JNUC.

Basically you'll want to add that script to your JSS and then create a policy to call the script. In the Parameter 4 box of the script in the policy, you'll want to put your local root password. I'm assuming you have root enabled on all of the machines.

Anyway, that will reset your cupsctl back to Basic authentication.

McNeil
New Contributor

Thanks so much! Not much time today, then I'm out starting lunch time tomorrow through Friday, but I'll test it out as soon as possible and let you know how it goes. Much appreciated!