Help requested with making a script for copying files.

Dear readers,

Before I ask your help with my problem, I would like to introduce myself ever so shortly:

My name is Dennis, a 40 year old Apple Service Engineer from the northern part of the Netherlands.
I have been working with Apple’s for over 15 years now and repairing them for over 8 now.
My expertise in repairs is much much better than my expertise in scripting.

This is why I would like to ask this great community for some help!

The problem is as follows:

For an educational partner I am looking to find a way to add printers to the printerlist without overwriting the excisting printerlist.
This is much more of a challenge than I anticipated.
I tried using Pakcagemaker to make a package of the printers that need to be added in order for the users to easily upgrade their excisting printer list with new printers bought by the organization.

The problem with this is the fact that the package made by packagemaker will overwrite the excisting list.

After some hard thinking I found a solution (in my head at least).

What if I could copy the contents of the /private/etc/cups/ppd folder to a temporary folder on the desktop, then execute the package made with packagemaker and then copy the contents of the temporary folder back to the /private/etc/cups/ppd folder without overwriting it’s current contents.

That would probably solve my problem as the overwriting from the package made with Packagemaker would be negated by making a copy of the excisting folder nd then copying the contents of said folder back to the system folder.

I found out you can add applescript tp your packagemaker package, so it would be fantastic if I could come up with a script that would do the following things for me:

  • Create a temporary folder on the desktop called “CUPS_TEMP”
  • Copy the contents of the /private/etc/cups/ppd folder to the CUPS_TEMP folder on the desktop
  • Wait for the execution of the packagemaker folder (I can set priorities in packagemaker to solve sequence problems)
  • After the execution and adding of the new printers copy the contents of the CUPS_TEMP folder back to the /private/etc/cups/ppd folder and adding the contents to that folder without overwriting the contents of that folder.
  • Delete the CUPS_TEMP folder after all actions have been completed

Sadly, my knowledge and Google haven’t brought me past the creation of a folder on my desktop with the name CUPS_TEMP using the following script:

tell application "Finder"
set p to path to desktop
make new folder at p with properties {name:"CUPS_TEMP"}
end tell

I would REALLY appreciate any help you could give me regarding this problem.

Thank you in advance for reading and any help you can give me!

Kind regards,

Dennis

Hi Dennis,

I’m not sure from your post if you are trying to install printer queues or if you only need to add additional PPD files to the directory /private/etc/cups/

My understanding is that this directory holds a copy of the PPD. It is created from the ‘base’ PPD that lives in the /Library/Printers/PPDs/Contents/Resources directory, and is updated to store settings you specify in preference to the manufacturers defaults. As you may know these printing defaults can be set via the cups web ui or using lpadmin terminal commands.

One word of caution - some printers drivers (especially for multifunctional devices) use calls to additional plugins that live in the /Library/Printers/PPDs directory, they are installed along with the PPD by the printer driver installer. You may find that copying the PPD on its own creates issues if it makes calls to missing plugins.

It is fairly simple to script the install of the drivers if you have a .pkg file. Once the driver is installed and a PPD is present in the you can use the lpadmin terminal command to install a print queue. Here is a simple example of an Applescript that will install a printer from an existing PPD.


set portName to "Printer_01" --Avoid using spaces in port names.
set ipAddress to "10.1.1.243" --Substitue for the IP address of your printer.
set ppdPath to "/Library/Printers/PPDs/Contents/Resources/Xerox ColorQube 8870DN.gz" --Enter the path to the correct PPD for your printer (must be present).  This example uses a ppd which is in a compressed .gz format
set displayName to "Staff Room Printer" --Set a display name for the printer.

--Install printer
try
	do shell script "/usr/sbin/lpadmin -p " & quoted form of portName & " -E -v lpd://" & ipAddress & "/lp -P " & quoted form of ppdPath & " -D " & quoted form of displayName & " -o printer-is-shared=false"
on error error_message number error_number
	display alert ("Failed to create print queue - Please consult your System Admin") ¬
		message error_message & (" Error number ") & error_number & "."
	return
end try

This can easily be made into a repeat loop that installs multiple printers. You can even extend it to set default options such as colour/mono, 1-sided,2-sided etc

If this is missing the point of your post then please disregard - in any case good luck!

RBUDD

Hey RBUDD,

First of all - thank you very much for your answer!

Let me try to clarify what the exact problem is, and what I am trying to do.

We are trying to make it so that a user gets a clickable executable that will add a series of printers (combined in a self made package) to the excisting printer list.
We are trying to install a new printer, so no preferences :slight_smile:

