Add a user to the admin group via command line 3.0

Posted January 14, 2010 by GregN
Categories: DirectoryService, OS X

One of the more visited articles on this site is several years old – this one on adding a user to the local admin group.

I thought I should update that information since it is somewhat out of date. Apple’s preferred and recommended way to add a user to the local admin group is to use dseditgroup, like so:


/usr/sbin/dseditgroup -o edit -a gneagle -t user admin

This -a(dds) “gneagle”, which is an object of -t(ype) “user”, to the group “admin”.

To delete a user from the local admin group:


/usr/sbin/dseditgroup -o edit -d gneagle -t user admin

You can also use dseditgroup on a network directory service if you have admin credentials for the directory server:


dseditgroup -o edit -n /LDAPv3/ldap.company.com -u dsadminusername -p -a gneagle -t user group_on_network_directory

This will prompt you for the dsadminusername’s password interactively. You can include the dsadminuser’s password like so:


dseditgroup -o edit -n /LDAPv3/ldap.company.com -u dsadminusername -P dsadminuserpassword -a gneagle -t user group_on_network_directory

dseditgroup can do many other things, like create and delete groups, add nested groups to an existing group, and check membership of a given user for a given group.

man dseditgroup for more info.

Firefox global extensions

Posted January 13, 2010 by GregN
Categories: Deployment, OS X

firefox icon
On the MacEnterprise list recently, there was a discussion about installing Firefox extensions.

Specifically, the originator of the thread wanted to install a PDF plugin for Firefox so all users of a machine could use it without having to manually install it.

I had looked at this issue a while back, and didn’t find a satisfactory solution.

Here were the options I saw:

  1. Just let users install it themselves. Since by default, Firefox extensions install in their Firefox profile in their home directory, this is possible. But the user has to know to look for the extension, download it and install it. Plus, as a policy, you may not want to encourage users to download and install software themselves.
  2. Follow the instructions in this mozillaZine article to install a global extension. This installs the extension inside the Firefox application bundle and makes it available to all users. But each time a new version of Firefox is released, you’ll have to do this again, which quickly becomes a pain. Additionally, in my testing, this method doesn’t actually make the extension directly available; instead, on the next launch the user is prompted to install it.

Neither option appealed to me, but since the first was no more work for me, I went with that. But in the MacEnterprise discussion this Mozilla link was brought up, which describes a new option for Firefox 3 and later.

Basically, you just need to copy the extension to


/Library/Application Support/Mozilla/Extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}

and it becomes available to all users of the machine. Since it’s not in the Firefox application bundle, it can survive updates to the Firefox application.

I found that instead of copying the .xpi file there, I got better results by first installing the extension into my user profile, then copying the installed extension to the directory above. The PDF plugin installs in a directory named “colesbury@gmail.com”, so the process looks something like this:


cd /Users/gneagle/Library/Application\ Support/Firefox/Profiles/cuak0rwz.default/extensions
cp -R colesbury@gmail.com /Library/Application\ Support/Mozilla/Extensions/\{ec8030f7-c20a-464f-9b0e-13a3a9e97384\}/

The extension is now available to all users, and the users are NOT prompted to install it — it just works. Even better, you can package it up and deliver it to all your machines via radmind, ARD, Casper, etc.

Firefox default settings revisited

Posted January 11, 2010 by GregN
Categories: Deployment, OS X

firefox iconOne of the most-visited articles I’ve written here is one on managing Firefox default settings. I continue to get questions about this, so I thought it was time to revisit the issue. Read the rest of this post »

Partial installs of Final Cut Studio 3

Posted January 8, 2010 by GregN
Categories: Deployment, General, OS X

When doing unattended installs of suites of software, sometimes you want to install something other than the default set of applications and add-ons. For example, if you are doing a remote/unattended install of iLife ‘09, maybe you want to install only iDVD, iPhoto, and iMovie, and leave off iWeb and GarageBand. Read the rest of this post »

Silent installs for Acrobat Pro 9 updates

Posted January 6, 2010 by GregN
Categories: Deployment, General, OS X, Python

Silent installs of Adobe products are a bane of an OS X administrator’s existence. However, there are some officially supported methods to do silent installs of CS3/CS4 apps, and even to install updates to those apps.

Some links:

CS3 Deployment
CS4 Manual Deployment
CS4 Enterprise Deployment Toolkit

But updates to Acrobat Pro 9 are in a completely different format than all other Adobe installers/updaters and can’t be silently installed with any of the supported methods.

I started tearing apart the patching app on one of the update disk images and discovered it was running some shell and Python scripts to do the actual patching. That got the wheels turning…

The result: a Python script you can use to silently install all of the (so far) released updates to Acrobat Pro 9.

This script skips all of the process checking done by the original patching app, so it’s best to run it when no-one is logged in.

You could use this script via SSH or ARD to install the updates:

Install the script itself somewhere on the target machine. Copy the needed disk images to the target machine. Install each update in order, something like this:


./updateAcrobatNine.py /path/to/AcroProUpd910_all.dmg
./updateAcrobatNine.py /path/to/AcroProUpd911_all.dmg
./updateAcrobatNine.py /path/to/AcroProUpd912_all.dmg
./updateAcrobatNine.py /path/to/AcroProUpd913_all.dmg
./updateAcrobatNine.py /path/to/AcroProUpd920_all.dmg

Here’s some output from an install session:


