Archive

Uncategorized

I was given the task of deploying a custom theme for Office 2016 the other day. Not having done this before, I did what I always do: I searched Google for the answer. I was able to figure out where to place the theme file, so I went about my merry way packaging up the theme (along with a script to move it into place) and the fonts that were part of the them, and then I deployed it.

Today I started getting reports that the fonts were not working in the theme. It turns out that when you use custom fonts in a theme, you have to deploy a special XML file that describes those fonts. I headed back over to Google only to find out that Office 2016 on the Mac does not support the creation of themes with fonts in them. Well, it doesn’t give you an easy way to customize the fonts

Fortunately, with a little searching, I found a web site that explained how to hack together a Theme Font file: XML Hacking Font Themes. So I started off and created a new XML file to get the fonts into the theme.

The easiest thing to do, as is explained in that article, is to grab an XML file out of the app bundle:

Just grab one of those XML files and copy it to your desktop. Once you’ve done that, edit the file, replacing the font inside the <a:latin> bracket with the name of the font you need. Do this for the Major and Minor font sections, then save the file. Name the new file the name of the font you are using to make it simple to find. My completed XML file looks like this:

Now that you have your XML file and your theme, you need to place them in the correct folder. Office 2016 keeps themes inside the user’s home folder in the following path:

/Users/<user>/Library/Group Containers/UBF8T346G9.Office/User Content/

We’re going to throw the theme into the Themes folder in that path, and the font XML file will go into the Theme Fonts folder in that path:

Voila! You now have a working theme in Office 2016 that can be used in PowerPoint, Word, or Excel.

When I first started out with the Casper Suite back in 2008, it was commonplace to create imaging configurations with their Casper Imaging tool. Drop an OS image into Casper, add in some applications in the order you want them installed, maybe a preference or two, and voila, you now have an imaging configuration for use in Casper Imaging. The next steps after that were to boot the machine you want imaged from an external source (NetBoot, USB drive, DVD, etc), run Casper Imaging, choose the configuration you want to run, and after some amount of time you’d have a machine ready to deploy.

Fast forward a few years, and more and more admins are no longer using an imaging methodology like this. Instead we’ve switched to leaving the factory operating system in place and simply adding the necessary applications and settings onto the systems. You can still utilize an imaging configuration deployed with Casper Imaging for this method, and that’s exactly how I first started with this method, but then I switched methods again, and started deploying apps and preferences with a post image, or First Boot, script.

This method, I felt, allowed me more opportunities to update the imaging process without having to touch the configuration. All I had to do was create a simple Bash script (or Python or whatever language you prefer) that would get called after Casper was done. After Casper had done it’s thing and restarted, my script would run and apply any config type items (set NTP server, time zone, etc) and then use the jamf binary to install software by calling policies.

Let’s take a look at the actual script and the LaunchDaemon I use to call it. The script in its entirety can be found on my GitHub repo here.

Script City

So the first bit of the script is just for setting up some variables and to setup logging. The script will output everything into this log file so that you can go back and troubleshoot later. If you are passing any sensitive data in the script, you may want to ship the log to a secure server and then delete it.

After we’ve taken care of some of that housekeeping, we lock the screen so the end user or tech knows that we are working on the system. You can use the default lock icon that Apple uses, or you can upload your own icon and declare that in the swuIcon variable. This bit of code is not my own, but was borrowed from Mike Morales out of this JAMFNation post. Thanks Mike!

Next we put a dummy receipt down in the JAMF Receipts folder (/Library/Application Support/JAMF/Receipts). This is so we can scope via Smart Groups to machines imaged on a certain day, if we need or want. The modelName variable uses system_profiler to grab the machine model.

After this, we get into setting system preferences like time servers and such. Rather than post all of the code, I’m going to point out a few key blocks. Like this one for enabling Location Services:

UPDATE: With Apple’s continuing security stance and the introduction of SIP, it is no longer possible to set the Location Services settings via script.

Or how about how to set the system preferences authorization to allow users access to the Network pref panel, etc:

And finally, the script checks for the location of the jamf binary file (to combat post-10.11 woes) and uses the binary to call policies. Thanks to Rich Trouton (derflounder.wordpress.com)for the code that checks for the binary location. Just copy and paste (changing policy ID and description) the policy install piece to add as many policies as you need.

After installing everything, run software update to install updates, remove the LaunchDaemon that controls the lock screen, and then restart the computer.

LaunchDaemon And Delivery

Now that we have our script built, we need to get it onto the system and have the system call the script. Let’s start with the LaunchDaemon. It’s a simple process to create a the file, just open up your favorite text editor (I like TextMate for writing Bash and Sublime Text for writing Python), drop in your XML and save out as a .plist file.

