Thursday, September 24, 2009

Install files into user directories

The new LANrev Install Ease application has the ability to create packages that automatically adds files to all current users on your system.

Lets look at doing it the ol' fashioned way....

Using Iceberg makes this easy.  Either install files somewhere on your HD (like the user template located at /System/Library/User Template/English.lproj and inside there is the template of what gets copied to all new users. Lets say you want to install prefs for an application you are pushing out.  Install the pref file at /System/Library/User Template/English.lproj/Library/Preferences then create a text file script that will copy that to all your users.  Lets say the pref file is myapp.plist.

____ 8< snip ________


# get listing of /Users Directory
# and set template locaton

dirs=`ls /Users`
template="/System/Library/User Template/English.lprog"

# now do something for each entry

for dir in $dirs
     # exclude /Users/Shared
     if [ "$dirs" != "Shared" ]; then
     cp "$template/Library/Preferences/myapp.plist" "/Users/$dir/Library/Preferences"
     chown $dir:$dir "/Users/$dir/Library/Preferences/myapp.plist"
     chmod 700 "/Users/$dir/Library/Preferences/myapp.plist"

______ 8< snip _______

Take this script and make it a postflight script.  Iceberg will take care of naming it correctly and such for you.

Now, if you simply want to make a quick package to copy stuff you can do this....Make a new dummy package and put the item  you want to copy in the "Resources" section of Iceberg (Iceberg will add it to the Resources folder of your package for you).  Then do a postflight script  which is something like above...

____ 8< snip ________


# get listing of /Users Directory

dirs=`ls /Users`

# now do something for each entry

for dir in $dirs
     # exclude /Users/Shared
     if [ "$dirs" != "Shared" ]; then
     cp "$1/Contents/Resources/myapp.plist" "/Users/$dir/Library/Preferences"
     chown $dir:$dir "/Users/$dir/Library/Preferences/myapp.plist"
     chmod 700 "/Users/$dir/Library/Preferences/myapp.plist"
______ 8< snip _______

the $1 indicates the path to the script and then follow the path to the Resources folder.

The chown and chmod commands make sure the file has the correct owner and permissions.


Monday, September 14, 2009

-36 Errors with EZIP and 10.5.7 and 10.5.8

We were experiencing issues with clicking on files in a users home directory mounted via the AD plugin with EZIP 5.x running on Windows 2003 File Servers.  Upgrading EZIP to 6.x seems to take care of it (as noted in a KB Article on their support website.)  If you are seeing these errors, try to upgrade EZIP to the most recent version.

Sunday, September 13, 2009

DIY Centralized Printer Management

We currently use Windows servers as our backend.  With 10.4 we basically used MCX settings to push out printer management.  This was broken with 10.5.4 so we had to come up with a home brew solution.  We already use a PHP/SQL solution that controls our imaging solution, so adding printers to that was not that difficult.  In addition, we use GroupLogic ExtremeZ-IP software to dish out our file and printer shares.
No matter where you get your printer list from, you can use the following code to pull printer info, and process the changes.  We will be using the Widget from GroupLogic, they call it a "Zidget".  Contained in the Zidget is an application called "zidgethelper" which can process the URL's of the printer share and install it on the local computer.  If you copy this application, and put it in your /Applications directory, then you can use it to also process URL's from a webpage (this means you can have a web page with a map, and click on locations to install a printer from there...really cool). EZIP also downloads PPD files if needed from the server.
This script is a login script and does the following...
  1. Pulls down a printer list from a web server
  2. Pulls down default printer from a web server
  3. Looks for existing printer list, if none, make a blank
  4. Compare New printer list to Old printer list
  5. Remove any printers that need to be removed
  6. Add any printers that need to be added
  7. set the default for the logged in user
The beauty in this is that is will only add/remove printers that you specify, leaving user added printers alone.  If there are any problems, delete all printers and delete the file.  Once the script runs again, all printers will be re-added.  FYI, we pass several items to the login script.  Some of those items are the logged in user name, Platform UUID (for ByHost settings) and more.  You will see a reference to those variable at the end of the script.
__________ 8< snip ____________
# Check for exising printers.txt file, if none, make one
echo "Checking for org.lmsd.printers"
if [ ! -e $oldprinters ];then
echo "Creating"
touch $oldprinters
chown root:wheel $oldprinters
chmod 700 $oldprinters
# cleaning up and creating blank newprinters and defaultprinter files
rm -f /tmp/.newprinters
touch /tmp/.newprinters
rm -f /tmp/.newprinters
touch /tmp/.defaultprinter
# Now we have an existing existing printers.txt, check for server
echo "checking for server"
curl -s --fail -o /tmp/.newprinters $printers_url
if [ $RESULT -eq 6 ] ; then
echo "Server not availble or Network Interfaces off"
if [ $RESULT -eq 22 ] ; then
echo "Server there, no printers file"
if [ $RESULT -eq 0 ] ; then
echo "Found Server and File moving forward"
# We found server, continue with pulling printers and remove existing
# LPD printers and install new ones using ZidgetHelper
echo "Checking for changed printers"
        touch /tmp/.newprinters
diff -q $oldprinters $newprinters >/dev/null
if [ $RESULT -ne 0 ]; then
echo "Assigned printers have changed, setting up new printers"
echo "removing printers no longer assigned"
remove=`diff -w $oldprinters $newprinters | awk '/
for printer in $remove
lpadmin -x $printer
echo "adding newly assigned printers"
add=`diff -w $oldprinters $newprinters | awk '/>/ {print $2}'`
for printer in $add
/Library/Widgets/Zidget.wdgt/ShellScripts/ $printer
mv -f $newprinters $oldprinters
chown root:wheel $oldprinters
chmod 700 $oldprinters
rm -f /tmp/.defaultprinter
else echo "Assigned printers are the same"
echo "Setting default printer if needed"
curl -s --fail -o /tmp/.defaultprinter $default_url
if [ -e /tmp/.defaultprinter ];then
echo "Setting default printer to `cat /tmp/.defaultprinter` for ${1}"
su ${1} -l -c "touch /Users/${1}/Library/Preferences/ByHost/$PLATFORM_UUID.plist"
su ${1} -l -c "defaults -currentHost write UseLastPrinterAsCurrentPrinter -bool False"
su ${1} -l -c "lpoptions -d `cat /tmp/.defaultprinter` >/dev/null"
rm -f /tmp/.defaultprinter
exit 0

Lightspeed and OpenBook software

Lightspeed TTC+ has a feature to block any traffic that resembles proxied traffic.  For some reason, this applies to the OpenBook software and the connection it needs back to the OpenBook network.  Since it is blocked at the TTC+ level, you receive NO block messages.  You can manually browse the URLS's in a browser, but the application will still not function.  You need to add the IP address of the OpenBook network in your bypass sections of the TTC+ configuration.  This is the only way at the moment to make this work.

Dual Boot Backup and Restore

One of the first (and my opinion still the best) tools for backing up and restoring a Windows partition on a dual boot Mac (mostly referred to as Boot Camp) is a utility called Winclone.

With this utility you boot into your OSX partition, launch the utility use the SHRINK VOLUME menu tool to make the Windows partition as small as possible then back up the partition your OSX volume or external HD.  You can then reformat, or remove the Boot Camp partition and create a new one of different size.  You can then restore using the utility as well.  One nice feature, is the ability to restore the Windows partition without needing the Winclone software.  This is called the "self extract" feature and is great if you wish to distribute the Windows backup to other computers.  Copy the backup file to the remote computer.  Create the Windows partition, either by remote control and using the Boot Camp Utility or issuing the correct command line commands, then run the following...

/path/to/backup.winclone/winclone.perl -self-extract

There is an excellent PDF at the Winclone site that expands upon this.

Modifying Print Queue Behavior

Somewhere after 10.5.4 Apple modified the way in which print queues can be controlled.  It requires you to either put users/groups into the lpadmin group, or you need to edit the /etc/cups/cupsd.conf file.  One of the things we need to do is allow a valid user to operate a print queue (pause, resume, cancel jobs) but not modify or add/delete print queues.  You can edit a section of of the cupsd.conf file to achieve this..

1. Make a backup of your existing cupsd.conf file

sudo cp /etc/cups/cupsd.conf /etc/cups/cupsd.bak

2. Edit the follow section of the original using your favorite text editor of choice.

Edit the lines below that entry from:
   AuthType Default
   Require user @AUTHKEY(system.print.admin) @admin @lpadmin
   Order deny,allow

   #AuthType Default
   #Require user @AUTHKEY(system.print.admin) @admin @lpadmin
   Require valid-user
   Order deny,allow

3. Stop and restart the cups service (or reboot).

killall -HUP cupsd

Thats it.  You can then distribute that modified cupsd.conf file as you would any other file.  Make sure you use a postflight script to stop/restart the cups service, or your changes wont take affect until a restart.

Compare secure values in a script

I am always leery of putting a password into a script in case someone gets into the script and can see the text.  One thing you can do is read a value and encrypt it with openssl (included with OSX).  This allows you to encrypt the results of a command and then you can compare that encrypted result with a known good encrypted result.

echo "123456abc" | openssl dgst -sha1

this results in the following


Now, if you run the above command ahead of time on a known good value, you can put this all in a script like the following..
_______ 8< snip ____________
test=`echo "123456abc" | openssl dgst -sha1`
if [ "$test" = "$good" ]; then
echo "they match"
echo "they don't match"

Some image based things

Some things you might want to consider doing for your these as sudo

# Hide account from login Window
defaults write /Library/Preferences/  HiddenUsersList  -array-add accountsname

# Locking down SSH to a given username
echo "AllowUsers username" > /etc/sshd_config
echo "PermitRootLogin no" >> /etc/sshd_config
echo "PermitEmptyPasswords no" >> /etc/sshd_config

# Enabling Shortname in Connect to Server dialog
defaults write /Library/Preferences/ UseDefaultName -bool NO
defaults write /Library/Preferences/ UseShortName -bool YES

# Disabling Computer-Computer network creation without admin rights
/usr/libexec/airportd en1 -ibss_admin 1

# Enabling DVD Set Region First Time - Anyone
/usr/bin/security authorizationdb write system.device.dvd.setregion.initial allow

# Disable iWeb upsale dialog
defaults write /Users/username/Library/Preferences/ dismissDotMacUpsellWindow -bool True

# Remove sidebar settings and keychain from template account

rm /Users/username/Library/Preferences/
rm /Users/username/Library/Keychains/login.keychain

Converting DV video for Tricaster on OSX

You can use use Mpeg Streamclip to convert DV video files for use on NewTek Tricaster.  Newtek is very annoying in that they do NOT recognize Quicktime format files so you have to convert to AVI format.  Quicktime movies and AVI movies are just containers.  The important part is the format of the audio and video inside those containers.

Using Mpeg Streamclip you can install the included "Save as AVI" Quicktime component and make sure the video is in DV format and the Audio is in MP3 format.  You can then put the resulting AVI file on a thumb drive or external hard drive, quit the Tricaster interface and copy the file to the media clips folder.  Once you re-launch the Tricaster interface you can then load up the video in the "VCR" (or I will assume a DDR in the Video Toaster product) for playback.

Converting from Tricaster naitive format is pretty much impossible.  You need to obtain the video CODEC from the NewTek website and install it on your Windows workstation.  You can then open the file in Windows Media Player to view it...but you will have to find utilities to then convert it to a format you can play elsewhere.  NewTek does NOT make a Quicktime component to support their format, which in my opinion is a mistake on their part.  The prevents you from sourcing a video file on a Tricaster or Video Toaster and using it in Final Cut Pro on OSX.  Very short sighted on NewTeks behalf if you ask me.  I believe you now can use MPEG2 as a format, but in my opinion...too little...too late.

Audio/Video conversion tools for OSX

Some wonderful OSX tools to manipulate and convert audio/video.

Audacity - Open Source audio editor
Gimp - Open Source graphic editor
FFmpegX - GUI front end to OSX version of ffmpeg (Video Conversion)
Mpeg Streamclip - Converter (supports many formats)
VLC - Media player that can also transcode and convert in many formats
Perian - Quicktime component that allows Quicktime to play many formats
Handbrake - Rip DVD's to MP4, directly into iPod/iPhone formats as well as others.

All the above utilities are free.  You can download them and use them to perform many tasks.  Mpeg Streamclip also includes a "Save as AVI" quicktime component.  I use all these utilities on a regular basis when I need to convert video into different formats for our video needs.  The only other utility we use is Sorenson Squeeze to convert video to FLASH format for the website.  It isn't pretty or quick, but it does the job.

Creating packages and installing

There are many great ways to easily create packages.  The 2 that I mainly use are InstallEase and Iceberg.

InstallEase is a snapshot package creator that allows you to snapshot your machine.  You can then install, run, modify and configure your application.  Once finished you run InstallEase again and take a second snapshot of your machine.  You are then presented with what has changed.

You can now make changes or add/remove items from this list and proceed to make a package.  You can also have InstallEase create a DMG with all the files in their folder heiarchy, create an uninstaller and create a project folder and file for Iceberg.  It also copies all the source files to source folder for the Iceberg project.

The uninstaller simply is a dummy package with a script that uninstalls the items installed with your package.

InstallEase can also create an "uninstaller" for any package you feed it.  This uninstaller will only delete files installed, and not undo changed made to your system by script or other installer plug-ins.

In Iceberg, you can now make more changes and do things like add/modify license agreements and add different scripts (prefight, postflight etc etc).

Package making is an art form in that you need to understand what goes where, what you need, and what you don't need.  You also need to dig a little deeper into the guts of what makes OSX do what it does.  Simple applications are easy, but repackaging applications like Adobe CS3 take many attempts and testing.

Always have a test machine with your current image on it to install.  This allows you to install and test your applications in the same environment you will be deploying to.

Also a little tip.  We keep our packages on a network volume and you can NOT install packages from the GUI installer if they are located on a network volume without dragging it down to your local HD first, or putting everything on a disk image.  The way around this is to mount your network volume, then open the terminal and type

sudo installer -package /path/to/package -target /

This will run the installer with admin priv's and install on the root of the HD.  It works directly off of a network volume and is quicker (in my opinion) than the GUI installer.

Repackage Xcode for distribution

The Xcode distribution from Apple consists of an installer metapackage and all the sub-packages are stored in a directory called "packages" located at the same level as the installer metapackage.

No existing tools (Iceberg etc..) will allow you to use this metapackage, so in order to distribute as an installer (to be installed by end users or pushed out via utilities like ARD or LANrev) you need to create a dummy package with a postflight script that runs the terminal installer program and include the Xcode installer metapackage and package folder in the package resources.  Iceberg is a great utility to create packages and this can be done easily.  Here is the postflight script.

installer -package "$1/Contents/Resources/XcodeTools.mpkg" -target /

Notice the "$1/Contents/Resources" refers to the path to the packages Resources folder.   This is a great trick for any utility commands that you wish to install with a package and run as part of a script.

Removing First run warnings from downloaded applications

Apple has metadata that trigger the OS when you are running applications that were downloaded from the internet.  To remove this warning use the following terminal command

xattr -d /path/to/application

Using Terminal to turn Airport off

Here is a little code snippet to use terminal to turn the Airport on and off

/System/Library/CoreServices/RemoteManagement/ -setnetworkserviceenabled "AirPort" off

Running an Application that requires a mounted Network Share

Here is an example of how to script the mounting of a network share, and launching an application.  You can then use a utility like Platypus to create an application.  In this case, the actual KIDPIX application folder is copied inside the application bundle created by Platypus.  This script mounts the share in the background and it does not appear in the finder.  It then waits for the program KIDPIX to quit and then unmounts the share.  Notice the $1/Contents/Resources which references the KIDPIX files located inside the application bundle.

_______ 8< snip ________


echo "KIDPIX: Creating mount point"
mkdir /Volumes/KIDPIX4

echo "KIDPIX: mounting AFP server"
mount_afp -o nobrowse afp://username:password@server/KIDPIX4 /Volumes/KIDPIX4

echo "KIDPIX: Launching Application"
open "$1/Contents/Resources/Kid Pix 4 Network/Kid Pix Deluxe 4"

echo "Sleeping so Program can Launch"
sleep 10

echo "KIDPIX: Waiting for program exit"
while ps wwax | grep "[K]id Pix Deluxe 4" >/dev/null; do
sleep 5

echo "KIDPIX: umount volume"
umount /Volumes/KIDPIX4

echo "KIDPIX: Remove mount point"
rm -d /Volumes/KIDPIX4

echo "KIDPIX: Always exit 0"
exit 0

Testing for Machine Architecture

I little script to run if on PPC or Intel then do something....

_______ 8< snip ______________


# check for hardware arch
echo "Hardware Type is $type"

#Install appropriate package
# If result is Intel
if [ $type = "i386" ]; then
     # Put what you want to do here
     echo "You are running on Intel
# If PPC
     if [ $type = "ppc" ]; then
          # Put what you want to do here
          echo "You are runnin on PPC"

# Always exit cleanly
exit 0

Enable and Disable the built in iSight.

This can be accomplished by changing the permissions of 2 files.  It can be done by removing rwx for all users (ie chmod a-rwk) on the following



This has been tested on OSX 10.5.7 (MacBook) and OSX 10.5.8 (MacBook Pro)

A DMG with the completed script and application can be found here.

The script should go somewhere in your path (/usr/sbin or such) and have the appropriate permissions and owner.  You can then run it from a utility such as ARD or LANrev, or from a SSH login by issueing the command with the appropriate option use -h or -help for info.

The Application has a copy of the isighter script contained in it's bundle.  The actual Applescript is an example of how to run a terminal command with admin privileges and can be found here.


Hey there!

Welcome to my blog.  I will attempt to blog on snippets of code and other utilities that I use day in and day out to do my job.  I don't claim to be an expert but I do believe that you should share information that has helped you so that others may find it if they need help.  Everything contained in here are snippets of code that I have seen or found on the internet, as well as from the fantastic individuals on the MacEnterprise forum.  If you are supporting OSX in any larger scale network, you should check out this fine resource at