Archive for the ‘Bash scripting’ Category

Upgrading from Casper 8.73 to 9.32

June 28, 2014 4 comments

Since Casper 9.x was first released, I’ve been preparing for my shop’s own upgrade from Casper 8.x to 9.x. As of the morning of Saturday, June 28th, those preparations have ended with my shop’s successful upgrade to Casper 9.32. When I mentioned this on Twitter, I heard from a few folks who mentioned that they were planning to also do this in the near future and @theycallmebauer asked if I was going to post about my experience.

Screen Shot 2014-06-28 at 3.48.47 PM

I thought that was a good idea, so please see below the jump for the details.

Read more…

Automatically fixing MDM certificate enrollment with Casper 9.x

June 15, 2014 1 comment

A while back, I wrote a post on fixing Casper Mac MDM enrollment. This post covered my experiences with Casper 8.7.x and provided a method to automatically fix any problems with the MDM certificate. Unfortunately, the method that works in 8.7.x does not work in 9.x because the command that I use to do the MDM enrollment in Casper 8.x is jamf mdm. As part of the change from Casper 8.x to 9.x, the function performed by the jamf mdm command is now handled by the jamf manage command in Casper 9.x. The jamf mdm command itself does not exist in Casper 9.x

To duplicate the general process which I’m using in Casper 8.x, I needed to run the following commands:

/usr/sbin/jamf removeMdmProfile -verbose
/usr/sbin/jamf manage -verbose
/usr/sbin/jamf recon

The issue I ran into is that jamf manage waits until all policies are finished running, which meant that the MDM fix is running after the jamf recon command completes its inventory update and sends it on to the Casper server. The consequence is that the Casper server would never be informed that the machine had actually been fixed, which potentially cues an infinite loop of fixing a problem which is already fixed.

So I had two issues:

1. I wanted to fix my problem with a Casper smart group that would contain only affected machines and an associated Casper policy that would fix the machines in the smart group. This would allow the problem to be automatically detected and then fixed without the need for human intervention.
2. I needed to make reasonably sure all policies were finished running before trying to run the jamf manage command. Otherwise, running jamf manage would result in the recon running before the MDM certificate gets fixed.

On top of that, I preferred that jamf manage only be run once rather than building a process that potentially ran it a large number of times.

To sum up:

A) I wanted to fix the problem automatically with a Casper policy.
B) I couldn’t directly fix this with a Casper policy. Running the commands above using a policy would mean that jamf manage and jamf recon would not run in the order I wanted them to, with the undesired “infinite loop” consequences described above.

Shea Craig gave me the idea of using a LaunchDaemon and script to run the commands I needed, but I still needed a reliable way of determining if Casper policies were running. Shea’s approach relies on killing the jamf process as needed, but that ran the risk of interrupting any active policies or other tasks that were running.

After mulling over the problem for a while, I thought of another way to determine if a policy was running. /var/log/jamf.log is updated when Casper policies or check-ins run on an individual Mac, so if the log hasn’t been updated in a while, it is very unlikely that a policy is running.

Using this idea, I wrote a script and an associated LaunchDaemon to perform the following tasks:

1. Verify that the Mac can contact the Casper server.
2. Verify that /var/log/jamf.log has not been written to in the past five minutes.
3. If /var/log/jamf.log has not been written to in the past five minutes, fix the MDM certificate and communicate that it is fixed to the Casper server.
4. Delete itself and its associated launchdaemon.

For the details, see below the jump.

Read more…

Understanding Payload-Free Packages

June 1, 2014 2 comments

Back when Apple Remote Desktop 1.2 (ARD) was the main tool I used to administer my Macs remotely, I wanted to be able to run Unix commands remotely but needed a delivery vehicle that could send them over ARD. Payload-free installer packages were the answer.

Installer packages are Apple’s preferred way to install software. Apple built into ARD the ability to install software on remote machines using the Install Packages… function. One useful feature of installer packages is that you can have them run a script before or after the package is installed. You can even set up a number of scripts and have them run in the order you designate. Best of all, you can build a payload-free installer package that run scripts but does not install files. So, when I needed to run a Unix command on one or more of my managed Macs, I’d normally build a payload-free package and use the Install Packages… function to push it out to the relevant machines.

With Apple Remote Desktop 2 and later, Apple included a Send Unix Command… function. This gives you the ability to send a Unix command and get the feedback from the remote machine, without the extra work of building a payload-free installer package. However, the practice of building payload-free packages and using those to run my Unix commands stayed with me for the following reasons:


1. Ease of use – Running a script contained within a payload-free package does not require any special knowledge or training. All the person using it has to know is how to run an installation using an installer package.

2. Portability – When my management methods evolved beyond using ARD as my primary management tool, I found that different management tools had their own ways to deploy scripts but a common denominator of system management and deployment tools for Macs is that they can deploy installer packages. Using payload-free packages allows me to run scripts on managed machines in a consistent manner regardless of which management or deployment tool is being used.

Read more…

Users folder being hidden with iTunes 11.2 installed and Find My Mac enabled

May 16, 2014 7 comments

