Fri - February 10, 2006

Nothing to see here, move along...


I haven't posted here in over a year. May I direct your attention here , instead?


Posted at 06:50 PM     Read More  


Sun - January 2, 2005

Updating Dock icons


In one-to-one deployments, you may not have direct control of a user's Dock - especially if you do not use Macintosh Manager becuase you are using a non-Apple directory. When you update applications on a user's machine, this sometimes breaks Dock items. We faced this when updating machines from Office v.X to Office 2004. I wrote a script that ran at login that changed any existing Office v.X Dock icons into their corresponding Office 2004 icons.

The script is posted here in a quick tip I submitted to MacEnterprise.org. It's meant to be run by my LoginLauncher app (current version) (older version). I repost the script here as well:

#!/usr/bin/perl
# This script edits com.apple.dock.plist
# to remove Office X entries and replace them with
# Office 2004 entries.
#
#
# by Greg Neagle Jul 2004

$homedir = $ENV{'HOME'};

# is Office 2004 installed?
if (-d "/Applications/Microsoft Office 2004") {
   # has this script done its thing?
   if (!(-e "$homedir/Library/Preferences/com.apple.dock.plist.officex")) {
      open DOCKPREFS, "$homedir/Library/Preferences/com.apple.dock.plist"
         or die ("Cannot open $homedir/Library/Preferences/com.apple.dock.plist");
      open DOCKOUTPUT, ">$homedir/Library/Preferences/com.apple.dock.plist.new"
         or die ("Cannot open $homedir/Library/Preferences/com.apple.dock.plist.new for output");
      until (eof DOCKPREFS) {
         $text = readline(DOCKPREFS);
         print DOCKOUTPUT "$text";
         if ($text =~ "file-data") {
            $dictBlock = "";
            $officeAppFound = 0;
            while(!($text =~ "")) {
               $text = readline(DOCKPREFS);
               if ($text =~ "/Applications/Microsoft Office X/") {
                  # replace the path
                  $text =~ s/Microsoft Office X/Microsoft Office 2004/;
                  $officeAppFound = 1;
               }
               $dictBlock = $dictBlock . $text;
            }
            if ($officeAppFound) {
               # get rid of the _CFURLAliasData block
               $dictBlock =~ s|_CFURLAliasData.*||s
            }
            print DOCKOUTPUT "$dictBlock";
         }
      }
      close (DOCKOUTPUT);
      close (DOCKPREFS);

      #rename our files
      `mv $homedir/Library/Preferences/com.apple.dock.plist $homedir/Library/Preferences/com.apple.dock.plist.officex` ;
      `mv $homedir/Library/Preferences/com.apple.dock.plist.new $homedir/Library/Preferences/com.apple.dock.plist` ;

      # restart the Dock
      `killall Dock`;
   }
}
#END



The basic concepts here could be used to update other icons. The key points are that the path to the item is modified, and that the "CFURLAliasData" is removed. This needs to be removed because it is an alias that points to the old file item. The first time the user clicks on the icon after the update, this data is regenerated based on the pathname.

Posted at 09:15 AM     Read More  

Using niutil to manage user accounts


Let's say you've assumed responsibility for managing a new group of Mac OS X machines. These machines were previously set up by a variety of people, and have different local admin account names and passwords. To simplify your life, you want to standardize the local admin account name and password, and additionally, create a way to update the local admin password periodically.

Here's an article I wrote for MacEnterprise.org that shows you one way to change the name, home directory and password for the admin account on your managed machines using a Perl script and nituil.

Posted at 09:00 AM     Read More  


Thu - December 30, 2004

Update to "Globally launching items at login"



Here's an article I did for MacEnterprise.org on launching items at login for all users of a machine. It's sort of a follow-up and expansion of this article. In the new article, I replace the AppleScript applet with a bundle-based application, and demonstrate a whole bunch of techniques of interest to Mac systems administrators.

Posted at 07:04 PM     Read More  


Tue - June 15, 2004

Screensaver over loginwindow


Apple seems to have missed a bit of functionality with their screensaver: when a Mac is sitting at the loginwindow, the screen saver never comes on. If you have a Mac sitting at the loginwindow for many hours a day, and you do not have the Mac set to dim the screen after a short time, you could begin to burn-in the loginwindow's image into the screen!
There may be other reasons you need a screensaver to run at login. Whatever those might be, there's a fairly simple solution.