I am trying to look into a way to solve the problem that packages create because they simply overwrite the excisiting printer list in the system preferences - > printers & scanners pane.

I would like to make it so that our package adds printers to the excisting list but doesn’t overwrite that excisting list.

I looked into various methods of mass deployment, but have not been able to solve this issue.
This might be due to my own limited knowledge of Unix structures - I will immediately admitt this.

If there is another way, that would be extremely welcome - but I thought I could maybe fix it by copying the excisting printerlist (or the source of where they are in the OS) and copy them to a temporary folder - then execute the package we made and then solve the problem of the overwritten printer list by copying back the previous list we started with back from a temporary folder.
Thus intergrating the old list with the newly installed one.

I hope this makes sense :slight_smile:

Thank you though for clarifying what the files in the directory I mentioned actually do - I was unaware of their function and thought this was the actuall printer list!

Kind regards,

Dennis

Hi Dennis,

Thanks for the clarification. I did a few quick tests, and found that copying files in /private/etc/cups/ppd from one Mac to another is possible, but it won’t actually create a new printer within System Prefs > Printers & Scanners.

I understand that you want to launch an app that installs multiple printers, fortunately Applescript can do that. There are a few edge cases where it might not work, mostly on older Macs that are pre 10.6 but I’m not sure if that is relevant to you?

The example script in my previous post is a good starting point for you to experiment, but it requires a Xerox PPD that you probably don’t have on your system so i am reposting the code with something that will work on your Macs.


set portName to "Printer_01" --Do not uses spaces in port name.
set ipAddress to "10.1.1.243" --Substitue for IP address of your printer.
set genericPpdPath to "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/Resources/Generic.ppd" --Path to Apple Generic PostScript PPD (On 10.11.4).
set displayName to "Staff Room Printer" --Set a display name for the printer.

--Install printer
try
	do shell script "/usr/sbin/lpadmin -p " & quoted form of portName & " -E -v lpd://" & ipAddress & "/lp -P " & quoted form of genericPpdPath & " -D " & quoted form of displayName & " -o printer-is-shared=false" with administrator privileges
on error error_message number error_number
	display alert ("Failed to create print queue - Please consult your System Admin") ¬
		message error_message & (" Error number ") & error_number & "."
	return
end try

The script above uses Apple’s Generic PostScript Printer driver. I recommend you check that the path is correct, i have checked with 10.11 and 10.8 - but it may move around in other versions. I have also added ‘with administrator privileges’ to the ‘do shell script’ so that it prompts for admin credentials. You’ll need this if logged in users are not running as local admins, if they are you don’t need it.

Anyway… Copy this script into your Applescript script editor, then choose file > export and set the export option to ‘Application’. This will give you an installer app that installs the test printer. You can then look at modify the script to add more printers - your printers!

The application you create will likely be blocked by gatekeeper permissions on newer Macs if they are on Apple’s default settings. I’m sure you know the ways around that. Personally i tend to code sign my Applescript apps, but you need a developer account for that.

If you end up going with this method you’ll need to consider which drivers or PPDs you use for the printer queues. The generic driver is good, but very limited if your using anything but a desktop A4 printer. You’ll really want to use the right drivers, if they are not installed you can get the script to install them. But lets not get ahead of ourselves…

Regards,

RBUDD

Hey RBUDD,

Thanks again for your fantastic help!

I’ll look into to this and start some tests to see if this solves our problem :slight_smile:

I really appreciate your help on this matter, I will get back to you next week :slight_smile:

Kind regards,

Dennis

RBUDD, you are a star - the script works like a charm!

We do not use any older systems than 10.9 - so this works just fine.

I tested it with a little setup I have and it works :slight_smile:

But here comes the difficult part - is it possible to use the correct PPD’s when we have the installers downloaded and present on the systems they need to be installed on?
How do I go about installing these through a script?

And can these script be combined into 1 installer, much like we made an installer of your brilliant previous script.

And the final hurdle we need to tackle is the installation of preferences such as the correct paper tray the prints should come from - is this at all scriptable?

I REALLY appreciate your hard work to help me solve this problem, if we manage to overcome these last hurdles, we should build a statue for you here because man you deserve it :slight_smile:

Hope to hear from you and many many thanks for your help!

Dennis

Hi Dennis - the short answer is yes!

Can you give me an example of a printer model you have and what the presets would be?

Hey RBUDD,

The printer I would like to test the script with is a Xerox Phaser 6180 MFP

And I would like it to print to paper tray 3 by default.