One side effect of the iTunes 11.2 update on Thursday, May 15th 2014 has been that some but not all Macs were seeing the /Users and /Users/Shared folders disappear.

Screen Shot 2014-05-16 at 1.01.52 PM

The permissions on the /Users folder were also changed to be world-writable, so that anyone could read and write to the /Users folder.

Update – 5-16-2014: Apple has released iTunes 11.2.1 to fix this issue. It’s available via Apple’s Software Update or from the main iTunes download site.

After installing iTunes 11.2.1, I’ve verified that I can re-enable Find My Mac and not have /Users or /Users/Shared vanish. The permissions on /Users were also still correct following the installation. To verify that the fix sticks, I rebooted several times and observed that the visibility and permissions for /Users and /Users/Shared stayed what they should be.

After considerable investigation by the folks in the ##osx-server IRC room, it looks like the issue has been tied to two causes:

1. iTunes 11.2 being installed

2. iCloud’s Find My Mac being enabled.

The 10.9.3 update does not seem to be the root cause, as the behavior has also been reproduced on 10.9.2 with iTunes 11.2 and Find My Mac enabled.

To fix this issue if you’re seeing it:

1. Open System Preferences

2. Open the iCloud preference pane

Screen Shot 2014-05-16 at 1.42.32 PM

3. Check if Find My Mac is enabled.

Screen Shot 2014-05-16 at 1.41.53 PM

4. If Find My Mac is enabled, uncheck it to disable it.

Screen Shot 2014-05-16 at 1.40.56 PM

5. Run the script below

What this script does is look for the /Users and /Users/Shared directory. If found, the directories are unhidden. A permissions repair is then run using the diskutil command to fix the world-writable permission issue for the /Users directory.

Note: The permissions repair may take up to 10 minutes to run.

Once the script is run, the /Users folder should be visible again.

Screen Shot 2014-05-16 at 1.38.40 PM

It is important that Find My Mac be disabled before the permissions fix is run and also that Find My Mac remain disabled. If Find My Mac is re-enabled, the /Users and /Users/Shared folder will disappear again and /Users will revert to being world-writable.

My understanding is that Apple is aware of the issue and working on it. Hopefully a fix appears quickly.

The script is also available on my GitHub repo:

A payload-free package containing the script is also available there, to help automate running this script.

Simple Package

April 29, 2014 5 comments

One task that has always seemed to me to take more time than it should is the process of packaging applications like Firefox, Google Chrome or other applications which are self-contained and can be copied as-is into /Applications. While tools like AutoPkg have helped a good deal by automating the download and packaging of various self-contained applications, this approach still requires some setup work and requires a recipe to be written to handle the application.

Screen Shot 2014-04-28 at 3.06.33 PM

To help make this task easier, I’ve developed Simple Package, an Automator application that will allow the selection of a self-contained application and creates an installer package that enables the installation of the application with pre-set permissions into /Applications. For more details, see below the jump.

Read more…

CasperCheck – an auto-repair process for Casper agents

April 23, 2014 24 comments

One of the issues that I occasionally run into in my shop is that sometimes the Casper agent on individual Macs stops working properly. They stop checking in with the Casper server, or check in but can’t run policies anymore. I’ve set up smart groups on my Casper server to help me identify these machines, but actually fixing them has not been an automated process.

While at the JAMF Nation User Conference in October 2013, I was fortunate enough to hear Mike Dodge and Ajay Chand talk about the challenges they faced at Facebook with keeping Casper agents working in an environment where users are encouraged to break down any obstacle that gets in their way (sometimes, the obstacles in question were perceived to include the Casper agent.) As part of their talk, they mentioned they had a scripted way to verify that the Casper agent was running properly and automatically fix it if it wasn’t. This was a capability that I wanted to include in my own environment, so I asked them if this was going to be available at some point. They said it would be, so I waited to see what would be released.

At this point, the story fast forwards to March 2014, where the Facebook team was able to release their code to GitHub and I was able to take a look and see what they had done. I saw that I could adapt some of their work, but I would need to do additional work on my end to develop a solution that not only worked in my environment, but would be relatively straightforward to adapt to work in others’.

After a lot of work and testing, I’m happy to announce the release of CasperCheck. This is a script-driven solution that will do the following:

A. Check to see if a Casper-managed Mac’s network connection is live

B. If the network is working, check to see if the machine is on a network where the Mac’s Casper JSS is accessible.

C. If both of the conditions above are true, check to see if the Casper agent on the machine can contact the JSS and run a policy.

D. If the Casper agent on the machine cannot run a policy, the appropriate functions run and repair the Casper agent on the machine.

For more details, see below the jump.

Read more…

First Boot Package Install Revisited

April 17, 2014 3 comments

As covered previously, Greg Neagle’s createOSXinstallPkg is a useful tool for installing or upgrading Mac OS X in a variety of situations. One of the nicer features is that you can edit the OS X installer to install additional packages.

However, the limitations of the OS X install environment mean that there are a number of installers that won’t install correctly. In particular, packages that rely on pre- or postflight scripts to perform important tasks may fail to run properly in the OS X install environment.

