Tiny Deathstars of Foulness

The next release of iOS (10.3), macOS (10.12.4), and tvOS (10.2) bring us a host of new management features. These include DEP configuration, remote wipe, single app mode, conference room mode, and remote reboot for Apple TVs. The next evolution of iOS brings us sounds in lost mode, the ability to prevent users from connecting to unmanaged wireless networks (just make sure to push that policy after sending down the actual managed wireless networks – or eek), the option to remotely shut down and reboot devices,

The Mac options includes some of the above but also restricting the feature to unlock macOS devices with Touch ID, restrict documents and desktop syncing with Apple’s iCloud service. Shared iPad environments also get new passcode policies.

Jamf Pro 9.98 has also comes with Symantec PKI integration and lots, and lots, and lots of resolutions to product issues. For more, see For a full run-down of profile options and MDM commands:’s_New_in_This_Release.html.

Keeping with Apple’s evolving standards, Managed Preferences and Provisioning Profiles are being deprecated: (which isn’t to say you can’t still deploy these kinds of things using your own scripts, etc).

Finally, if you have a problem in your environment and want to see if it’s been fixed, for a list of defects and product improvements – see

March 23rd, 2017

Posted In: JAMF, Mac OS X, Mac OS X Server

Tags: , , , ,

Databases and Tables

A SQL database is an organized collection of data. Or at least that’s what they taught me in college. In real life, it’s only as organized as the people putting data into the database. Databases contain schemas, tables, stored procedures, reports, views and other objects. Most databases will contain multiple tables. Tables contain rows that have data in them. I like to think of a database kinda’ like an Excel spreadsheet. Each tab on a spreadsheet is similar to a table; each row is similar to a row in a database and each column in the spreadsheet is somewhat similar to a column, or attribute. The headers are kinda’ like the schema.

These are overly simplistic explanations. And whenever you oversimplify something, you run the risk of miscommunication, but it helps as a starting place. This page is meant to be a short and easy guide to get started writing SQL queries. More links will appear throughout the page that point to other posts on my site, so stay tuned. Throughout my exercises in this page, I will use the following sample database, which has five records (one for each ID) and seven columns (ID,Site,Contact,Address,City,Zip, and Country).

Below is a selection from the “Customers” table (note that when querying data, SQL commands are NOT case sensitive)

ID Site Contact Address City Zip Country
1 Krypted Charles Edge my house Minneapolis 55418 US
2 Apple Tim Cook spaceship Cupertino 95014 US
3 Microsoft Satya Nadella campus Redmond 98053 US
4 Facebook Mark Zuckerberg foodhall Menlo Park 94025 US
5 JAMF Dean Hager Grain Exchange Minneapolis 55418 US

SQL Statements

Most tasks you will execute against a database are done with SQL statements. Think of this as a query, an insert, a change, or a delete operating. For example, to see all of your data, you would select all of the records from a database using the SELECT statement. Then we’ll ask for all, or *, and tell the command to show us where the data is coming from, which is the Customers table. Finally, we’ll be nice and tidy and put a semi-colon at the end; although if you forget, you can always do so after you hit return:

SELECT * FROM Customers;

The SELECT statement is the most common command I run in SQL. This is how you query data, build reports, derive the layout of a database and so, so much more.

Other Important SQL Commands covered in this series (if there is no link, I haven’t written that article yet):

  • SELECT – Query and pull information from a database
  • CREATE TABLE – Create tables in specified databases
  • DELETE – Delete data
  • UPDATE – Update data in a database
  • DROP TABLE – Delete tables
  • INSERT INTO – Inserts new data into a specified database
  • CREATE DATABASE – Create databases
  • ALTER DATABASE – Modify databases
  • ALTER TABLE – Modify tables
  • CREATE INDEX – Create indexes
  • DROP INDEX – Deletes indexes
  • INNER JOIN – Merge rows in a database

January 26th, 2016

Posted In: SQL

Tags: , , , , , , , , ,

I’ve been light on posting here, mostly because I’ve been swamped with work, selling my old house, buying a new house, doing some crazy taxes, wrapping production on a new book and updating the Take Control of OS X Server book to Yosemite Server. Well, earlier this week I sold my house, got the next version of Bushel ready to rock and filed my taxes. Aaaaannnnnndddddd, the Yosemite version of Take Control Of OS X Server is now available at

Screen Shot 2015-02-05 at 2.24.54 PM

Boom. Will get back to my normally scheduled postings shortly!

February 5th, 2015

Posted In: Mac OS X, Mac OS X Server, Mac Security, Mass Deployment

Tags: , , , , , , , , , , , , ,

The swupd.plist file used to daisy chain multiple servers so they act as a cascade of software update servers. The new path for the property list is /Library/Server/Software Update/Config/swupd.plist. Here, the metaIndexURL key is sill the location that points to an internal Software Update Server that the server you are editing should look to for updates.

The default server is To set a server to look at another internal server for software updates, edit the metaIndexURL key in the /Library/Server/Software Update/Config/swupd.plist file to include the path to the new server. The path should always have /content/meta/mirror-config-1.plist after the FQDN of the host name. So if your internal software update server was called the command to set that as the upstream software update server would be:

defaults write /Library/Server/Software\ Update/Config/swupd metaiIndexURL “”

This is a minor change, but one that might be frustrating if you were still trying to cascade updates the old way. If you’re new to cascading updates, this is a pretty straight forward configuration change, run from a Terminal command. It’s also worth noting that there are a few other settings in this file that could come in handy. You can limit bandwidth using the limitBandwidth key, purge any old updates using the PurgeUnused key, set a max download speed using the maxDownloadSpeed key, configure the Software Update Server TCP port using the portToUse key (automatically set to 8088), change the path to the updates (e.g. if you mv them and then want to repoint to the new location without downloading them all again) using the updatesDocRoot key, etc. Overall, the settings align with the old settings, but just in a new place.

Note: The keys above correspond to settings found in the following command:

sudo serveradmin settings swupdate

The list of settings is as follows:

swupdate:checkError = no
swupdate:limitBandwidth = no
swupdate:PurgeUnused = yes
swupdate:portToUse = 8088
swupdate:autoEnable = yes
swupdate:valueBandwidth = 0
swupdate:syncStatus = "Initializing"
swupdate:autoMirror = yes
swupdate:syncBandwidth = 0
swupdate:updatesDocRoot = "/Library/Server/Software Update/Data/"
swupdate:autoMirrorOnlyNew = no

October 31st, 2014

Posted In: Mac OS X, Mac OS X Server, Mass Deployment

Tags: , , , , , , , , , , ,

Push Notifications can be used in most every service in the Server app, especially in 3.5 for Yosemite (which I still like to call Yosemite Server as it makes me think of Yosemite Sam in a tux, pouring champagne). Any service that requires Push Notifications will provide the ability to setup APNS during the configuration of the service. But at this point, I usually just set up Push Notifications when I setup a new server.


To enable Push Notifications for services, you’ll first need to have a valid AppleID. Once you have an AppleID, open the Server app and then click on the name of the server. At the Overview screen, click on Settings.


At the Settings screen for your server, click on the check-box for “Enable Apple push notifications.” At the Apple Push Notification Services certificate screen, enter an AppleID if you have not yet configured APNS and click on OK. The Apple Push Notification Service certificate will then be configured.


The certificate is valid for one year, by default. Administrators receive an alert when the certificate is due to expire. To renew, open the same screen and click on the Renew button.

October 18th, 2014

Posted In: iPhone, Mac OS X, Mac OS X Server

Tags: , , , , , , , , , ,

There are a number of ways to create groups in OS X Mavericks Server (Server 3). The first is using the Server app, the second is using Workgroup Manager (which could be running on an older operating system and connecting to the Mavericks Server in question), the third is using the Users & Groups System Preference pane and the fourth is using the command line. In this article we will look at creating groups in the Server app.

Once a server has been an Open Directory Master all user and group accounts created will be in the Local Network Group when created in Server app. Before that, all user and group objects are stored locally when created in Server app. Once promoted to an Open Directory server, local groups must be created in Workgroup Manager, the Users & Groups System Preference pane or using a command line tool appropriate for group management.

 To create a new group, open the Server app and then click on Groups in the ACCOUNTS list of the Server app sidebar. From here, you can switch between the various directory domains accessible to the server using the drop-down list available. Click on the plus sign to create a local network group.


At the New Group screen, provide a name for the group in the Full Name field. This can have spaces. Then create a short name for the group in the Group Name field. This should not have spaces.


Click Done when you have supplied the appropriate information and the group is created. Once done, double-click on the group to see more options.


Here, use the plus sign (“+”) to add members to the group or highlight members and use the minus sign (“-”) to remove users from the group. You can also choose to use the following options:

  • Give this group a shared folder: Creates a shared directory for the group, or a group with an ACL that grants all group members access.
  • Make group members Messages buddies: Adds each group member to each other group members buddy list in the Messages client.
  • Enable group mailing list: Enables a list using the short name of the group where all members receive emails to that address.
  • Create Group Wiki: Opens the Wiki interface for creating a wiki for the group.
  • Keywords: Keywords/tags to help locate users.
  • Notes: Notes about users.

Once changes have been made, click Done to commit the changes.

October 16th, 2014

Posted In: Mac OS X Server

Tags: , , , , , , , ,

Apple has released the client and server updates for Apple Remote Desktop. Both are now available on the App Store. For official information of the server update, see

New features include:

  • Support for OS X Mavericks
  • A shared clipboard which allows automatic copy and paste between local and remote computers
  • Improved support for Mac systems with multiple displays or multiple IP addresses
  • Enhanced multi-observe with gesture support for swiping between screens
  • Output of remote UNIX commands is no longer truncated

The client update documentation is at

October 24th, 2013

Posted In: Mac OS X, Mac OS X Server, Mac Security, Mass Deployment

Tags: , , , , , ,

I’ve done a few articles in the past on different tasks in svn and git, but I have a little cheat sheet of sorts I’ve been using for awhile for Subversion on Mac OS X and thought I would share it. Before you get started, check your version. I use 2.0 but I seem to remember all of these are about the same as they were previously:

svn --version

To get started, Subversion uses a repository to store projects. Each client needs a repository and these should be on direct attached drives. The repository hosts a Berkeley database a folder per project you check out, or import. To create a repository in a folder called Repository that lives in your home folder, you can use the following command, which uses the svnadmin command (svnadmin is used for most admin tasks in Subversion and the svn command itself is used for most user operations) and then the create verb, followed by a path:

svnadmin create ~/Repository

Note: These commands are mostly the same in Windows, except you use a drive letter rather than a fully qualified path. They are identical in Linux.

Within the Repository directory, each project will have a folder. Within these, you would then create folders for branches, tags and trunk, where trunk is the directories and files you will be working with. Then, we’ll import our first project. To do so we’re going to use the svn command, along with the import verb and then in the second position, we’ll use project to define the type of import. Next, we’ll define the location. The location could be http:// or file:///. In this case we’ll use an existing, mounted AFP file system at /Volumes/myserver/sharedrepo/projectname. Next, we’ll just put a message in there using the -m option, indicating “Initial Import”:

svn import project file:///Volumes/myserver/sharedrepo/projectname -m "First Import"

That wasn’t so bad. To see a list of the projects stored in a repository, use the svn command along with the list verb. When I do this, I like to use the –verbose option (optional, thus an option). YOu would also provide the path to the repository:

svn list --verbose file:///Users/cedge/Repository

To update the repository:

svn update

We now have a local copy of the project we imported earlier (creatively called projectname) and can work on it. Before we start working on it though, we want to check it out. To do so, we’ll use the svn command, along with the checkout verb. We’ll then provide the path to the project and name of the project:

svn checkout file:///Users/cedge/Repository/projectname/trunk projectname

When you’re done working on things, let’s look at what’s changed using svn’s status verb (btw, a writing point, by making svn possessive there, did I give it a personality? If so, then it’s certainly cranky at times so I suppose that’s fine):

svn status

You’ll invariably want to add things to a project, which uses the oddly named add verb (bad grammar pun, sry):

svn add filename

Removing files is a similar process:

svn delete filename

Adding, deleting and changes all need to be committed once you’re done working on the project. To commit changes, use the commit verb. Here, we’re going to provide a message explaining what we did (Added a method for handling invalid file names and bad grammar puns) and then the path:

svn commit -m "Added a method for handling invalid file names and bad grammar puns" file:///Users/cedge/Repository/projectname/trunk

I didn’t include tagging, getting releases (list verb), using preshared keys (ssh-keygen, ssh-copy-id, ssh-agent, ssh-add), resolving conflicts (resolved verb), so feel free to add comments with your examples if others read this and would like to add more!

March 12th, 2011

Posted In: Mac OS X, Unix, Windows XP

Tags: , , , , , , , , , , , , ,

Version 3.3 of the KACE 2000 appliance introduces a few enhancements for the Mac OS X operating system. These include the following:

  • International Keyboards are now supported in the KACE NetBoot environment
  • Hardware inventory is now supported
  • Pre-installation tasks now support error handling
  • Post-installation tasks now have ByHost support

Overall, a nice update if you’re invested in the KACE appliances, although the Windows enhancements are far more substantial (understandably), with updates to user profile migration (now hive based), driver harvesting and other features, primarily for the Windows 7 clients in your environments.

December 16th, 2010

Posted In: Mass Deployment

Tags: , , , , , ,

Sometimes you can bite yourself a little when you experiment around with things. I installed a security plug-in and the next thing you know I couldn’t log into my own website. Ouch. Not a huge deal as it actually led to experimentation with the MySQL tables for WordPress, which oddly enough, I’ve typically just left well enough alone. But this I figured was gonna’ need to be updated eventually (although I relished the opportunity to get caught up on some stuff in the meantime). So first up, SSH into your box. Then fire up mysql:

mysql -u root -p

Turns out there’s a wp_users table in there. For my user I was able to do the following (replacing MYUSERNAME with my actual username):


Then the following (again assuming MYUSERNAME is the user and now substituting MYPASSWORD with the password you want to use – lucky us that md5 is supported from the mysql CLI now, as that’s what WordPress is gonna’ want us to use):


And then viola I was back to writing the same old dribble once again. I had been really busy finishing off some chapters and so hadn’t bothered to figure it out. Now I’ll be back to it. Lucky you, right?!?!

April 13th, 2010

Posted In: Unix, WordPress

Tags: , , , , ,