With our script written and our LaunchDaemon ready, we just need to bundle it all up and get it into Casper. I use Packages for this part, but you can use your favorite packaging application.

I utilize a folder that I create inside of /private/var to hide all of my admin stuff, like scripts and binaries. So for this script, I would place it in this folder path I create, place the LaunchDaemon inside of /Library/LaunchDaemons, and then package it up.

Once packaged, drop your package into Casper Admin, set the priority to something low, like 5, and make sure to select “Install on boot drive after imaging”

With all of that work done, just add that to a configuration for Casper Imaging and image away. Casper Imaging will reboot the computer, at which time Casper’s first boot script will run and install any packages that were set to “Install on boot drive after imaging” and then restart the computer.

With our package installed during that process, on reboot of the computer our LaunchDaemon will take over and call our script. From there it’s just a matter of watching the paint dry until our computer is ready for us.

Final Thoughts

I’ve glossed over some things to try and shorten an overly long post. There are plenty of ways to image computers, and while this process works for me right now, it may not be your cup of tea. I’m currently looking at whether I should get rid of the system preference pieces and move that to Configuration Profiles, or if there’s some other trick to try. Either way, never stop tinkering with what you do, it’s what makes the job enjoyable and is the quickest way to learn something new.

If you’d like more information, or have a question, hit me up on the inter webs.

I’m a fanboy. There, I said it and I’m proud of it. I’m a fanboy of JAMF Software’s Casper Suite. I’m also a fanboy of Code42 and their CrashPlan software. Put them together and it’s like when the two teens discovered peanut butter and chocolate as an amazing combination.

I am all about trying to minimize the amount of time my users need to be interrupted due to IT needs. That’s a large part of the reason we use Casper, so that my users do not have to be inconvenienced. Let’s face it, the more time I take performing IT tasks on their computer that cause them to not be able to work, the less money they are making for our agency. It’s one of my primary tenets of customer support: make every reasonable effort to not disturb the end user, period. So when I discovered several of my end user machines were not backing up via CrashPlan, I needed to find a way to deploy CrashPlan with as little interruption as possible. In steps Casper and CrashPlan together.

Our original setup of CrashPlan that has been running for several years, was setup using local logins. At the time when we first deployed, we were not on a single LDAP implementation, so I didn’t want to deploy an LDAP integrated CrashPlan. Fast forward to now, and we have a single LDAP (AD) and I want to take advantage of that implementation to provide “same password” logins for my users.

Fortunately JAMF has a technical paper outlining how to do this, titled Administering CrashPlan PROe with The Casper Suite. This paper was written back when CrashPlan PROe was still a thing. With the release of version 5 of CrashPlan, it has now become simply Code42 CrashPlan. This document still works for the newer version of the software.

Get The Template

The first step is to get ahold of CrashPlan custom template for the installer. Following the paper, you can download the custom template by navigating to this URL:

http://YourServerAddress:4280/download/CrashPlanPROe_Custom.zip

NOTE: If you are deploying version 5 or higher of CrashPlan, you can use this URL to download a newer version of the kit:

http://YourServerAddress:4280/download/Code42CrashPlan_Custom.zip

While there are two different URLs, you can use either one to customize your install.

Edit Away

After downloading and expanding the zip file, you will need to edit the userInfo.sh file to set some settings. First of which is to hide the application from your users during installation. Simply set the following line:

The next thing you will want to edit are the user variables. CrashPlan uses these variables to grab the user’s short name and their home folder location. An assumption is made when it comes to the user’s home folder, and that is the assumption that the home folder lives in /Users. If your home folders do not live there, or you want to script the generation using dscl, you can. I’m lazy and so I simply went with the /Users setting.

Also, the method to grab the user short name is based on the user that is logged in currently. Now, we didn’t discuss before how you were deploying this via Casper (login, logout, Self Service, etc), but suffice it to say, it is preferable to deploy this when a user is logged in to the computer. There have been many discussions on JAMF Nation about CrashPlan and how to grab the user, I used the information found in this post to grab the info I needed:

Now that you have the edits done, keep going through the technical paper, running the custom.sh script next to build the Custom folder we will need in a minute, and to download the installers. The custom.sh script will download the installers for Windows, Mac, and Linux, and slipstream the Custom folder into the installer package for us. In our case, since we are only concerned with the Mac installer, it places a hidden .Custom folder at the root of the DMG. We want that folder. So follow along in the tech paper to mount the Mac installer DMG and copy the .Custom folder out somewhere.

Package It All Up