In the final version, the print queue will write to a Windows Following Me print system in which a user goes to the printer and receives their print after logging in to the actually printer with a username and password.

However, let’s concentrate on fine-tuning this script and we’ll give it a whirl on-site and test to see if all goes well :slight_smile:

Once again, thank you very much for your time and efforts, it is highly appreciated!

Kind regards,

Dennis

Hi Dennis,

The ‘follow-me’ print may cause issues with making it a single click installer.

These sort of systems need to identify who within the database actually printed so that jobs are pooled correctly for release buy the end user.

On a Windows PC within a Windows domain this is usually seamless as the logged in user has all the credentials when printing and the follow me system knows them. When you connect a Mac to a Windows print queue the first thing it usually asks if for your domain credentials. A script could prompt a user for these, or could be pre-populated - but this adds good deal a complication.

I’ve messaged you with a link to a standalone 6180 installer. If you think it will do the job we can look at the various steps used in this thread. However, if the end goal has to be that we integrate with the follow-me system i think it would be best to investigate that first.

Cheers
Richard

Hi Dennis,

Here are some details on how to package and deploy a printer driver using Applescript, I will use the Ricoh Aficio MP C6000 as an example.

First you will need to download the correct printer driver from the manufacturers website, making sure that it is compatible with the version of OS X your users are running. The download comes in the form of a .DMG file, when mounted you will find a .pkg file inside. In my example the .pkg file from Ricoh is:
Ricoh_PS_Printers_Vol2_EXP_LIO_Driver.pkg

Copy this file from the .DMG to your desktop.

Next open a new blank AppleScript project. From the menu bar select File > Save then change the ˜File Format’ option to ‘Script Bundle’ and save to your desktop. With the script still open in Script Editor choose View > Show Bundle Contents from the menu bar.

You will see a side panel open up in Script Editor with ˜Bundle Info’ at the top and ˜Resources’ below. Expand the ˜Scripts’ folder in the resources section then right click to create a new folder inside named ˜Driver’. Once created right click the ˜Driver’ folder and choose ˜Reveal in Finder’. The folder will open up in Finder, copy the .pkg driver package into the folder.

You should now be able to see the .pkg within the ˜Drivers’ folder from within Script Editor. Save the script again making sure to keep the file format as ˜Script Bundle’.

Now that we have the driver package bundled in or script we can write the code to run the installer. In order to make the script portable use the ˜path to me’ option and add the path the .pkg installer:


--Create a varible for the path to .pkg installer
set printerDriver to ((POSIX path of (path to me)) as text) & "Contents/Resources/Scripts/Driver/Ricoh_PS_Printers_Vol2_EXP_LIO_Driver.pkg"

--Install the driver
try
	do shell script "sudo installer -verboseR -pkg " & quoted form of printerDriver & " -target /" with administrator privileges
on error error_message number error_number
	display alert ("Cannot Install Driver") message error_message & (" Error number ") & error_number & "."
	return
end try

The try statement is useful as it will stop the script if the install fails.

If you add the code from my previous post you will have a script that can install the driver and then the printer queue. To keep the example consistent with installing this printer the code would look like this:


set portName to "Printer_01" --Do not uses spaces in port name.
set ipAddress to "10.1.1.243" --Substitue for IP address of your printer.
set genericPpdPath to "/Library/Printers/PPDs/Contents/Resources/RICOH Aficio MP C6000" --Path to Ricoh c6000 PPD installed by .pkg
set displayName to "Staff Room Printer" --Set a display name for the printer.

--Install printer
try
	do shell script "/usr/sbin/lpadmin -p " & quoted form of portName & " -E -v lpd://" & ipAddress & "/lp -P " & quoted form of genericPpdPath & " -D " & quoted form of displayName & " -o printer-is-shared=false" with administrator privileges
on error error_message number error_number
	display alert ("Failed to create print queue - Please consult your System Admin") ¬
		message error_message & (" Error number ") & error_number & "."
	return
end try

Awesome help once again RBUDD!

I am currently getting information on the exact printer they are using, so we can make an installer specifically for that printer.

Thanks a million for all your help - you are a lifesaver!

Kind regards,

Dennis

Hey RBUDD,

I sent you a mail with the exact printer model - for future user’s sake I’ll post it here as well :slight_smile:

It’s a Canon C5235i.

Hope to hear from you soon!

Kind regards

To whoever reads this - RBUDD is a print god!

He got everything to work for me, his knowledge about printers is beyond everything I ever saw in a mere mortal!

In all honesty, Richard has been a fantastic help and we solved the issue, many many thanks!!!