In Mac OS X 10.0-10.2.8, it was difficult if not impossible to run Apple's screensaver over the login window. Several applications were written to act as psuedo-screen savers: Andrew Mortenson's ScreenPreserver.app and Penn State's PSU Screen Saver are examples. Some people even used the University of Michigan's RSUG's iHook for this.

There were several disadvantages to these apps. Among them:

• After the psuedo-screen saver went away, the logonwindow was not restored as the active application, forcing the user to first click in the window to make in active before they could start entering their username/password.

• Most of these applications did not correctly handle multiple monitors: they would protect the main screen, but any additional monitors would maintain the default Aqua Blue image forever.

• One of these was too sensitive to events - when a Wacom tablet was attached to a machine, the psuedo-screensaver would kick in, then immediately abort, having received some event from the tablet driver. As it happened - the machines that had Wacom tablets were among those that most needed the screensaver to run over the login window!

• They did not behave exactly like the built-in Mac OS screensaver, leading to a small amount of user confusion.

Now with Mac OS X 10.3, it is possible to run Apple's screensaver over the loginwindow. It behaves exactly as one expects. You'll need to install a script that runs the screensaver, and you'll need cron to call it periodically. Here's the script I use (note that no lines should be wrapped - be careful with the line beginning "idleTime="):

#!/bin/sh

# define the path to the screen saver engine
launchPath="/System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resources/ScreenSaverEngine.app"

# check to see if a user is logged into the console
loggedInUser=`/usr/bin/who | /usr/bin/grep console | /usr/bin/cut -d " " -f 1`

if [ "$loggedInUser" = "" ]; then
   # no one is logged in
   # but first check to see if the screen saver is already running!
   procList=`/bin/ps -auxwww | /usr/bin/grep -c "$launchPath"`

   if [ $procList -lt  2 ]; then
      # the screen saver is not already running, let's launch it,
      # but only if the system has been idle at least 5 minutes

      #get the system idle time in seconds
      idleTime=`/usr/sbin/ioreg -c IOHIDSystem | /usr/bin/perl -ane 'if (/Idle/) {$idle=int((pop @F)/1000000000); print $idle,"\n"; last}'`
                
      if [ $idleTime -gt 300 ]; then
         /usr/bin/open "$launchPath"
      fi
   fi
fi

exit 0

Make sure the script is executable.

I have a system cron task that calls this script every 15 minutes. So when a user logs out, the screen saver will start between 5 and 20 minutes after they log out; depending on when they log out.

The screensaver module that will run will be either the default store in the Engine Defaults.plist (see this entry) or the module saved as part of root's preferences (/var/root/Library/Preferences/ByHost/com.apple.screensaver.<mac layer address>.plist). Unless you are running another script to help you manage ByHost preferences, the easiest way to set this preference for all the machines you manage is to edit the "Engine Defaults.plist" (again see this for details) and make it part of your image, or use radmind to manage it.

Note that there is no need to enable the root account to set things up. Everything can be done with sudo from an admin account.

Thanks to this tip from Mac OS X Hints , and this discussion for the last pieces of the puzzle.

(Update 10/9/04)
I've been asked for a little more detail on adding this to cron, so here is one solution:

Login as an administrator, open /Applications/Utilities/Terminal.app, and type

sudo pico -w /etc/crontab

Add the three lines you see at the bottom of this example in red:

# /etc/crontab
SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
HOME=/var/log
#
#minute hour mday month wday who command
#
#*/5 * * * * root /usr/libexec/atrun
#
# Run daily/weekly/monthly jobs.
15 3 * * * root periodic daily
30 4 * * 6 root periodic weekly
30 5 1 * * root periodic monthly
#
# Check to see if we need to run the screen saver over the login window
*/15 * * * * root /path/to/run_screensaver.sh

Replace "/path/to/run_screensaver.sh" with the path to your script. (You should consider putting your management scripts in one location -- a folder named after your organization in the /Library folder would be a good choice.) Type Control-O to save, and Control-X to exit the pico editor.

Make sure the script has the executable bit set:

sudo chmod a+x /path/to/run_screensaver.sh

---

One more note:

This script uses the output of /usr/bin/who to determine if no-one is logged in via the GUI. If no-one, is we launch the screensaver. This arrangement is OK if "Fast User Switching" is off, but if it's on, the output of /usr/bin/who is different and the screensaver will never activate. Since Fast User Switching is off in our environment, I haven't had a need to figure out how to make it work if it's on. Email me if you need this functionality and I'll see if I can figure it out.

----

(Update 12/1/04)
Christian Pagé writes:

"For this to work with FUS, replace

loggedInUser=`/usr/bin/who | /usr/bin/grep console | /usr/bin/cut -d " " -f 1`

with

loggedInUser=`/bin/ls -l /dev/console | awk '{print $3}' | fgrep -v root`

This works only if you never login as root on the console."

I've done a little testing, and this seems to work. Basically, /dev/console is owned by the currently logged-in user, or by root if no user is logged in. (Thus Christian's caveat).
So if you need this to work in an environment with Fast User Switching on, give this modification a try.

Posted at 07:36 PM     Read More  


Sat - January 17, 2004

10.3.2 auto proxy configuration


Mac OS X 10.3.2 adds a feature to the Proxies tab of the Network Preferences Pane. This allows you to specify a URL to automatically configure proxies. This URL points to a "PAC" (Proxy Auto Configuration") file. These files are traditionally used Netscape and IE for Windows to configure their proxies. Now that this feature has been added to Mac OS X, Mac OS X applications can take advantage of this feature.

Here's how the configuration option looks:



Currently, it appears that only Safari is aware of this feature, but this was the final hurdle that allowed us to use Safari at Disney. Prior to 10.2.3, Safari had problems navigating our proxies: you could configure Safari to connect to web sites inside our proxy or outside our proxy, but not both simultaneously. Now it is possible to use Safari as a main browser at Disney.

To implement this, we needed not only to update machines to Mac OS X 10.3.2, but also we needed to push out a modification to the Network configurations for each machine so they would use the autoproxy URL.
Network configurations are stored in /Library/Preferences/SystemConfiguration/preferences.plist, or if you've upgraded from Jaguar and have made no changes to your Network configuration, the OS will still reference the "old" location of this data: /private/var/db/SystemConfiguration/preferences.xml.
We do not manage this file with radmind as it varies too much from machine to machine: it contains Network locations and entries for every possible Network interface: Built-in Ethernet, Modem, Airport, even IrDA. So instead this file is part of our standard installed image, but then remains unmanaged. This makes it difficult to update if needed.
The solution was to write a script that edits the file and makes the required changes. This script is then called as part of a custom startup item. The script must parse through the /Library/Preferences/SystemConfiguration/preferences.plist and add the autoproxy configuration info in the correct places. This is no small task. Again, the file can contain multiple network locations and multiple network interfaces. What I decided to do was look for existing proxy information that was Disney-related and make my additions there. That way I could be reasonably certain I was making my additions in the right place. We can be reasonably certain there is existing Disney-related proxy info in the Network configuration or Internet Explorer would not be functional.

Here's the script, though iBlog tends to mangle its formatting, so I've attached a "clean" version as well.

#!/usr/bin/perl

# This script adds the autoProxyConfig information to the Network configuration located at
# /Library/Preferences/SystemConfiguration/preferences.plist
# which is a complicated plist file.
#
# This allows Safari to work in our environment as of OS X 10.3.2.
# If this script did not add the autoProxyConfig info, we'd have to visit each machine one by one.
#
# by Greg Neagle Dec 2003

# change these as needed for your use
$localProxyDomain = ".disney.com";
$autoProxyURL = "http://fawww/auto.proxy";

# if the file /Library/Preferences/SystemConfiguration/.FAautoProxyUpdated exists
# then this script has already done its job and can exit
if (!(-e "/Library/Preferences/SystemConfiguration/.FAautoProxyUpdated")) {

        # if this machine was upgraded from 10.2, it may have the SystemConfiguration preferences in the "old" location
        if (!(-e "/Library/Preferences/SystemConfiguration/preferences.plist")) {
                `cp /private/var/db/SystemConfiguration/preferences.xml /Library/Preferences/SystemConfiguration/preferences.plist` ;
        }

        open SCPREFS, "/Library/Preferences/SystemConfiguration/preferences.plist"
                or die ("Cannot open /Library/Preferences/SystemConfiguration/preferences.plist");

        open SCOUTPUT, ">/Library/Preferences/SystemConfiguration/preferences.new"
                or die ("Cannot open /Library/Preferences/SystemConfiguration/preferences.new for output");

        until (eof SCPREFS) {
                $text = readline(SCPREFS);
                print SCOUTPUT "$text";
                if ($text =~ "<key>Proxies</key>") {
                        # we found a Proxies key
                        $text = readline(SCPREFS);
                        print SCOUTPUT "$text";
                        if ($text =~ "<dict>") {
                                # this line better be the start of a <dict> block
                                $foundLocalProxies = 0;
                                $foundAutoProxies = 0;
                                while (!($text =~ "</dict>")) {
                                        $text = readline(SCPREFS);
                                        if ($text =~ $localProxyDomain) {
                                                $foundLocalProxies = 1;
                                        }
                                        if ($text =~ "<key>ProxyAutoConfigEnable</key>") {
                                                $foundAutoProxies = 1;
                                        }
                                        if ($text =~ "</dict>") {
                                                # we're at the end of the dict block, we should
                                                # write out our additions if needed
                                                if ($foundLocalProxies && !($foundAutoProxies)) {
                                                        print SCOUTPUT "<key>ProxyAutoConfigEnable</key>\n";
                                                        print SCOUTPUT "<integer>1</integer>\n";
                                                        print SCOUTPUT "<key>ProxyAutoConfigURLString</key>\n";
                                                        print SCOUTPUT "<string>$autoProxyURL</string>\n";
                                                }
                                        }
                                        print SCOUTPUT "$text";
                                }
                                # we're at the end of a <dict> block
                        }
                }
        }

        close (SCOUTPUT);
        close (SCPREFS);

        # rename our files
        `mv /Library/Preferences/SystemConfiguration/preferences.plist /Library/Preferences/SystemConfiguration/preferences.old` ;
        `mv /Library/Preferences/SystemConfiguration/preferences.new /Library/Preferences/SystemConfiguration/preferences.plist` ;
        `touch /Library/Preferences/SystemConfiguration/.FAautoProxyUpdated`; #leave our mark

        # reselect the current location so the OS will read our changes
# first we call scutil to get the name of the current location
# then we call scselect and pass it the name of the current location
        # this forces the OS to re-read its Network configuration files
# (because it thinks its changing locations) and thereby picks up
# the changes we wrote to the .plist file
        $currLoc = get_location_from_scutil();
        if ($currLoc ne "") {
                `scselect $currLoc`
        }
}

#END

sub get_location_from_scutil {
    my @scutil = `scutil <<- end_scutil 2> /dev/null
open
show Setup:/
close
end_scutil`;

   my @matches = map { m/UserDefinedName : (.*)/ } @scutil;
    if(@matches == 1) {
        return $matches[0];
    }
    else {
        return "";
    }
}

autoProxyConfig.pl

Posted at 05:05 PM     Read More  

Custom startup items


In this blog, I've posted several scripts that we run at startup, without being terribly specific as to the details. Today I'd like to remedy that. I'll show you a custom startup item that can run any number of scripts (or executable binaries for that matter) that you place in a special directory.

Over the last couple of years, I've developed several scripts to manage certain aspects of OS X that I run at startup. Originally, I created a custom StartupItem which contained one big script that contained all the code I wanted to run at startup. The main disadvantages of this approach were:

• It wasn't very modular: if I wanted to run some scripts on some machines, and other scripts on other machines, I'd have to maintain different versions of the startup item.

• If you wanted to change the execution order of various subtasks, you needed to rewrite the script.

• All the code needed to be in a single shell language. I could not (easily) mix shell scripts with Perl scripts, and definitely could not (easily) run a pre-compiled binary if needed.

So I rewrote the StartupItem to be a simple shell script that simply ran every executable item in a predefined directory. I could add or remove items in that directory, rename them to control execution order, and can mix and match shell languages.

Let's step through the StartupItem.

A StartupItem is simply a directory (folder) in /Library/StartupItems. I've called mine "FAconfiguration":

[istanbul:/Library/StartupItems/FAconfiguration] madmin% ls -al
total 16
drwxr-xr-x 5 root admin 170 29 Dec 17:16 .
drwxrwxr-x 7 root admin 238 15 Jan 16:11 ..
-rwxr-xr-x 1 root admin 662 29 Dec 17:45 FAconfiguration
drwxr-xr-x 3 root admin 102 29 Dec 17:07 Resources
-rw-r--r-- 1 root admin 181 10 Oct 11:01 StartupParameters.plist

This directory contains three items:
StartupParameters.plist gives the SystemStarter process (which runs the StartupItems) some information about the item:

[istanbul:/Library/StartupItems/FAconfiguration] madmin% cat StartupParameters.plist 
{
    Description     = "Feature Animation Configuration";
    Provides        = ("FA Configuration");
    Requires        = ("Resolver", "Core Services");
    OrderPreference = "Late";
}

"Description" is simply a human-friendly name for the item, and will appear in the startup window that shows what things are being started before the Login Window appears.
"Provides" tells SystemStarter what services your StartupItem provides, this can be important if there are other services that should not be started until AFTER this service is available.
"Requires" tells SystemStarter what services must be available before attempting to run this item. Take a look at the items in /System/Library/StartupItems to get an idea of what is available and required.
"OrderPreference" gives SystemStarter a hint as to where (relatively) in the startup sequence this item should be run. We'd like it to run near the end of the process.

FAconfiguration is the actual script run by SystemStarter. Notice that it has the exact same name as the enclosing directory. SystemStart expects this. Note also that it is executable.

[istanbul:/Library/StartupItems/FAconfiguration] madmin% cat FAconfiguration 
#!/bin/sh

# Master FAconfiguration script
#
# runs each script found in /Library/StartupItems/FAconfiguration/Resources/scripts/

. /etc/rc.common

SCRIPTSDIR="/Library/StartupItems/FAconfiguration/Resources/scripts"
ConsoleMessage "Setting FA configuration"

if [ -d ${SCRIPTSDIR} ]; then
    for script in ${SCRIPTSDIR}/* ; do
        echo ${script}
        if [ -s ${script} -a -x ${script} ]; then
            logger -s -t FAConfiguration -p user.info Executing ${script}... 1>&2

            # run the item
            ${script}

            rc=$?
            if [ $rc -ne 0 ]; then
                logger -s -t FAconfiguration -p user.info ${script} failed with return code ${rc} 1>&2
            fi
        fi
    done
fi

exit 0

You can see that this script simply executes each executable item found in /Library/StartupItems/FAconfiguration/Resources/scripts, and writes some messages to the log to help us debug things if needed.

Finally, the Resources directory simply contains the scripts directory, which in turn contains each of the individual scripts to run:

[istanbul:FAconfiguration/Resources/scripts] madmin% ls -al
total 48
drwxr-xr-x 7 root admin 238 29 Dec 17:57 .
drwxr-xr-x 3 root admin 102 29 Dec 17:07 ..
-rwxr-xr-x 1 root admin 822 29 Dec 17:08 100.PowerManagement
-rwxr-xr-x 1 root admin 1108 29 Dec 17:10 200.SSH
-rwxr-xr-x 1 root admin 324 29 Dec 17:11 300.PasswordMaintenance
-rwxr-xr-x 1 root admin 5183 29 Dec 17:12 400.ValidateSystemUsers
-rwxr-xr-x 1 root admin 3240 31 Dec 10:56 500.setFAautoProxy

In this particular case, the first four scripts are shell scripts, and 500.setFAautoProxy is a Perl script. The scripts are run in "alphabetical" order, so I've named them with starting numbers to make the order obvious.

You can see other blog entries for details on each of the scripts.

Posted at 05:04 PM     Read More  


Tue - November 18, 2003

Enforcing ColorSync profiles


We had a need on certain machines to ensure that the ColorSync monitor profile was always set to a specific ColorSync profile, regardless of who logged in. This would ensure color consistency for all artwork created at a given workstation.

The first part of the solution was to write an AppleScript that set the display profile to the desired ColorSync profile:

property displayProfile : "/Library/ColorSync/Profiles/WDFA/WDFA.D65.g250.mac.icc"
on run
       tell application "ColorSyncScripting" to launch
       set displayFile to POSIX file displayProfile as alias
       try
              tell application "ColorSyncScripting"
                     repeat with x from 1 to (count of display)
                            set display profile of display x to displayFile
                     end repeat
              end tell
       on error errmsg
              activate
              display dialog errmsg
       end try
       tell application "ColorSyncScripting" to set quit delay to 5
end run

This script uses the “ColorSyncScripting” background app to set the display profile of all attached displays to our preferred profile.

The second part of the solution was to use the method of globally launching items at login described in another article here. This method ensures the script will be run at login for every user who logs into the machine.

Posted at 09:44 PM     Read More  

Screensaver configuration


For our environment, we are required to enforce a screensaver that comes on after 10 minutes of inactivity and requires a password to clear. Here's how we accomplish that for all users of a system.

In /System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resources/ is a file called Engine Defaults.plist

The default contents look something like this:

{
       idleTime = 1200;
       moduleName = "Flurry";
       askForPassword = 0;
}

This makes the default screensaver the "Flurry" module, sets its activation to 20 minutes, and does not require a password to clear it. We changed this file to read:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
       <key>askForPassword</key>
       <integer>1</integer>
       <key>hotCorners</key>
       <array>
              <array>
                     <string>0</string>
                     <string>0</string>
                     <string>1</string>
                     <string>1</string>
              </array>
       </array>
       <key>idleTime</key>
       <integer>600</integer>
       <key>moduleName</key>
       <string>Computer Name</string>
       <key>modulePath</key>
       <string>/System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resoures/Computer Name.saver</string>
</dict>
</plist>

This changes the default screen saver to the Computer Name module, sets it to activate after 10 minutes, requires a password, and sets both bottom corners to “activate now” hot corners.

To prevent our users from changing this default screen saver, we changed the ownership and privileges on the ScreenSaver.prefPane in /System/Library/PreferencePanes/ as follows:
       drwxr-x--- 3 root admin 102 Jul 27 2002 ScreenSaver.prefPane

This prevents non-admin users from using this prefs pane; and therefore they cannot change the screensaver settings.

Posted at 09:39 PM     Read More  


Sat - November 15, 2003

Managing account passwords


In most managed environments, workstations will all have either the same root password, or an admin account with a common password. This allows support personnel to access any machine they support and perform admin tasks. A problem arises when it is necessary or desirable to change the password on these admin accounts. If each machine must be visited individually in order to change the password, it probably won't happen very often, if at all. Here's one way to ensure password consistency...

You'll need to deliver a script to /etc/periodic/daily/
I use radmind, you could use scp or Apple Remote Desktop or Timbuktu, or NetOctopus, or FileWave, or ...

The script must be owned by root and the executable bit set. Since it contains an encrypted password, I recommend chmod 700 so it is only readable by root.
Here's the script:

#!/bin/sh
niutil -createprop . /users/name=XXXXX passwd YYYYY
exit 0

XXXXX is the short name of the admin account. If you don't know the shortname, log in as the admin account, open the terminal, and type 'whoami'.

YYYYY is the encrypted password. To generate this, in Terminal, use the openssl passwd command:

[localhost:~] admin% openssl passwd Mypswd1
EACXL1BcAq0hU

You would then use EACXL1BcAq0hU as the encrypted password for "Mypswd1" in the script.
Name the script something like 700.passwordMaintenance and put it in /etc/periodic/daily
It will run as part of the daily maintenance tasks, which typically run at 3:15 AM every day. Machines that are off or asleep at this time will never run the script. Anacron might be an option - it can run scripts that were missed when a machine was off or asleep.

An alternative would be to write this script as a StartupItem, which means it would run at every restart. In practice, I do both - I have the script run as a periodic task, and I have a custom StartupItem also run the script.

Since it is a periodic task, not only does it change the password, but it will keep it set to your desired password even if someone else changes it. This could be a good thing, or a bad thing, depending on your point of view.

This may break in 10.3 Panther, depending on if the machine was upgraded from Jaguar, and if the affected accounts use the new shadow password scheme. I expect to be able to fix it with a revised script, but haven't had time to test yet.

Posted at 09:28 PM     Read More  

Globally launching items at login


A common need in a managed environment is to run certain scripts every time someone logs in, or to open certain items (apps, folders, documents). Apple has provided a method for each user to specify items to be opened at login, but it is not entirely obvious how to specify certain items to be opened or executed for all users of a given computer.
Fortunately, there is a simple way to do this.

As it turns out, the loginwindow.plist file, located at ~/Library/Preferences/loginwindow.plist, works the way you'd wish all preference files worked. This file contains the list of items to open at login. If you take this file, copy it to /Library/Preferences/ and make sure it is readable by everyone (chmod o+r /Library/Preferences/loginwindow.plist), the items you've specified to open at login will now be opened for every user of that machine. What's even better is that if a user specifies items to be opened at login (using the "My Account" (Jaguar) or "Accounts" (Panther) preference pane), the items defined in /Library/Preferences/loginwindow.plist AND the items defined for the specific user at ~/Library/Preferences/loginwindow.plist will be opened. So you can define items to be opened for every user of a machine without interfering with the ability for a user to define their own items.

This technique can be further refined. I have defined a single item to be opened by every user of the machines I manage. It's an AppleScript application I call "LoginLauncher". This application looks in a folder I've defined (/Library/FA/LoginItems/) and opens everything in it. It knows how to run AppleScripts, execute shell and Perl scripts, and open anything else the same way the Finder would. The advantage of this method is that you do not have to keep editing /Library/Preferences/loginwindow.plist - instead, simply add or remove items from /Library/FA/LoginItems/ to control what is open or executed at start up.

Here's the AppleScript for LoginLauncher:
set scriptPath to "/Library/FA/LoginItems" --change this to the path for your Login Items
set theFolder to POSIX file scriptPath
set folderPath to theFolder as text
tell application "Finder"
    repeat with aFile in folder folderPath
        copy kind of item (aFile as textto theKind
        if theKind is "script text" or theKind is "compiled script" or theKind is "Script" then
            --run an AppleScript
            run script file (aFile as text)
        else if (aFile as textcontains ".sh" or (aFile as textcontains ".pl" then
            --run a shell or Perl script
            copy POSIX path of file (aFile as textto scriptPath
            do shell script (ASCII character 34) & scriptPath & (ASCII character 34)
        else
            --just tell the Finder to open it
            open item (aFile as text)
        end if
    end repeat
end tell

Posted at 08:26 PM     Read More  


Wed - November 12, 2003

Turning on SSHd


In Jaguar, SSHd was started by /System/Library/StartupItems/SSH and looked for a line in /etc/hostconfig to decide whether or not to launch sshd. In Panther, sshd is started if needed by xinet.d

To turn on SSH on Panther, either manage the file at /private/etc/xinetd.d/ssh or run the following:

/sbin/service ssh start

Either way you want to be sure that /priavye/etc/xinetd.d/ssh contains "disable=no".

Posted at 10:36 PM     Read More  

Power Management


Since various Apple hardware has different Power Manager capabilities, it's not recommended to include Energy Saver settings in an OS X image. How then to manage Energy Saver settings? pmset to the rescue!

Even Mike Bombich's excellent Carbon Copy Cloner removes Energy Saver settings when it is building an image of an OS X installation. So Energy Saver settings may not be consistent among your managed machines. If you run tasks automatically at night, it may be important to ensure your machines never go to sleep. If you have color-calibrated displays, you may need to ensure the displays never dim or sleep (as this can affect color calibration).

Enter pmset - a command-line interface to the Energy saver settings. Type man pmset at a command prompt for the complete tour.

Here's how I use it:

##################################################################
# Power Management
##################################################################
# -c flag means wall power, so this does not affect battery settings
# sets sleep never, disk spindown 10 mins
# and turns on wake on administrator network access
echo "Configuring Power Management options"
pmset -c sleep 0 spindown 10 womp 1

# if dim time is less than 30 minutes, set it to 30 minutes.
# (Again does not affect settings when running on battery)
dimtime=`pmset -g | grep dim | awk '{ print $2 }'`
if [ $dimtime -lt 30 -a  $dimtime -ne 0 ]; then
    #set dim time to 30 minutes
    echo "Setting display dim time to 30 minutes"
    pmset -c dim 30
fi

This script is called at startup as part of a custom StartupItem.

It leaves any Energy Saver settings that are for use when the machine is running on battery alone, though you could certainly script those as well, if you wanted. It sets the machine to never sleep, spin the hard drive down after 10 minutes of idle time, and turns on "wake on administrator network access" (which I have yet to put to good use).

Next, it sets the display to dim after 30 minutes, unless the user has set the time to an even greater value.

Posted at 10:13 PM     Read More  


©