We are going to need to deploy these custom settings alongside the CrashPlan installer. The tech paper has you using Composer (no surprise since it is their product), but I personally like to use Packages for my packaging fun. I’m not going to get into a discussion about what the best packaging method is, because that’s like debating which Star Trek movie was the best.

Using your method of packaging, create a package that drops that Custom folder (notice we are dropping the period so it is not hidden) into the following location:

/Library/Application Support/CrashPlan

Now that we’ve got our custom settings, we can move over to the JSS to work on our deployment. I’m going to skip discussing how to do this via Self Service, and instead stick with either a Login trigger or Recurring Check-In trigger. But first things first, go ahead and upload that custom settings package you just created into the JSS. Once it’s uploaded set the priority to something low, like 8:

 

Screen Shot 2016-02-12 at 12.05.44 PM

Create Your Policies

The tech paper discusses uploading the CrashPlan installer along with the custom properties, but I like the method that is discussed in this JAMF Nation post. It’s towards the bottom, and basically it uses curl to download the installer from the CrashPlan server. This method insures you have the latest version for your server. Of course, if you are trying to deploy to end users around the globe that may not have curl access to your CrashPlan server, uploading the installer to Casper may be your only option. For me, however, it was not.

First step is to create a new script in the JSS (or upload a script if your scripts are not stored in the database). The script itself is nothing special, it checks for the presence of the CrashPlan launch daemon, and if it is there unloads it and removes CrashPlan. Then the script continues on to install the custom properties (via a second policy) and finally installs CrashPlan:

Screen Shot 2016-02-12 at 12.14.24 PM.png

Screen_Shot_2016-02-12_at_12_28_13_PM.png

As you can see, I’m using a second policy to install the custom properties. You could do everything with one policy and two scripts, or one policy and curl the custom properties from another location. The key point is that if you are removing an existing installation (like I was), you cannot install the custom properties until you are done removing the existing. Make sense?

Now that we have all of our pieces and parts up there, you will create your two policies, one to install the custom properties and the other to run the script.

To Trigger Or Not To Trigger

With your policies created, you now need to determine how you want to trigger these policies. Obviously you will need to trigger one from within the script, but what about the main policy that kicks it all off? Well, I would probably do this via a recurring check-in trigger. It keeps the user from having to wait for the policy to complete before their login completes.

Of course, you could use the login trigger and throw up a nice notification using jamfHelper, Notification Center, or CocoaDialog. That sounds like a nice post for another day.

I Didn’t Do It

I cannot take the credit for this process. It was people like Bob Gendler and Kevin Cecil on JAMF Nation, along with the folks at JAMF and Code42, that did the heavy lifting. I just put it all into one location for me to remember later.

Here are the links to resources that were mentioned tonight at the meeting:

Rich Trouton’s blog:  http://derflounder.wordpress.com

Ben Tom’s blog:  http://macmule.com

Shea Craig’s blog:  http://labs.da.org/wordpress/sheagcraig/

Univ Utah rc.netboot fix:  http://goo.gl/xrBxa

JAMF Support GitHub:  https://github.com/JAMFSupport/

Bryson Tyrell:  https://bryson3gps.wordpress.com/

Mike Morales GitHub:  https://github.com/mm2270

JAMF Nation JNUC 2014 Playlist: https://www.youtube.com/playlist?list=PLlxHm_Px-Ie2e4a8tSFpc7JKdxYPxAS0M

My GitHub Repo:  https://github.com/stevewood-tx

IRC – there is a #jamfnation channel on the Freenode IRC server. A lot of great minds hang out on that channel during the day. While it is not a JAMF sponsored place, even a few JAMFers hang out in there occasionally. It’s a great way to get help in real time.  If you’ve never used IRC before, or it’s been a while, IRC Cloud is a great IRC app:

www.irccloud.com

Some Tools:

AutoDMG – tool for creating never before booted OS X DMG files for use in Casper or AutoCasperNBI

AutoCasperNBI – tool for creating NetBoot images

CreateUserPKG – tool for creating a package that will “install” a user on a system

AutoPKG – tool for downloading applications and updates. Utilizes recipes from the community. Can be coupled with Jenkins for automation. See my series of posts about it, starting with this one.

AutoPKGr – AutoPKG with a GUI front end, and integeration into the JSS. This tool eliminates the need to implement Jenkins

vfuse – tool for creating VMware Fusion VMs from DMG files

The presentation from tonight, minus the movies, can be downloaded from here:  https://github.com/stevewood-tx/CasperUserGroup

Music tonight was courtesy of the JNUC 2014 playlist on Spotify, put together by Mike Paul:  https://open.spotify.com/user/springfedmusic/playlist/3u1Hja1DYQHVOzvlGcWbK1