The Time Machine service in macOS Server 5.2 hasn’t changed much from the service in previous operating systems. To enable the Time Machine service, open the Server app, click on Time Machine in the SERVICES sidebar. If the service hasn’t been enabled to date, the ON/OFF switch will be in the OFF position and no “Backup destination” will be shown in the Settings pane. screen-shot-2016-09-29-at-8-56-29-pm Click on the ON button to see the New Destination screen, used to configure a list of volumes as a destinations for Time Machine backups. The selection volume should be large enough to have space for all of the users that can potentially use the Time Machine service hosted on the server. When you click the Choose button, a list of volumes appears in a standard Finder selection screen. screen-shot-2016-09-29-at-8-57-19-pm Here, click on the volume to save your backups to in the sidebar. In most cases the Backup destination will be a mass storage device and not the boot volume of the computer. Once selected, click Choose and then if desired, limit the amount of storage on the volume to be used for backups. Click Create and a share called Backups is created and the service will start. Don’t touch anything until the service starts. Once started, add a backup destination at any time using the plus sign button (“+”) and defining another destination. screen-shot-2016-09-29-at-8-57-40-pm Time Machine Server works via Bonjour. Open the Time Machine System Preference pane and then click on the Select Backup Disk button from a client to see the server in the list of available targets, much as you would do with an Apple Time Capsule. screen-shot-2016-09-29-at-8-58-33-pm Under the hood, a backup share is creating in the file sharing service. To see the attributes of this share, use the serveradmin command followed by the settings option and then the sharing:sharePointList:_array_id:, so for a path of /Volumes/New Volume 1/Shared Items/Backups use: sudo serveradmin settings sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups The output indicates the options configured for the share, including how locking is handled, guest access disabled, generated identifiers and the protocols the backups share listens as:
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:name = "Backups"
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:smbName = "Backups"
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:nfsExportRecord = _empty_array
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:afpIsGuestAccessEnabled = no
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:isTimeMachineBackup = yes
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:dsAttrTypeNative\:sharepoint_group_id = "F4610C2C-70CD-47CF-A75B-3BAFB26D9EF3"
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:isIndexingEnabled = yes
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:mountedOnPath = "/Volumes/New Volume 1"
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:dsAttrTypeStandard\:GeneratedUID = "FAB13586-2A2A-4DB2-97C7-FDD2D747A0CD"
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:path = "/Volumes/New Volume 1/Shared Items/Backups"
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:smbIsShared = no
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:smbIsGuestAccessEnabled = no
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:afpName = "Backups"
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:smbDirectoryMask = "755"
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:afpIsShared = yes
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:smbCreateMask = "644"
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:ftpName = "Backups"
sharing:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:timeMachineBackupUUID = "844A1C43-61C9-4F99-91DE-C105EA95BD45"
Once the service is running, administrators frequently fill up the target volume. To move data to another location, first stop the service and then move the folder (e.g. using mv). Once moved, use the serveradmin command to send settings to the new backup path. For example, to change the target to /Volumes/bighonkindisk, use the following command: sudo serveradmin settings sharing:sharePointList:_array_id:/Shared Items/Backups:path = "/Volumes/bighonkindisk" Another way to see the share and attributes of the share is through the sharing command: sharing -l Which should show output similar to the following: List of Share Points
name: Backups
path: /Shared Items/Backups
afp: {
name: Backups
shared: 1
guest access: 0
inherit perms: 0
ftp: {
name: Backups
shared: 0
guest access: 0
smb: {
name: Backups
shared: 0
guest access: 0
} There’s also a Bonjour service published that announces to other clients on the same subnet that the server can be used as a backup destination (the same technology used in a Time Capsule). One major update from back in Mavericks Server is the addition of the timemachine service in the severadmin command line interface. To see the command line settings for Time Machine: sudo serveradmin settings timemachine The output shows that share info is displayed as with the sharing service, but you can also see the GUID assigned to each share that is a part of the backup pool of storage:
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:dsAttrTypeStandard\:GeneratedUID = "FAB13586-2A2A-4DB2-97C7-FDD2D747A0CD"
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:smbName = "Backups"
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:afpIsGuestAccessEnabled = no
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:smbDirectoryMask = "755"
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:afpName = "Backups"
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:smbCreateMask = "644"
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:nfsExportRecord = _empty_array
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:path = "/Volumes/New Volume 1/Shared Items/Backups"
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:smbIsGuestAccessEnabled = no
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:name = "Backups"
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:ftpName = "Backups"
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:smbIsShared = no
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:afpIsShared = yes
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:timeMachineBackupUUID = "844A1C43-61C9-4F99-91DE-C105EA95BD45"
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:isTimeMachineBackup = yes
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:backupQuota = 0
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:dsAttrTypeNative\:sharepoint_group_id = "F4610C2C-70CD-47CF-A75B-3BAFB26D9EF3"
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:isIndexingEnabled = yes
timemachine:sharePointList:_array_id:/Volumes/New Volume 1/Shared Items/Backups:mountedOnPath = "/Volumes/New Volume 1" Additionally you can also query for the service to verify it’s running using full status: sudo serveradmin fullstatus timemachine Which outputs something similar to the following: timemachine:command = "getState"
timemachine:state = "RUNNING"
While I found plenty to ramble on about in this article, Mass deployment is still the same, as is client side configuration.

Recently, I looked at leveraging the CrashPlan Pro REST API to extend the functionality of what can be done with CrashPlan Pro. It just so happens that I’m not quite done talking about CrashPlan Pro just yet. Now that you are off to the races with the API, it’s time to look at pushing that client you’ve got out en masse. Our good friends at JAMF software have been kind enough to publish a white paper that is pretty darn awesome to get ya’ started. But let’s look at what, other than setting the server address and registration key, that you can do. There are a few files embedded in the installer package. Most importantly, these include a default.service.xml file and a The looks at the system the package is installing on and figures out some variables to populate the default.service.xml file with. The default.service.xml file ends up with some other settings (ie – host name, registration key, etc) that are static in the file rather than dynamically loaded based on the output of the To get started building your deployment package, open the Install CrashPlanPRO installer package and then copy the Custom-example folder, naming the new instance simply Custom (or rename Custom-example to Custom given that you can always redownload). Then find the commented out section for <!– <authority address=”hostname:port”/> –> and uncomment it, changing the address variable so that the hostname:port reflects the actual address and port combination of your server. For example, if your server name were and you were running CrashPlan Pro on the default port (4282) then the address to use would be File System Layout of the Package You also need to choose whether or not the server address will be shown to users, the registration key of the organization that your user will be placed into and choose how to handle the username and password. These are done using the hideAddress, RegistrationKey, username and password variables. If you wish to hide the server address from end users, once the package has been deployed, then the hideAddress variable would be true; otherwise it would be false. Each organization in your server will have a registration key. Use the quoted form of the registration key for the organization (or parent organization) that the package should join in the registrationKey field. If the username is to be dynamically loaded from the then you should leave username=”${username}” and the password can be set to deferred or statically assigned as might be common with new deployments. If this seems like a lot, the authority section should read as follows:
<authority address=”” hideAddress=”true” registrationKey=”ABCD-EFGH-IJKL-MNOP” username=”${username}” password=”${deferred}” />
The above would suit most deployments. But the real flexibility comes in with Given that is a shell script, you can go way beyond what CrashPlan intends. By default, the uncommented lines of the script include the following:
startDesktop=true userHome=”$HOME” user=”$USER” userGroup=`id -gn “$user”` userEmail=”$user”
The startDesktop variable defines whether the desktop application will open following the installation of the package. The $USER variable gives you the opportunity to build out the user that will be used based on a number of variables. One of which is the computername for those environments that use the user name in LDAP as the computer name. For example, a line to set a username might instead be:
user=`scutil –get ComputerName`.
Or the user name might be pulled in from a user fillable field in Apple Remote Desktop:
user=`defaults read /Library/Preferences/ Text1`
The reason for the focus on pulling the user name out of something other than the currently logged in user here is that many will want to push out a lot of computers en masse without logging in as the user who will get the systems for each one… Of course, user isn’t the only thing we’ll want… The userGroup variable doesn’t seem to do anything, so we’re not going to be worried about that one. But the userEmail can often be looked up using dscl based on whatever LDAP attribute you might be storing it in… Oh, and then there’s the userHome. Well, what exactly do you want to back up on the machine? Just the home or /Users or /Volumes/MyBigOldXsan? One very interesting aspect of the script is that you can kill the package at this point and throw an error. For example, if the server is not accessible then the installer will complete but the package will not be useable. he banner for port 4282 isn’t easily programatically checked, although performing a quick check of the port is a good start for this (and becomes one of the ways you can monitor that CrashPlan Pro is running):
“`/Applications/Utilities/Network 4282 4282 | awk ‘{print $1}’`”
If the port isn’t open then let’s just:
else killall Installer fi
Or something like that… If you’re going to be pushing a package out then it’s not very likely that you’re going to worry too much about customizing how the installer actually looks. But, if you’re going to allow users to install it then you might want to. Basically, there are a number of images in a directory in your new custom folder called skin. In here, you can edit the images that make up those that appear throughout the package when it is run manually.