root# ./updateAcrobatNine.py AcroProUpd910_all.dmg
Mounting disk image AcroProUpd910_all.dmg
Searching for Adobe Acrobat Pro.app
Getting info on currently installed applications...
Updating Adobe Acrobat Pro.app
Updater log at /var/root/Library/Logs/Adobe/Acrobat/Acrobat 9 Pro Patch0.log
Patching Adobe Acrobat Pro.app complete.
Searching for Acrobat Distiller.app
Updating Acrobat Distiller.app
Updater log at /var/root/Library/Logs/Adobe/Acrobat/Acrobat 9 Pro Patch1.log
Patching Acrobat Distiller.app complete.
Searching for Acrobat Uninstaller.app
Updating Acrobat Uninstaller.app
Updater log at /var/root/Library/Logs/Adobe/Acrobat/Acrobat 9 Pro Patch2.log
Patching Acrobat Uninstaller.app complete.
Done.

Enjoy.

ADDENDUM:

If you do install Acrobat Pro 9 updates, unattended uninstalls using the methods from the Adobe Enterprise Deployment Toolkit now fail, because Adobe Setup no longer thinks Acrobat Pro 9 is installed and gets very confused. Manual uninstalls using the uninstaller in /Applications/Utilities/Adobe Installers still work, though. Grrrr….

Apple Software Update wishes

Posted October 13, 2009 by GregN
Categories: Commentary, Deployment, MCX, OS X

Software UpdateSince we’ve examined some ways to script around Software Update’s limitations, I thought maybe now would be a good time to describe changes I’d like to see to Apple’s Software Update so we don’t have to hack at it…
Read the rest of this post »

Apple Software Update options

Posted October 12, 2009 by GregN
Categories: Deployment, General, OS X

Software UpdateAt work, I’ve been working on a solution for handling Apple Software Updates for non-administrative users. Each approach I’ve tried has serious obstacles. Here’s a brief history of what I’ve tried and what worked and what didn’t.
Read the rest of this post »

Adobe Product Codes

Posted October 8, 2009 by GregN
Categories: Deployment, OS X

While digging into the Adobe install process, I needed to be able to translate from “AdobeCodes” like “{27B54140-8302-4B5D-83DD-AEE4B18BC7A4}” to product names like “Adobe Encore CS4″ and the installer payload name like “AdobeEncore4All”.

I ended up writing a Python script to crawl through the payloads directory of Adobe install media to generate a table. The script is below, and called like:

python adobeparser.py /path/to/payloads

It’s probably not generally useful, though I include it just for completeness…


#!/usr/bin/env python
# encoding: utf-8
"""
adobeparser.py

Created by Greg Neagle on 2009-10-07.
"""

import sys
import os
import optparse
from xml.dom import minidom

def parseAdobeProxyXML(filename):
    payloadinfo = {}
    dom = minidom.parse(filename)
    installer_properties = dom.getElementsByTagName("InstallerProperties")
    if installer_properties:
        properties = installer_properties[0].getElementsByTagName("Property")
        if properties:
            for prop in properties:
                if 'name' in prop.attributes.keys():
                    propertyname = prop.attributes['name'].value
                    propertyvalue = ""
                    for node in prop.childNodes:
                        propertyvalue += node.nodeValue
                    payloadinfo[propertyname] = propertyvalue

    return payloadinfo

def analyzePayloads(dirname):
    payloads = []
    dirname = dirname.rstrip("/")
    if dirname.endswith('payloads'):
        for payloaditem in os.listdir(dirname):
            payloaditempath = os.path.join(dirname, payloaditem)
            if os.path.isdir(payloaditempath):
                for item in os.listdir(payloaditempath):
                    if item.endswith(".proxy.xml"):
                        proxyxmlfile = os.path.join(payloaditempath, item)
                        payloadinfo = parseAdobeProxyXML(proxyxmlfile)
                        payloadinfo['ComponentName'] = payloaditem
                        if payloadinfo:
                            payloads.append(payloadinfo)
                        break

    return payloads

def main():
    p = optparse.OptionParser()
    options, arguments = p.parse_args()
    if arguments:
        payloads = analyzePayloads(arguments[0])
        print "Adobe Code\tName\tVersion"
        for payload in payloads:
            print "%s\t%s\t%s\t%s" % (payload['AdobeCode'], payload['ProductName'], payload['ProductVersion'], payload['ComponentName'])

if __name__ == '__main__':
	main()

I ran this script against the payloads folder on the Adobe CS4 Master Collection installation media. I then sorted the output by AdobeCode and added a header line, and here is the result: a tab-delimited list of AdobeCodes, ProductNames, ProductVersions, and PayloadNames.

I hope this list is useful to someone other than me! Combine this with the info here and you can get a pretty good idea of everything that’s installed.

More Adobe Enterprise Deployment Toolkit FAIL

Posted October 7, 2009 by GregN
Categories: Deployment, General, OS X

This post will act as a running log of today’s struggles with the CS4 Deployment Toolkit. This post was updated several times today, so if you read it earlier today, there may be new stuff added….

  • Start with the install media for Adobe CS4 Master Collection.
  • Run the CS4 Deployment Toolkit app and create a “package” that installs only Flash, Dreamweaver, Fireworks, and Contribute.
  • Move the package and install media files to the test machine
  • Run the AdobeUberInstaller

Result?

Flash, Dreamweaver, Fireworks and Contribute are installed. But…

So are:
After Effects, Encore, Premiere Pro, and Soundbooth. Or are they?

The application folders are there, but inside: broken apps.

Sheesh.
Read the rest of this post »

Adobe Enterprise Deployment Toolkit versus disk images…

Posted October 6, 2009 by GregN
Categories: Deployment, OS X

After getting lots of suggestions, and spending a few days tearing apart the JavaScript files that are part of the Adobe setup/install process, I have some progress to report on the task of getting Adobe Enterprise Deployment Toolkit “packages” to work from disk images.
Read the rest of this post »