To help work around this limitation, I developed First Boot Package Install.pkg, an installer package that enables other packages to be installed at first boot. It’s designed for use with createOSXinstallPkg with the goal of allowing installer packages that can’t run in the OS X Install environment to be incorporated into a createOSXinstallPkg-using deployment workflow.

The first version of First Boot Package Install.pkg had some limitations though, with the biggest one probably being that you couldn’t tell what it was doing when it was running. Instead, all that was displayed was the gray Apple loading screen.


I tried various approaches of booting into verbose mode and writing log entries to the console, but none of the approaches were good enough to introduce into production. Fortunately, Per Olofsson developed exactly what I was looking for with his LoginLog tool.


Using as a way to display updates to the user, I’ve been able to update First Boot Package Install.pkg with improved visual feedback. I’ve also now incorporated another piece of feedback I’ve received, which is to add a network check. This new check makes sure that the Mac has a network address other than or before it proceeds to install any packages. For more details, see below the jump.

Read more…

Repackaging the Microsoft Lync 14.0.8 installer

April 10, 2014 7 comments

Microsoft has released Microsoft Lync 14.0.8, which included compatibility with Mavericks. Since we have several folks using both Lync and Mavericks, I wanted to get this into our Casper server’s Self Service as soon as possible.

To test installing it, I downloaded the installer on a disk image from Microsoft’s site, then renamed the package from Lync Installer.pkg to Lync 14.0.8 Installer.pkg. After renaming it, I set up an installation policy for Self Service, scoped the policy so that only my test machine could see it, then ran the installation.


I go check the logs and see this entry:

/usr/sbin/jamf is version 8.73
Executing Policy Microsoft Lync...
[STEP 1 of 2]
Downloading BOM for Lync 14.0.8 Installer.pkg...
This Apple Package did not have a valid file. Assuming it is a flat file package.
Downloading 14.0.8 Installer.pkg...
Error: The package could not be found on the server.
[STEP 2 of 2]
Running Recon...
Displaying message to end user...

OK, maybe I did that wrong. Deleted the package and this time uploaded the installer to my Casper server without changing the name from Lync Installer.pkg.

/usr/sbin/jamf is version 8.73
Executing Policy Microsoft Lync...
[STEP 1 of 2]
Downloading BOM for Lync Installer.pkg...
This Apple Package did not have a valid file. Assuming it is a flat file package.
Downloading Installer.pkg...
Error: The package could not be found on the server.
[STEP 2 of 2]
Running Recon...
Displaying message to end user...

Failed again. Meanwhile, /var/log/install.log on my test Mac only showed that installd was starting and then stopping. In short, Casper’s logs were right; the installation process was starting but couldn’t then find a package.

At that point, I started thinking. How would the developer have installed this package? How did Q&A likely test installing it, however minimally?

Developer – Would have double-clicked on the package to install it, followed by typing in an admin password.

Q&A – Same process as the developer, except they would have tested installing it from the mounted disk image.

Read more…

Setting Parameter Labels in Casper

March 20, 2014 3 comments

I recently learned about how to use Parameter Labels as part of a JAMF training class. I had read about them in the Casper Administrator’s Guide but managed to fundamentally misunderstand what they did and how they work.

What I thought:

Adding a Parameter Label value to a script in Casper Admin meant that the associated variable value would be pre-set for the script when I added it to a policy.

I didn’t want this behavior, as I wanted to maintain flexibility when setting policies. Consequently, I didn’t set anything in the Parameter Label value for my scripts.

How they actually work:

Setting the Parameter Label value in Casper Admin means that you’re changing the label that shows up in the script parameters in a policy. For example, changing the Parameter Label value for Parameter 4 in Casper Admin to Username means that the parameter name for the script will change from Parameter 4 to Username when you add the script to a policy.

Screen Shot 2014-03-20 at 10.29.02 AM

Screen Shot 2014-03-20 at 10.28.01 AM

Here’s how to set Parameter Labels in Casper Admin:

1. Open Casper Admin

2. Select the script you want.

3. Click the Info button.

Screen Shot 2014-03-20 at 10.30.47 AM

4. Click the Options tab.

Screen Shot 2014-03-20 at 10.32.11 AM

5. Set the parameter you want to change to the desired name.

Screen Shot 2014-03-20 at 10.26.28 AM

6. When you create a policy that uses that script, the parameter will have the name you set instead of the default parameter name.

Screen Shot 2014-03-20 at 10.28.01 AM

Categories: Bash scripting, Casper

Payload-Free Package

March 8, 2014 3 comments

I do a lot of work with payload-free packages and I’ve looked for a while for a tool that would let me easily create them from existing scripts. While I have a process for creating them as needed with pkgbuild, this approach still requires some setup work.

Payload-Free Package Creator logo

After thinking about it and taking a look at various approaches, I’ve developed Payload-Free Package, an Automator application that will allow the selection of an existing script and create a payload-free package that runs the selected script. For more details, see below the jump.

Read more…


Get every new post delivered to your Inbox.

Join 141 other followers

%d bloggers like this: