Tiny Deathstars of Foulness

OS X Server stores most logs in files that are in the /Library/Logs/ProfileManager directory. Logs are split up between php, devicemgrd.log, scep_helper.log, servermgr_devicemgr.log, profilemanager.log and others. In my experience, if there’s a lot of errors at first, or if the service doesn’t work, just reformat and start over. But, once a server is in production, you don’t want to re-enroll devices after you do that. So, as with all good error prodding, start with the logs to troubleshoot.

By default the logs can appear a bit anemic. You can enable more information by increasing the logging level. Here, we’ll shoot it up to 6, which can be done with the following command:

sudo debugDeviceMgr 6

Debug levels go all the way to 9, but at that point things get… Noisy. And to turn it back off, use:

sudo debugDeviceMgr 1

Basically, this command sets the required services in /Applications/ to debug mode as well as /Applications/ and /Applications/ to configure debug mode. In other words, it touches a lot of services. And given how chatty some can be, only leave logging levels higher than I’d say 2 in the event of short-term troubleshooting.

December 29th, 2016

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

Tags: , , , , , , ,

One of the first things we do when we setup a new macOS Caching Server is to check the logs to see if it’s actually serving content. You can view thee logs at /Library/Server/Caching/Logs/Debug.log. In the log, when a Caching Server has registered for your network, you’ll see a line that begins with the following:

Got request for host =

This above means that the server actually got a request (as it says) and that the request is for an asset at (followed by the actual package path). Once found, the server caches the asset, which starts with the following:

Initializing asset handler for

The path would then match the same asset along with a path=(followed by the path to the asset on your server).

You’ll then see some information and ultimately a list of the number of bytes served from the cache, as well as the number of downloads. If that sits at 0 the server isn’t really doing anything…

November 16th, 2016

Posted In: Mac OS X Server

Tags: , , , ,

Servers can have problems. When they have problems, you need to grab logs and stuff. Ever wonder what Apple developers think is important, when it comes to logs and stuff? Try serverdiagnose!


Then hit the Enter (return) key. Then it collects some logs into a tgz. Why a tgz? No clue. But it ends up in /tmp. Notice the name as ServerLogs- followed by the hostname, then a date stamp (yearmonthday) and an underscore followed by a timestamp. Inside the tgz is /Library/Logs, /Library/Server, /tmp/dsdiagnose (a dump of OD debug logs), serverlogs_S3vKsy (configuration statuses), a couple of things from /var/db (the most important of which is PreviousSystemLogs), and /var/log.

November 9th, 2016

Posted In: Mac OS X Server

Tags: , , , , ,

Server comes with a command called RoomsAdminTool located at /Applications/ This tool can list available rooms using a -l flag:

RoomsAdminTool -l

You can also create new rooms, using the following format, where krypted is the name of the room, the persistent option means the room is, er, persistent. The description option indicates a description used for the room.

RoomsAdminTool -n krypted -c persistent yes description "This room is for friends of krypted only”

To then delete the room, use the -d option:

RoomsAdminTool -n krypted -d

Add the -v to do it all verbosely. There are lots of other options as well, as follows (from the man page):

Valid Configuration Keys and Values:

descriptionstringA short description for the room
passwordstringDefine a password for room entry. An empty string implies no password required.
membersOnlyyes | noOnly room members are allowed to enter the room.
subjectLockedyes | noAre non-moderators and non-admins prevented from setting the room subject
logFormatDisabled | Text | XHTMLDisable room logging, or enable it using Text or XHTML.
maxUsersinteger; 0 for unlimitedSet the maximum allowed occupants for the room.
moderatedyes | no Make the room "moderated".
nonAnonymousyes | noIf "yes", only moderators/owners can discover occupants' real JIDs.
persistentyes | noPersistent rooms stay open until they are explicitly destroyed and their configuration survives service restarts, unlike non-persistent rooms.
privateMessagesAllowedyes | no Whether or not occupants can exchange private messages within the room.
roomPublicyes | no Defines whether the room be discovered by anyone
subjectstringSet a room subject/topic
usersCanInviteyes | no Defines whether occupants can invite other users to enter the room
addOwnervalid JabberIDMake the specified user a room owner (ex.: Rooms can have multiple owners.
removeOwnervalid JabberIDRemove the specified user from the room owner list
addAdminvalid JabberIDMake the specified user a room admin
removeAdminvalid JabberIDRemove the specified user from the room admin list
addMembervalid JabberIDMake the specified user a room member
removeMembervalid JabberIDRemove the specified user from the room member list
addOutcastvalid JabberIDMake the specified user a room outcast (banned from public rooms)
removeOutcastvalid JabberIDRemove the specified user from the room outcast list

Ultimately, if you’d like to do Student Information System (SIS) integration, or wait for an AD/OD group and then programmatically generate rooms, this is how you’d do it.

November 7th, 2016

Posted In: Mac OS X Server

Tags: , , , , ,

The NetBoot service allows administrators of Apple computers to leverage images hosted on a server to boot computers to a central location and put a new image on them, upgrade them and perform automations based on upgrades and images. Since the very first versions of OS X, the service has been called NetBoot and so the name remains at the command line, but is listed as NetInstall in the Server app. In the Server app, Apple provides a number of options surrounding the NetInstall service, based on Automator-style which we’ll explore further in this article.

The first step to configuring the NetInstall service is to decide what you want the service to do. There are three options available in System Image Utility (available under the Tools menu of the Server app in OS X Server):

  • Create a NetBoot Image: Allows Macs to boot over the network to a disk image hosted on a server.
  • Create a NetInstall Image: Leverage NetBoot as a boot disk so that an image hosted on a server can be used to run a macOS installer.
  • Create a NetRestore Image: Leverage NetBoot as a boot disk so that you can restore a computer that has been configured over a network. Use this option to restore an image that has been prepared.

For the purposes of this example, we’re going to use a macOS Sierra (10.12) installer running Server 5.2 to boot a Mac over the network. The first step in doing so is to create a Network Disk Image (in this case 10.12), or the 10.9 installation media (which is the Install macOS Sierra bundle for this example). Before setting it up, download the Install macOS Sierra installer app into the /Applications directory from the App Store.

Create An Image

To then set up the NetBoot disk image (you can’t start the NetInstall service until you give it an image to serve), often referred to as the NetBoot set, open the Server app and then click on System Image Utility from the Tools menu of OS X.

When System Image Utility opens, click on the Install macOS Sierra entry in the list of available sources and click Next.


Then, in the list of options, click on NetBoot Image and then click on the Next button.


At the License Agreement screen, click Agree.


Then provide an account name, short name and password in the Image Settings screen. Also choose the language of the user and select if you want the account to log in automatically. Once provided, click Next.

Next, select any profiles, packages or post-install scripts to run on the NetBoot image once created. Here, you can use a profile to deploy a printer, bind to Active Directory, or use a package to install software. Post-install scripts allow you to do pretty much anything you’d like to a system, provided it’s allowed by SIP.


At the System Configuration screen, choose how you’d like systems to receive names. Here, you can provide a name as a base for computers to get a computer name or you can use a file to deploy names. In most cases, you should also check the box for “Match to client after install.” Click Next once you’ve selected how this should occur.


At the Directory Servers screen, click on the plus sign if you’d like to bind the system to a particular directory server.


In this example, we’re binding to Also provide an account with access to bind to where you’re binding. In this case, we’re using the built-in admin account for Active Directory. Click Add once you’ve provided the appropriate directory server and credentials.


At the Image Settings screen, provide a name for the image, as well as how the index number for the image is created. Note that each image should have a unique image index, so unless you’re storing your image on multiple servers, it’s best left at the defaults. Click Next.


At the Supported Computer Models screen, you can choose which models of computer you don’t wish to support for this image. We’re not doing that here, but it’s useful, for example, if you’d like to preclude desktops from an image.


At the Filter Clients By MAC Address, you can choose to explicitly allow or deny given MAC addresses for computers. We’re not going to do that as part of this workflow, so just click Next (unless of course you’d like to do that).

Then, when prompted, select a location to store the Disk Image, provide any tags to be applied to the files that comprise the image and click on Save.

The computer will then start creating the NetBoot set.

Setup The NetInstall Service

Once finished, it’s time to set up the NetInstall service in macOS Server. To get started, go back to the Server app.

First, define which disk will host NetBoot Images. To do so, click on the Edit Storage Settings button. At the Storage Settings overlay, select the volume that Images will be hosted as well as the volume that Client Data will be hosted. The Image is what you are creating and the Client Data is dynamic data stored in images.

If you only have one disk, as in this example, click on “Images & Client Data” for that disk. Then click on the OK button. Once you’ve selected a disk to store your image, we need to copy the disk image into the Library/NetBoot/NetBootSP0 folder of the disk used for images.


Once in the appropriate folder, click on the Edit button for Network Interfaces and select the appropriate network interface you wish to serve images over, and click OK. Refresh the Server app (Command-R) and provided the image was created and moved into the /Library/NetBoot/NetBootSP0 directory of a volume set to host images, the image will appear in the images list, with a green indicator light.


The green indicator light means the image is being served over the network. Double-click on an image.

At the image settings screen, you can select NFS over the default HTTP protocol for “Make available over”.Note, you can also restrict access to the image to certain models of Apple computers and/or certain MAC addresses by using the “Image is visible to” and “Restrict access to this images” options respectively. Additionally, use the Make this image available for diskless booting option to allow computers without hard drives to boot to the image.


Click on the OK button. Click on the image and then click on the cog-wheel icon. Click on “Use as Default Boot Image” to set an image to be the default images computers boot to when booting to NetBoot. Now, it’s as easy as clicking on the ON button. Do so to start the service.

Once started, open a Terminal window. Here, let’s get a status of the service using the serveradmin fullstatus option (along with the service name, which is still netboot from the command line):

sudo serveradmin fullstatus netboot

The output of which shows the various components, logs and states of components:

netboot:state = "RUNNING"
netboot:stateTFTP = "RUNNING"
netboot:readWriteSettingsVersion = 1
netboot:netBootConnectionsArray = _empty_array
netboot:logPaths:netBootLog = "/var/log/system.log"
netboot:dhcpLeasesArray = _empty_array
netboot:stateDHCP = "STOPPED"
netboot:stateHTTP = "RUNNING"
netboot:serviceCanStart = 1
netboot:timeOfSnapshot = "2016-09-27 02:07:32 +0000"
netboot:stateNFS = "STOPPED"
netboot:stateImageArray:_array_index:0:_array_index:0 = 1
netboot:stateImageArray:_array_index:0:_array_index:1 = 0
netboot:stateImageArray:_array_index:0:_array_index:2 = 0
netboot:stateImageArray:_array_index:0:_array_index:3 = 1
netboot:stateImageArray:_array_index:0:_array_index:4 = 2
netboot:stateImageArray:_array_index:1:_array_index:0 = 0
netboot:stateImageArray:_array_index:1:_array_index:1 = 0
netboot:stateImageArray:_array_index:1:_array_index:2 = 0
netboot:stateImageArray:_array_index:1:_array_index:3 = 0
netboot:stateImageArray:_array_index:1:_array_index:4 = 2
netboot:stateImageArray:_array_index:2:_array_index:0 = 0
netboot:stateImageArray:_array_index:2:_array_index:1 = 0
netboot:stateImageArray:_array_index:2:_array_index:2 = 0
netboot:stateImageArray:_array_index:2:_array_index:3 = 0
netboot:stateImageArray:_array_index:2:_array_index:4 = 2
netboot:stateImageArray:_array_index:3:_array_index:0 = 0
netboot:stateImageArray:_array_index:3:_array_index:1 = 0
netboot:stateImageArray:_array_index:3:_array_index:2 = 0
netboot:stateImageArray:_array_index:3:_array_index:3 = 0
netboot:stateImageArray:_array_index:3:_array_index:4 = 2
netboot:servicePortsRestrictionInfo = _empty_array
netboot:netBootClientsArray = _empty_array
netboot:servicePortsAreRestricted = "NO"
netboot:setStateVersion = 1
netboot:startedTime = "2016-09-27 02:06:53 +0000"
netboot:stateAFP = "STOPPED"

And to start the service when not running:

sudo serveradmin start netboot

There are also a number of settings available at the command line that are not in the graphical interface. For example, to allow writing to the NetBoot share:

sudo serveradmin settings netboot:netBootStorageRecordsArray:_array_index:0:readOnlyShare = no

Or to get more verbose logs:

sudo serveradmin settings netboot:logging_level = "HIGH"

To stop the service:

sudo serveradmin stop netboot

In the beginning of this article, I mentioned that ways to configure NetInstall images. I’ll cover NetInstall and NetRestore in later articles as they tend to be more involved workflow-wise than copying a volume into a Network Disk Image. But to end this one, many an old-school admin might wonder where all the settings went that used to be in the GUI. Well, serveradmin still maintains a lot of the older stuff. To see a list of all available settings, run serveradmin with the settings verb and then netboot:

sudo serveradmin settings netboot

If there was a feature you want to use (e.g. maximum users), you should see it in the resultant list:

netboot:netBootFiltersRecordsArray = _empty_array
netboot:netBootStorageRecordsArray:_array_index:0:sharepoint = yes
netboot:netBootStorageRecordsArray:_array_index:0:clients = yes
netboot:netBootStorageRecordsArray:_array_index:0:volType = "hfs"
netboot:netBootStorageRecordsArray:_array_index:0:okToDeleteSharepoint = no
netboot:netBootStorageRecordsArray:_array_index:0:readOnlyShare = no
netboot:netBootStorageRecordsArray:_array_index:0:path = "/"
netboot:netBootStorageRecordsArray:_array_index:0:okToDeleteClients = yes
netboot:netBootStorageRecordsArray:_array_index:0:volName = "Macintosh HD"
netboot:netBootPortsRecordsArray:_array_index:0:deviceAtIndex = "en5"
netboot:netBootPortsRecordsArray:_array_index:0:nameAtIndex = "USB 10/100/1000 LAN"
netboot:netBootPortsRecordsArray:_array_index:0:isEnabledAtIndex = yes
netboot:logging_level = "MEDIUM"
netboot:filterEnabled = no
netboot:netBootImagesRecordsArray:_array_index:0:RootPath = "NetBoot.dmg"
netboot:netBootImagesRecordsArray:_array_index:0:IsInstall = no
netboot:netBootImagesRecordsArray:_array_index:0:Kind = "1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:0 = "MacBookAir6,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:1 = "MacBookAir5,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:2 = "MacBookAir7,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:3 = "MacBookAir2,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:4 = "MacBookAir5,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:5 = "MacBookAir4,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:6 = "MacBookAir4,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:7 = "MacBookAir6,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:8 = "MacBookAir7,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:9 = "MacBookAir3,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:10 = "MacBookAir3,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:11 = "MacBookPro5,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:12 = "MacBookPro9,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:13 = "MacBookPro6,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:14 = "MacBookPro6,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:15 = "MacBookPro8,3"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:16 = "MacBookPro11,3"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:17 = "MacBookPro7,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:18 = "MacBookPro11,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:19 = "MacBookPro10,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:20 = "MacBookPro12,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:21 = "MacBookPro11,4"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:22 = "MacBookPro11,5"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:23 = "MacBookPro3,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:24 = "MacBookPro4,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:25 = "MacBookPro8,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:26 = "MacBookPro10,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:27 = "MacBookPro5,3"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:28 = "MacBookPro5,5"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:29 = "MacBookPro5,4"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:30 = "MacBookPro5,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:31 = "MacBookPro9,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:32 = "MacBookPro11,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:33 = "MacBookPro8,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:34 = "iMac14,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:35 = "iMac9,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:36 = "iMac7,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:37 = "iMac12,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:38 = "iMac11,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:39 = "iMac14,4"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:40 = "iMac11,3"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:41 = "iMac13,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:42 = "iMac15,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:43 = "iMac12,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:44 = "iMac8,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:45 = "iMac10,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:46 = "iMac13,3"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:47 = "iMac14,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:48 = "iMac14,3"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:49 = "iMac13,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:50 = "iMac11,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:51 = "Macmini5,3"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:52 = "Macmini5,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:53 = "Macmini4,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:54 = "Macmini5,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:55 = "Macmini3,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:56 = "Macmini6,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:57 = "Macmini6,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:58 = "Macmini7,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:59 = "MacBook8,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:60 = "MacBook7,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:61 = "MacBook5,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:62 = "MacBook6,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:63 = "MacBook5,2"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:64 = "MacPro3,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:65 = "MacPro5,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:66 = "MacPro4,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:67 = "MacPro6,1"
netboot:netBootImagesRecordsArray:_array_index:0:DisabledSystemIdentifiers:_array_index:68 = "Xserve3,1"
netboot:netBootImagesRecordsArray:_array_index:0:Description = "NetBoot of OS X 10.11 (15A178w) Install (9.12 GB)."
netboot:netBootImagesRecordsArray:_array_index:0:Name = "NetBoot of Install OS X 10.11 El Capitan"
netboot:netBootImagesRecordsArray:_array_index:0:imageType = "netboot"
netboot:netBootImagesRecordsArray:_array_index:0:Index = 3089
netboot:netBootImagesRecordsArray:_array_index:0:osVersion = "10.11"
netboot:netBootImagesRecordsArray:_array_index:0:BackwardCompatible = no
netboot:netBootImagesRecordsArray:_array_index:0:SupportsDiskless = no
netboot:netBootImagesRecordsArray:_array_index:0:EnabledSystemIdentifiers = _empty_array
netboot:netBootImagesRecordsArray:_array_index:0:Language = "Default"
netboot:netBootImagesRecordsArray:_array_index:0:BootFile = "booter"
netboot:netBootImagesRecordsArray:_array_index:0:IsDefault = no
netboot:netBootImagesRecordsArray:_array_index:0:Type = "HTTP"
netboot:netBootImagesRecordsArray:_array_index:0:Architectures = "4"
netboot:netBootImagesRecordsArray:_array_index:0:IsEnabled = yes
netboot:netBootImagesRecordsArray:_array_index:0:pathToImage = "/Library/NetBoot/NetBootSP0/NetBoot of Install macOS 10.12 Sierra.nbi/NBImageInfo.plist"
netboot:afpUsersMax = "50"

Boot to Your NetBoot Image

Next, you’ll want to have a computer boot to the NetBoot image you just created. Once upon a time, you would use the bless command to select a path to an image that you wanted to boot to in order to do so. Or you’d just boot holding down the N key and let the system pick an image. As of OS X 10.11, due to SIP restrictions, you’ll use the csrutil command to set a NetBoot address, continuing into macOS 10.12. To do so, run csrutil followed by the netboot option and then the add verb, followed by an address. In the following example, we’ll set the system to boot to the NetBoot server at

csrutil netboot add

Once you’ve finished any NetBoot workflows, use the remove verb to remove that address:

csrutil netboot remove

And to list any available NetBoot servers, use the list verb:

csrutil netboot list

Overall, all of this usually takes me a good 10 minutes of work, plus maybe up to half an hour of waiting for an image to create. You can use NetBoot to remotely boot systems, or NetInstall to remotely install systems. There are lots of articles out there (including here) on how to make sure clients can access these images over a network client, so I won’t rehash.

October 19th, 2016

Posted In: Mac OS X Server

Tags: , , , , , ,

Web Services in macOS Server, Linux and most versions of Unix are provided by Apache, an Open Source project that much of the Internet owes its origins to. Apache owes its name to the fact that it’s “a patchy” service. These patches are often mods, or modules. Configuring web services is as easy in macOS Server 5.2, running on Sierra (10.12), as it has ever been. To set up the default web portal, simply open the Server app, click on the Websites service and click on the ON button.


After a time, the service will start. Once running, click on the View Server Website link at the bottom of the pane.


Provided the stock macOS Server page loads, you are ready to use macOS Server as a web server.


Before we setup custom sites, there are a few things you should know. The first is, the server is no longer really designed to remove the default website. So if you remove the site, your server will exhibit inconsistent behavior. Also, don’t remove the files that comprise the default site. Instead just add sites, which is covered next. Webmail is gone. You don’t have to spend a ton of time looking for it as it isn’t there. Also, Mountain Lion Server added web apps, which we’ll briefly review later in this article as well, as those continue in Mavericks Server, Yosemite Server, El Capitan Server and ultimately macOS Server 5.2 for Sierra.  Finally, enabling PHP and Python on sites is done globally, so this setting applies to all sites hosted on the server.


Now that we’ve got that out of the way, let’s add our first custom site. Do so by clicking on the plus sign. At the New Web Site pane, you’ll be prompted for a number of options. The most important is the name of the site, with other options including the following:

  • Domain Name: The name the site is accessible from. The default sites do not have this option as they are accessible from all names that resolve to the server.
  • IP Address: The IP address the site listens on. Any means the site is available from every IP address the server is configured to use. The default websites do not have this option as they are accessible from all addresses automatically
  • Port: By default, sites without SSL run on port 80 on all network interfaces, and sites with SSL run on port 443 on all network interfaces. Use the Port field to use custom ports (e.g., 8080). The default sites do not have this option as they are configured to use 80 and 443 for default and SSL-based communications respectively.
  • SSL Certificate: Loads a list of SSL certificates installed using Keychain or the SSL Certificate option in the Settings pane of the Server application
  • Store Site Files In: The directory that the files that comprise the website are stored in. These can be placed into the correct directory using file shares or copying using the Finder. Click on the drop-down menu and then select Other to browse to the directory files are stored in.
  • Who Can Access: By default Anyone (all users, including unauthenticated guests) can access the contents of sites. Clicking on Anyone and then Customize… brings up the “Restrict access to the following folders to a chosen group” screen, where you can choose web directories and then define groups of users who can access the contents.
  • Additional Domains: Click on the Edit… button to bring up a simple list of domain names the the site also responds for (e.g. in addition to, add
  • Redirects: Click on the Edit… button to bring up a list of redirects within the site. This allows configuring redirects to other sites. For example, use /en to load or /cn to load
  • Aliases: Click on the Edit… button to load a list of aliases. This allows configuring redirects to folders within the same server. For example, /en loads /Library/Server/Web/Data/Sites/Default
  • Index Files: Click on the Edit… button to bring up a list of pages that are loaded when a page isn’t directly indicated. For example, when visiting, load the wp.php page by default.
  • Advanced Options: The remaining options are available by clicking on the “Edit Advanced Settings…” button.


The Advanced Option include the following:

  • Enable Server Side Includes: Allows administrators to configure leveraging includes in web files, so that pieces of code can be used across multiple pages in sites.
  • Allow overrides using .htaccess files: Using a .htaccess file allows administrators to define who is able to access a given directory, defining custom user names and passwords in the hidden .htaccess file. These aren’t usually required in an OS X Server web environment as local and directory-based accounts can be used for such operations. This setting enables using custom .htaccess files instead of relying on Apple’s stock web permissions.
  • Allow folder listing: Enables folder listings on directories of a site that don’t have an Index File (described in the non-Advanced settings earlier).
  • Allow CGI execution: Enables CGI scripts for the domain being configured.
  • Use custom error page: Allows administrators to define custom error pages, such as those annoying 404 error pages that load when a page can’t be found
  • Make these web apps available on this website: A somewhat advanced setting, loads items into the webapps array, which can be viewed using the following command:  sudo serveradmin settings web:definedWebApps

Once you’ve configured all the appropriate options, click on Done to save your changes. The site should then load. Sites are then listed in the list of Websites.

The Apache service is most easily managed from the Server app, but there are too many options in Apache to really be able to put into a holistic graphical interface. The easiest way to manage the Websites service in OS X Yosemite Server is using the serveradmin command. Apache administrators from other platforms will be tempted to use the apachectl command to restart the Websites service. Instead, use the serveradmin command to do so. To start the service:

sudo serveradmin start web

To stop the service(s):

sudo serveradmin stop web

And to see the status:

sudo serveradmin fullstatus web

Fullstatus returns the following information:

web:health = _empty_dictionary
web:readWriteSettingsVersion = 1
web:apacheVersion = “2.2”
web:servicePortsRestrictionInfo = _empty_array
web:startedTime = “2016-09-26 02:38:57 +0000”
web:apacheState = “RUNNING”
web:statusMessage = “”
web:ApacheMode = 2
web:servicePortsAreRestricted = “NO”
web:state = “RUNNING”
web:setStateVersion = 1

While the health option typically resembles kiosk computers in the Computer Science departments of most major universities, much of the rest of the output can be pretty helpful including the Apache version, whether the service is running, any restrictions on ports and the date/time stamp that the service was started.

To see all of the settings available to the serveradmin command, run it, followed by settings and then web, to indicate the Websites service:

sudo serveradmin settings web

The output is pretty verbose and can be considered in two sections, the first includes global settings across sites as well as the information for the default sites that should not be deleted:

web:defaultSite:documentRoot = “/Library/Server/Web/Data/Sites/Default”
web:defaultSite:serverName = “”
web:defaultSite:realms = _empty_dictionary
web:defaultSite:redirects = _empty_array
web:defaultSite:enableServerSideIncludes = no
web:defaultSite:networkAccesses = _empty_array
web:defaultSite:customLogPath = “"/var/log/apache2/access_log"”
web:defaultSite:webApps = _empty_array
web:defaultSite:sslCertificateIdentifier = “”
web:defaultSite:fullSiteRedirectToOtherSite = “https://%{SERVER_NAME}”
web:defaultSite:allowFolderListing = no
web:defaultSite:serverAliases = _empty_array
web:defaultSite:errorLogPath = “"/var/log/apache2/error_log"”
web:defaultSite:fileName = “/Library/Server/Web/Config/apache2/sites/0000_127.0.0.1_34580_.conf”
web:defaultSite:aliases = _empty_array
web:defaultSite:directoryIndexes:_array_index:0 = “index.html”
web:defaultSite:directoryIndexes:_array_index:1 = “index.php”
web:defaultSite:directoryIndexes:_array_index:2 = “default.html”
web:defaultSite:allowAllOverrides = no
web:defaultSite:identifier = “67127006”
web:defaultSite:port = 34580
web:defaultSite:allowCGIExecution = no
web:defaultSite:serverAddress = “”
web:defaultSite:requiresSSL = no
web:defaultSite:proxies = _empty_dictionary
web:defaultSite:errorDocuments = _empty_dictionary

The second section is per-site settings, with an array entry for each site:

web:customSites:_array_index:0:documentRoot = “/Library/Server/Web/Data/Sites/”
web:customSites:_array_index:0:serverName = “”
web:customSites:_array_index:0:realms = _empty_dictionary
web:customSites:_array_index:0:redirects = _empty_array
web:customSites:_array_index:0:enableServerSideIncludes = no
web:customSites:_array_index:0:networkAccesses = _empty_array
web:customSites:_array_index:0:customLogPath = “/var/log/apache2/access_log”
web:customSites:_array_index:0:webApps = _empty_array
web:customSites:_array_index:0:sslCertificateIdentifier = “”
web:customSites:_array_index:0:fullSiteRedirectToOtherSite = “”
web:customSites:_array_index:0:allowFolderListing = no
web:customSites:_array_index:0:serverAliases = _empty_array
web:customSites:_array_index:0:errorLogPath = “/var/log/apache2/error_log”
web:customSites:_array_index:0:fileName = “/Library/Server/Web/Config/apache2/sites/”
web:customSites:_array_index:0:aliases = _empty_array
web:customSites:_array_index:0:directoryIndexes:_array_index:0 = “index.html”
web:customSites:_array_index:0:directoryIndexes:_array_index:1 = “index.php”
web:customSites:_array_index:0:directoryIndexes:_array_index:2 = “default.html”
web:customSites:_array_index:0:allowAllOverrides = no
web:customSites:_array_index:0:identifier = “67127002”
web:customSites:_array_index:0:port = 34580
web:customSites:_array_index:0:allowCGIExecution = no
web:customSites:_array_index:0:serverAddress = “”
web:customSites:_array_index:0:requiresSSL = no
web:customSites:_array_index:0:proxies = _empty_dictionary
web:customSites:_array_index:0:errorDocuments = _empty_dictionary
web:dataLocation = “/Library/Server/Web/Data”

The next section (the largest by far) includes array entries for each defined web app. The following shows the entry for a Hello World Python app:

web:definedWebApps:_array_index:0:requiredWebAppNames = _empty_array
web:definedWebApps:_array_index:0:includeFiles:_array_index:0 = “/Library/Server/Web/Config/apache2/httpd_ACSServer.conf”
web:definedWebApps:_array_index:0:requiredModuleNames:_array_index:0 = “”
web:definedWebApps:_array_index:0:startCommand = “”
web:definedWebApps:_array_index:0:sslPolicy = 1
web:definedWebApps:_array_index:0:requiresSSL = no
web:definedWebApps:_array_index:0:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:0:launchKeys:_array_index:0 = “”
web:definedWebApps:_array_index:0:proxies:/AccountsConfigService/api/:path = “/AccountsConfigService/api/”
web:definedWebApps:_array_index:0:proxies:/AccountsConfigService/api/:urls:_array_index:0 = “http://localhost:31415/AccountsConfigService/api”
web:definedWebApps:_array_index:0:preflightCommand = “”
web:definedWebApps:_array_index:0:stopCommand = “”
web:definedWebApps:_array_index:0:name = “”
web:definedWebApps:_array_index:0:displayName = “”
web:definedWebApps:_array_index:1:requiredWebAppNames:_array_index:0 = “”
web:definedWebApps:_array_index:1:includeFiles:_array_index:0 = “/Library/Server/Web/Config/apache2/httpd_corecollaboration_webauth.conf”
web:definedWebApps:_array_index:1:requiredModuleNames:_array_index:0 = “proxy_module”
web:definedWebApps:_array_index:1:requiredModuleNames:_array_index:1 = “headers_module”
web:definedWebApps:_array_index:1:startCommand = “”
web:definedWebApps:_array_index:1:sslPolicy = 4
web:definedWebApps:_array_index:1:requiresSSL = no
web:definedWebApps:_array_index:1:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:1:launchKeys = _empty_array
web:definedWebApps:_array_index:1:proxies:/auth:path = “/auth”
web:definedWebApps:_array_index:1:proxies:/auth:urls:_array_index:0 = “http://localhost:4444/auth”
web:definedWebApps:_array_index:1:preflightCommand = “”
web:definedWebApps:_array_index:1:stopCommand = “”
web:definedWebApps:_array_index:1:name = “”
web:definedWebApps:_array_index:1:displayName = “”
web:definedWebApps:_array_index:2:requiredWebAppNames:_array_index:0 = “”
web:definedWebApps:_array_index:2:includeFiles:_array_index:0 = “/Library/Server/Web/Config/apache2/httpd_corecollaboration_webcalssl.conf”
web:definedWebApps:_array_index:2:requiredModuleNames:_array_index:0 = “proxy_module”
web:definedWebApps:_array_index:2:requiredModuleNames:_array_index:1 = “headers_module”
web:definedWebApps:_array_index:2:startCommand = “”
web:definedWebApps:_array_index:2:sslPolicy = 1
web:definedWebApps:_array_index:2:requiresSSL = no
web:definedWebApps:_array_index:2:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:2:launchKeys = _empty_array
web:definedWebApps:_array_index:2:proxies = _empty_dictionary
web:definedWebApps:_array_index:2:preflightCommand = “”
web:definedWebApps:_array_index:2:stopCommand = “”
web:definedWebApps:_array_index:2:name = “”
web:definedWebApps:_array_index:2:displayName = “”
web:definedWebApps:_array_index:3:requiredWebAppNames:_array_index:0 = “”
web:definedWebApps:_array_index:3:includeFiles:_array_index:0 = “/Library/Server/Web/Config/apache2/httpd_corecollaboration_changepassword.conf”
web:definedWebApps:_array_index:3:requiredModuleNames:_array_index:0 = “proxy_module”
web:definedWebApps:_array_index:3:requiredModuleNames:_array_index:1 = “headers_module”
web:definedWebApps:_array_index:3:startCommand = “”
web:definedWebApps:_array_index:3:sslPolicy = 4
web:definedWebApps:_array_index:3:requiresSSL = no
web:definedWebApps:_array_index:3:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:3:launchKeys = _empty_array
web:definedWebApps:_array_index:3:proxies:/changepassword:path = “/changepassword”
web:definedWebApps:_array_index:3:proxies:/changepassword:urls:_array_index:0 = “http://localhost:4444/changepassword”
web:definedWebApps:_array_index:3:preflightCommand = “”
web:definedWebApps:_array_index:3:stopCommand = “”
web:definedWebApps:_array_index:3:name = “”
web:definedWebApps:_array_index:3:displayName = “”
web:definedWebApps:_array_index:4:requiredWebAppNames = _empty_array
web:definedWebApps:_array_index:4:includeFiles:_array_index:0 = “/Library/Server/Web/Config/apache2/httpd_corecollaboration_shared.conf”
web:definedWebApps:_array_index:4:requiredModuleNames:_array_index:0 = “proxy_module”
web:definedWebApps:_array_index:4:requiredModuleNames:_array_index:1 = “xsendfile_module”
web:definedWebApps:_array_index:4:requiredModuleNames:_array_index:2 = “headers_module”
web:definedWebApps:_array_index:4:requiredModuleNames:_array_index:3 = “expires_module”
web:definedWebApps:_array_index:4:requiredModuleNames:_array_index:4 = “deflate_module”
web:definedWebApps:_array_index:4:startCommand = “”
web:definedWebApps:_array_index:4:sslPolicy = 0
web:definedWebApps:_array_index:4:requiresSSL = no
web:definedWebApps:_array_index:4:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:4:launchKeys:_array_index:0 = “”
web:definedWebApps:_array_index:4:launchKeys:_array_index:1 = “”
web:definedWebApps:_array_index:4:proxies:/collabdproxy:path = “/collabdproxy”
web:definedWebApps:_array_index:4:proxies:/collabdproxy:urls:_array_index:0 = “http://localhost:4444/svc”
web:definedWebApps:_array_index:4:proxies:/__collabd/streams/activity:path = “/__collabd/streams/activity”
web:definedWebApps:_array_index:4:proxies:/__collabd/streams/activity:urls:_array_index:0 = “http://localhost:4444/streams/activity”
web:definedWebApps:_array_index:4:preflightCommand = “”
web:definedWebApps:_array_index:4:stopCommand = “”
web:definedWebApps:_array_index:4:name = “”
web:definedWebApps:_array_index:4:displayName = “”
web:definedWebApps:_array_index:5:requiredWebAppNames:_array_index:0 = “”
web:definedWebApps:_array_index:5:includeFiles = _empty_array
web:definedWebApps:_array_index:5:requiredModuleNames = _empty_array
web:definedWebApps:_array_index:5:startCommand = “”
web:definedWebApps:_array_index:5:sslPolicy = 0
web:definedWebApps:_array_index:5:requiresSSL = no
web:definedWebApps:_array_index:5:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:5:launchKeys:_array_index:0 = “”
web:definedWebApps:_array_index:5:launchKeys:_array_index:1 = “”
web:definedWebApps:_array_index:5:proxies = _empty_dictionary
web:definedWebApps:_array_index:5:preflightCommand = “”
web:definedWebApps:_array_index:5:stopCommand = “”
web:definedWebApps:_array_index:5:name = “”
web:definedWebApps:_array_index:5:displayName = “”
web:definedWebApps:_array_index:6:requiredWebAppNames = _empty_array
web:definedWebApps:_array_index:6:includeFiles = _empty_array
web:definedWebApps:_array_index:6:requiredModuleNames:_array_index:0 = “php5_module”
web:definedWebApps:_array_index:6:startCommand = “”
web:definedWebApps:_array_index:6:sslPolicy = 0
web:definedWebApps:_array_index:6:requiresSSL = no
web:definedWebApps:_array_index:6:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:6:launchKeys = _empty_array
web:definedWebApps:_array_index:6:proxies = _empty_dictionary
web:definedWebApps:_array_index:6:preflightCommand = “”
web:definedWebApps:_array_index:6:stopCommand = “”
web:definedWebApps:_array_index:6:name = “”
web:definedWebApps:_array_index:6:displayName = “”
web:definedWebApps:_array_index:7:requiredWebAppNames = _empty_array
web:definedWebApps:_array_index:7:includeFiles:_array_index:0 = “/Library/Server/Web/Config/apache2/httpd_webdavsharing.conf”
web:definedWebApps:_array_index:7:requiredModuleNames:_array_index:0 = “rewrite_module”
web:definedWebApps:_array_index:7:requiredModuleNames:_array_index:1 = “bonjour_module”
web:definedWebApps:_array_index:7:startCommand = “”
web:definedWebApps:_array_index:7:sslPolicy = 0
web:definedWebApps:_array_index:7:requiresSSL = no
web:definedWebApps:_array_index:7:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:7:launchKeys = _empty_array
web:definedWebApps:_array_index:7:proxies = _empty_dictionary
web:definedWebApps:_array_index:7:preflightCommand = “”
web:definedWebApps:_array_index:7:stopCommand = “”
web:definedWebApps:_array_index:7:name = “”
web:definedWebApps:_array_index:7:displayName = “”
web:definedWebApps:_array_index:8:requiredWebAppNames:_array_index:0 = “”
web:definedWebApps:_array_index:8:requiredWebAppNames:_array_index:1 = “”
web:definedWebApps:_array_index:8:includeFiles:_array_index:0 = “/Library/Server/Web/Config/apache2/httpd_corecollaboration_wiki.conf”
web:definedWebApps:_array_index:8:requiredModuleNames:_array_index:0 = “proxy_module”
web:definedWebApps:_array_index:8:requiredModuleNames:_array_index:1 = “headers_module”
web:definedWebApps:_array_index:8:startCommand = “”
web:definedWebApps:_array_index:8:sslPolicy = 0
web:definedWebApps:_array_index:8:requiresSSL = no
web:definedWebApps:_array_index:8:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:8:launchKeys:_array_index:0 = “”
web:definedWebApps:_array_index:8:launchKeys:_array_index:1 = “”
web:definedWebApps:_array_index:8:proxies:/__collabd/preview:path = “/__collabd/preview”
web:definedWebApps:_array_index:8:proxies:/__collabd/preview:urls:_array_index:0 = “http://localhost:4444/preview”
web:definedWebApps:_array_index:8:proxies:/wiki/files/upload:path = “/wiki/files/upload”
web:definedWebApps:_array_index:8:proxies:/wiki/files/upload:urls:_array_index:0 = “http://localhost:4444/upload_file”
web:definedWebApps:_array_index:8:proxies:/wiki/files/download:path = “/wiki/files/download”
web:definedWebApps:_array_index:8:proxies:/wiki/files/download:urls:_array_index:0 = “http://localhost:4444/files”
web:definedWebApps:_array_index:8:proxies:/wiki/ipad:path = “/wiki/ipad”
web:definedWebApps:_array_index:8:proxies:/wiki/ipad:urls = _empty_array
web:definedWebApps:_array_index:8:proxies:/wiki:path = “/wiki”
web:definedWebApps:_array_index:8:proxies:/wiki:urls:_array_index:0 = “http://localhost:4444/app-context/wiki”
web:definedWebApps:_array_index:8:preflightCommand = “”
web:definedWebApps:_array_index:8:stopCommand = “”
web:definedWebApps:_array_index:8:name = “”
web:definedWebApps:_array_index:8:displayName = “”
web:definedWebApps:_array_index:9:requiredWebAppNames = _empty_array
web:definedWebApps:_array_index:9:includeFiles:_array_index:0 = “/Library/Server/Web/Config/apache2/httpd_wsgi.conf”
web:definedWebApps:_array_index:9:requiredModuleNames:_array_index:0 = “wsgi_module”
web:definedWebApps:_array_index:9:startCommand = “”
web:definedWebApps:_array_index:9:sslPolicy = 0
web:definedWebApps:_array_index:9:requiresSSL = no
web:definedWebApps:_array_index:9:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:9:launchKeys = _empty_array
web:definedWebApps:_array_index:9:proxies = _empty_dictionary
web:definedWebApps:_array_index:9:preflightCommand = “”
web:definedWebApps:_array_index:9:stopCommand = “”
web:definedWebApps:_array_index:9:name = “”
web:definedWebApps:_array_index:9:displayName = “Python "Hello World" app at /wsgi”
web:definedWebApps:_array_index:10:requiredWebAppNames = _empty_array
web:definedWebApps:_array_index:10:includeFiles:_array_index:0 = “/Library/Developer/XcodeServer/CurrentXcodeSymlink/Contents/Developer/usr/share/xcs/httpd_xcs.conf”
web:definedWebApps:_array_index:10:requiredModuleNames = _empty_array
web:definedWebApps:_array_index:10:startCommand = “”
web:definedWebApps:_array_index:10:sslPolicy = 4
web:definedWebApps:_array_index:10:requiresSSL = no
web:definedWebApps:_array_index:10:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:10:launchKeys = _empty_array
web:definedWebApps:_array_index:10:proxies = _empty_dictionary
web:definedWebApps:_array_index:10:preflightCommand = “”
web:definedWebApps:_array_index:10:stopCommand = “”
web:definedWebApps:_array_index:10:name = “”
web:definedWebApps:_array_index:10:displayName = “”
web:definedWebApps:_array_index:11:requiredWebAppNames:_array_index:0 = “com.example.webapp.myotherwebapp”
web:definedWebApps:_array_index:11:includeFiles:_array_index:0 = “/Library/Server/Web/Config/apache2/httpd_myinclude.conf”
web:definedWebApps:_array_index:11:requiredModuleNames:_array_index:0 = “mystuff_module”
web:definedWebApps:_array_index:11:startCommand = “/usr/local/bin/startmywebapp”
web:definedWebApps:_array_index:11:sslPolicy = 0
web:definedWebApps:_array_index:11:requiresSSL = no
web:definedWebApps:_array_index:11:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:11:launchKeys:_array_index:0 = “com.example.mywebapp”
web:definedWebApps:_array_index:11:proxies:/mywebapp:path = “/mywebapp”
web:definedWebApps:_array_index:11:proxies:/mywebapp:urls:_array_index:0 = “http://localhost:3000”
web:definedWebApps:_array_index:11:proxies:/mywebapp:urls:_array_index:1 = “http://localhost:3001”
web:definedWebApps:_array_index:11:preflightCommand = “/usr/local/bin/preflightmywebapp”
web:definedWebApps:_array_index:11:stopCommand = “/usr/local/bin/stopmywebapp”
web:definedWebApps:_array_index:11:name = “com.example.mywebapp”
web:definedWebApps:_array_index:11:displayName = “MyWebApp”

The final section defines the settings used for the default sites as well as a couple of host based settings:

web:defaultSecureSite:documentRoot = “/Library/Server/Web/Data/Sites/Default”
web:defaultSecureSite:serverName = “”
web:defaultSecureSite:realms = _empty_dictionary
web:defaultSecureSite:redirects = _empty_array
web:defaultSecureSite:enableServerSideIncludes = no
web:defaultSecureSite:networkAccesses = _empty_array
web:defaultSecureSite:customLogPath = “"/var/log/apache2/access_log"”
web:defaultSecureSite:webApps = _empty_array
web:defaultSecureSite:sslCertificateIdentifier = “”
web:defaultSecureSite:fullSiteRedirectToOtherSite = “”
web:defaultSecureSite:allowFolderListing = no
web:defaultSecureSite:serverAliases = _empty_array
web:defaultSecureSite:errorLogPath = “"/var/log/apache2/error_log"”
web:defaultSecureSite:fileName = “/Library/Server/Web/Config/apache2/sites/0000_127.0.0.1_34543_.conf”
web:defaultSecureSite:aliases = _empty_array
web:defaultSecureSite:directoryIndexes:_array_index:0 = “index.html”
web:defaultSecureSite:directoryIndexes:_array_index:1 = “index.php”
web:defaultSecureSite:directoryIndexes:_array_index:2 = “default.html”
web:defaultSecureSite:allowAllOverrides = no
web:defaultSecureSite:identifier = “67127004”
web:defaultSecureSite:port = 34543
web:defaultSecureSite:allowCGIExecution = no
web:defaultSecureSite:serverAddress = “”
web:defaultSecureSite:requiresSSL = yes
web:defaultSecureSite:proxies = _empty_dictionary
web:defaultSecureSite:errorDocuments = _empty_dictionary
web:mainHost:keepAliveTimeout = 15.000000
web:mainHost:maxClients = “256”

Each site has its own configuration file defined in the array for each section. By default these are stored in the /Library/Server/Web/Config/apache2/sites directory, with /Library/Server/Web/Config/apache2/sites/ being the file for the custom site we created previously. As you can see, many of the options available in the Server app are also available in these files:

DocumentRoot "/Library/Server/Web/Data/Sites/"
DirectoryIndex index.html index.php /wiki/ default.html
CustomLog /var/log/apache2/access_log combinedvhost
ErrorLog /var/log/apache2/error_log
SSLEngine Off
SSLProtocol -ALL +SSLv3 +TLSv1
SSLProxyEngine On
SSLProxyProtocol -ALL +SSLv3 +TLSv1

Options All -Indexes -ExecCGI -Includes +MultiViews
AllowOverride None


Deny from all
ErrorDocument 403 /customerror/websitesoff403.html

The serveradmin command can also be used to run commands. For example, to reset the service to factory defaults, delete the configuration files for each site and then run the following command:

sudo serveradmin command web:command=restoreFactorySettings

The final tip I’m going to give in this article is when to make changes with each app. I strongly recommend making all of your changes in the Server app when possible. When it isn’t, use serveradmin and when you can’t make changes in serveradmin, only then alter the configuration files that come with the operating system by default. For example, in this article I look at overriding some ports for some virtual sites that might conflict with other sites on your systems. I also recommend keeping backups of all configuration files that are altered and a log of what was altered in each, in order to help piece the server back together should it become unconfigured miraculously when a softwareupdate -all is run next.

October 18th, 2016

Posted In: Mac OS X Server

Tags: , , , , ,

A wiki is a repository of dynamically created and managed content, or content created or edited by multiple users collaboratively. This article is about using the wiki service in macOS Server 5.2 (the Apple Server app running on 10.12/Sierra). I reference file services with WebDAV because it is a very nice integration piece that I think a lot of people will find pretty beneficial.

To get started with the Wiki service, first turn it on. This one isn’t heavily dependent on host names (other than being able to access the server from a browser) or directory services (other than being able to authenticate users, but local accounts are perfectly functional) and it doesn’t require the Websites service to be running as well. One should always have good working directory services and host names, still…

To enable the service, open the Server app and click on Wiki in the list of SERVICES in the List Pane.


There are two configuration options. The first is to select who is able to create wikis. Use the “Wikis can be created by” drop-down list to select “all users” if anyone with an account on the server should be able to create a wiki or “only some users” to bring up the Wiki Creators screen.


If only some users can create new wikis, use the plus sign (“+”) at the Wiki Creators screen to add users and/or groups to the list of users that can create wikis. Click on OK when all users and groups that can create wikis are added. In a school I would imagine that only teachers or IT staff would be able to create wikis. Once a wiki is created, pages inside the wiki can still be created by non-wiki creators.

The other option available is the handy dandy WebDAV interface to the wikis. When you enable this option, you can connect to a server from OS X or iOS via WebDAV and access files in each wikis document repository. To be clear, this option doesn’t provide access to the user documents, but does provide access to the wiki documents. We’re going to check the box for “Enable WebDAV access to Wiki files” and then click the ON button.

Once the service starts, click on the View Wiki link in the Wiki workspace in Server app.


Here, click on the Log in button and enter a user with access to the server, preferably one who can create wikis.


At the Wikis page, you will then see a list of all wikis you have access to. Note that the previous screen showed one wiki and now we see two. That’s because one of the wikis has permissions that allow “All unauthenticated users” access to the wiki, which we’ll describe shortly. The first thing most administrators will do is create a wiki. To do so, click on the plus sign (“+”) icon on the web page and at the resultant screen, click on New Wiki.


At the “Create a new wiki” prompt, provide a name for the wiki and a brief description for it.


Click on Continue.


At the Set permissions screen, enter each user or group to provide access to edit and view wiki pages. Here, you’ll have the options for Read & Write (users can view and edit pages in the wiki), Read only (users can only view the contents of your pages) and No access (users have no access to the wiki). There is a group for All logged in users, which includes every user with access to the server and another for All unauthorized users, which includes guests to the server. Once you’ve given the appropriate permissions, click on Continue.
Note: You don’t have to get this perfect now as you can always edit these later.


At the Set Appearance screen, you can choose an icon for the wiki (shown in the wiki list and when you open the wiki) as well as a color scheme for the wiki. Choose the appropriate appearance for your wiki (again, you can always change this later) and then click on the Create button.


Once the setup is finished, you’ll see the Setup complete modal. Here, you can click on Go to Wiki button.


Once you’ve created your first wiki, let’s edit it and customize the content. To do so, click on it from the list of available wikis. Click on the cog-wheel icon and then Wiki Settings… to bring up the Wiki Settings page.


Here, you’ll see the previously entered name and description as well as options to enable Calendar (only available if Calendar Server is running on the server) and Blog, which enables  a blog service for the wiki (wiki administrators can post blog entries to the wiki). Click on Appearance.


Here, you will have the previous two options as well as the ability to upload a banner (which should be 62 pixels high) and background for each wiki.


Click on Permissions. Here, you’ll see the permissions previously configured as well as options to configure who can comment on articles (nobody disables comments completely) in the wiki and whether comments require approval (moderation).

Click on Save. Now, let’s edit the splash page. To do so, click the pencil icon in the top navigation bar.


At the edit screen, the top nav bar is replaced by a WYSIWIG editor for managing the page. Here you can justify, link, insert media and of course edit the text you see on the screen. I recommend spending some time embedding links, inserting tables, making text look like you want it to and editing the content to reflect the purpose of the wiki. Click Save when you’re done. Click the pencil again to edit it, and let’s create a new wiki page. Keep in mind that link wikipedia, each page should be linked to from other pages in the order they should be read. Unlike most wikis, there’s actually an index page of all the articles, which can come in handy.


From the edit page, to create a new page and link to it, enter some text (or lasso some) that you’ll use as the link to access the new page you’re creating. Then click on the arrow and select “New page.”

Note: Use Enter URL to link to an existing page or an external website, instead of creating a new page.


At the New Page screen, provide a name for the new page (the lasso’d text automatically appears as the Page Title) and click on the Add button.


Click Save and then click on the newly created link. You can now edit the new page the same way you edited the previous pages. Click on the disclosure triangles in the right sidebar to Comment on articles, link articles to related articles, tag articles and view editing history.


Now for the fun part. Click on Documents. Here, you’ll see the pages you already created. Click on the plus sign and select the option to Upload File to the wiki.


At the Upload File dialog, click on Choose File and then select a file to upload.


Click Upload when selected.


Then from the Finder of a macOS client, use the Go menu to select “Connect to Server”. Enter the name or IP of the server and then click on Connect.

Assuming you can access the server, you should then be prompted for a username and password. Enter it and click Connect. Eventually, the file(s) will display (it can take awhile according to your network speeds and how many files are in the directory). You can connect to this same screen through an iPad using a 3rd party WebDAV client or the build in options in Pages.

Managing wikis is as easy as its ever been, with the new options for appearance being a nice add-on. Active Directory integration is as easy as binding the server to Active Directory and using the accounts listed in Permissions of pages.

Now that iOS devices can edit wikis and many of the traditional word processing options are available in the wiki editor, consider what the Wiki can be. Could it replace text editing apps for iOS? Could the Wiki allow for more collaborative documents than a Word or other document editor? Could it keep from getting eaten like the rest of the homework? Could the comments in the Wiki be a good way for teachers to have students write responses to materials? Could the Wiki and the document management features allow your workers to access human resources documents and employee manuals? I know plenty of tech firms that use wikis to track information about the systems they manage.

Once you have all of this information, upgrading can seem downright scary. But fear not, there’s Carbon Copy Cloner. And once you’ve cloned, there’s wikiadmin. When doing an upgrade in place, the Wiki service is pretty straight forward to upgrade, but in many cases, due to aging hardware, wiki services are moving from an older computer to a newer computer. This can be done in one of two ways. The first is to “migrate” the data by copying the Collaboration folder onto the new system. The second is to “export” and “import” the data. I usually recommend doing a migrate where possible, so we’ll start with that method.

Note: Before getting started, make sure that the directory services side of things is good. If a user or group lookup for an object that owns, edits or has commented on a wiki fails then that wiki probably shouldn’t be migrated. Use the dscl or id commands to confirm that lookups are functioning as intended.

To migrate wikis from one server to another, first copy the Collaboration directory to the new server. In this example, the directory has been dropped onto the desktop of the currently logged in user. To migrate the data once copied, use the wikiadmin command, along with the migration option. The option requires the path to the Collaboration folder, defined with -r, as follows:

sudo wikiadmin migrate -r ~/Desktop/Collaboration

When moving wikis, you can take the opportunity to get rid of a few you don’t want (such as that test wiki from way back when). Or administrators may just choose to move a single wiki to a new server in order to split the load across multiple hosts. When doing so, use the same command as earlier, along with the name of each wiki that is being moved, along with the -g option. For example, if moving the Legal wiki:

sudo wikiadmin migrate -r ~/Desktop/Collaboration -g Legal

The second way of moving wikis around is to export and then import them. To do so, first export wikis on the old server, using the wikiadmin command along with the export option, which requires an –exportPath option and needs to be done, on a wiki-by-wiki basis. So to export that Legal wiki to a file called LegalWikiTMP on the desktop:

sudo wikiadmin export -g Legal --exportPath ~/Desktop/LegalWikiTMP

Next, copy the wiki to the new server and import it, using the import option along with –importPath to identify where the file being imported is located. Using the same location, the command would then be:

sudo wikiadmin import -g Legal --importPath ~/Desktop/LegalWikiTMP

Note: The ability to import a wiki also allows for an API of sorts, as you can programmatically create wikis from other sources. The ability to export also provides a way to move into another wiki tool if you happen to outgrow the options provided in Server and need to move to something more robust.

There is another way to move wikis, using pg_dump, copying the data and then using pg_restore to import the data once you’ve created the tables.  This way is, in my opinion, the last resort if the standard wikiadmin commands aren’t working. In my experience, if I’m doing the migration this way then I’ve got other, bigger issues that I need to deal with as well.

These commands work best when the wiki service has been started so that the databases are fully built out. To start the wiki service from the command line, use the serveradmin command instead of the wikiadmin command. The serveradmin command is used with the start option and then wiki is used to indicate the wiki service, as follows:

sudo serveradmin start wiki

The service can also be stopped, swapping out the start option with a stop option:

sudo serveradmin stop wiki

In a few cases (this is the main reason I’m writing this article), the attachments to wikis don’t come over during a migration. To migrate the files that are used for QuickLook, downloading attachments, etc, use the serveradmin command to locate the directory that these objects are stored in:

sudo serveradmin settings wiki:FileDataPath

The output identifies the directory where these objects are stored. Placing the contents in the same relative path as they are to the output of the same command on the target server usually results in restoring them. Once moved, use the fixPermissions option to repair the permissions of any files from the source (if any changes to account IDs are encountered such as an export/import rather than an archive/restore in OD this can lead to odd issues:

sudo wikiadmin fixPermissions

Also use the rebuildSearchIndex option with the wikiadmin command to fix any indexing, once the permissions have been repaired:

sudo wikiadmin rebuildSearchIndex

And finally use resetQuicklooks to clear any cached Quicklook representations of objects that have been inserted into a wiki and might not display properly using Quicklook (you know you might need to do this if they look fine when downloaded but look bad with Quicklook even though QuickLook on the server can view the files just fine):

sudo wikiadmin resetQuicklooks

When done properly the migration can take awhile. Keep in mind that every tag, every article, every edit to every article and basically everything else is tracked inside the tables that you’re moving. While there might not be a ton of data in the Collaboration directory or in an export, all of the data needs to go to the right location. This can take a little time in environments that have a lot of articles, even if they’re really short articles…

October 17th, 2016

Posted In: Mac OS X Server

Tags: , , , , , , , ,

macOS Server has long had a VPN service to allow client computers to connect to a network even when they’re out of the office. The server was once capable of running the two most commonly used VPN protocols: PPTP and L2TP. And while PPTP is still accessible via the command line, L2TP is now configured by default when you setup the server using the Server app.

Setting Up The VPN Service In OS X Server

To setup the VPN service, open the Server app and click on VPN in the Server app sidebar. The VPN Settings  screen has a number of options available, as seen here.


The VPN Host Name field is used by administrators leveraging profiles. The setting used becomes the address for the VPN service in the Everyone profile. L2TP requires a shared secret or an SSL certificate. In this example, we’ll configure a shared secret by providing a password in the Shared Secret field. Additionally, there are three fields, each with an Edit button that allows for configuration:

  • Client Addresses: The dynamic pool of addresses provided when clients connect to the VPN.


  • DNS Settings: The name servers used once a VPN client has connected to the server. As well as the Search Domains configuration.


  • Routes: Select which interface (VPN or default interface of the client system) that a client connects to each IP address and subnet mask over.


  • Save Configuration Profile: Use this button to export configuration profiles to a file, which can then be distributed to client systems (macOS using the profiles command, iOS using Apple Configurator or both using Profile Manager).
  • Shared Secret: A passphrase that must be supplied by the client prior to getting a username and password prompt.

Once configured, open incoming ports on the router/firewall. While deprecated(ish) PPTP runs over port 1723. L2TP is a bit more complicated, running over 1701, but also the IP-ESP protocol (IP Protocol 50). Both are configured automatically when using Apple AirPorts as gateway devices. Officially, the ports to forward are listed at

Using The Command Line

I know, I’ve described ways to manage these services from the command line before. The serveradmin command can be used to manage the service as well as the Server app. The serveradmin command can start the service, using the default settings, with no further configuration being required:

sudo serveradmin start vpn

And to stop the service:

sudo serveradmin stop vpn

And to list the available options:

sudo serveradmin settings vpn

The output of which shows all of the VPN settings available via serveradmin (which is many more than what you see in the Server app:

vpn:vpnHost = "" = "/var/log/ppp/vpnd.log" = 1 = 128 = "jamfsw.corp" = "" = "" = "" = "1" = "" = "2" = "" = "vpn/" = no = "PPTP" = "PPP" = 5 = 1 = "EAP-RSA" = "DSACL" = 1 = 0 = 1 = 1 = 60 = 1 = "MSCHAP2" = 0 = "DSAuth" = "/var/log/ppp/vpnd.log" = 1 = 7200 = "MPPE" = _empty_array = "" = "" = _empty_array = _empty_array = "Manual" = "" = 128 = 0 = "/var/log/ppp/vpnd.log" = 1 = "jamfsw.corp" = "" = "" = "" = "1" = "" = "2" = "" = "vpn/" = yes = "L2TP" = "PPP" = 5 = 1 = "EAP-KRB" = "DSACL" = 1 = 0 = 1 = 60 = 1 = "MSCHAP2" = "DSAuth" = "/var/log/ppp/vpnd.log" = 7200 = "Keychain" = "" = "" = "SharedSecret" = "" = "None" = <> = _empty_array = "" = "" = _empty_array = _empty_array = "Manual" = "IPSec" = "Yq!XdGsVyAY?o;9jnj[X"

To disable L2TP, set to no:

sudo serveradmin settings = no

To configure how long a client can be idle prior to being disconnected:

sudo serveradmin settings = 10

By default, each protocol has a maximum of 128 sessions, configureable using

sudo serveradmin settings = 200

To see the state of the service, the pid, the time the service was configured, the path to the log files, the number of clients and other information, use the fullstatus option:

sudo serveradmin fullstatus vpn

Which returns output similar to the following:

vpn:servicePortsAreRestricted = "NO"
vpn:readWriteSettingsVersion = 1 = "MSCHAP2" = 0 = yes = "MPPEKeySize128" = "PPP" = "PPTP" = "DSAuth" = "MSCHAP2" = "PPP" = yes = 0 = "L2TP" = "DSAuth"
vpn:servicePortsRestrictionInfo = _empty_array
vpn:health = _empty_dictionary
vpn:logPaths:vpnLog = "/var/log/ppp/vpnd.log"
vpn:configured = yes
vpn:state = "STOPPED"
vpn:setStateVersion = 1

Security folk will be stoked to see that the shared secret is shown in the clear using:

Configuring Users For VPN Access

Each account that accesses the VPN server needs a valid account to do so. To configure existing users to use the service, click on Users in the Server app sidebar.


At the list of users, click on a user and then click on the cog wheel icon, selecting Edit Access to Services.


At the Service Access screen will be a list of services that could be hosted on the server; verify the checkbox for VPN is highlighted for the user. If not, click Manage Service Access, click Manage and then check the VPN box.


Setting Up Client Computers

As you can see, configuring the VPN service in macOS Server 5.2 (running on Sierra) is a simple and straight-forward process – much easier than eating your cereal with a fork and doing your homework in the dark.. Configuring clients is as simple as importing the profile generated by the service. However, you can also configure clients manually. To do so on a Mac, open the Network System Preference pane. From here, click on the plus sign (“+”) to add a new network service.


At the prompt, select VPN in the Interface field and then either PPTP or L2TP over IPSec in the VPN Type. Then provide a name for the connection in the Service Name field and click on Create.


At the list of network interfaces in the Network System Preference pane, provide the hostname or address of the server in the Server Address field and the username that will be connecting to the VPN service in the Account Name field. If using L2TP, click on Authentication Settings.


At the prompt, provide the password entered into the Shared Secret field earlier in this article in the Machine Authentication Shared Secret field and the user’s password in the User Authentication Password field. When you’re done, click OK and then provided you’re outside the network and routeable to the server, click on Connect to test the connection.


Setting Up the VPN service in macOS Server 5.2 is as simple as clicking the ON button. But much more information about using a VPN can be required. The natd binary is still built into OS X at /usr/sbin/natd and can be managed in a number of ways. And if you’re using an Apple AirPort as a router (hopefully in a very small environment) then the whole process of setting this thing up should be super-simple.

October 16th, 2016

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

Tags: , , , , , , ,

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.


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.


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.


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.


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.

October 15th, 2016

Posted In: Mac OS X, Mac OS X Server, Time Machine

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

Mac Server Services

 RhapsodyMac Server 1Server 10.2OS X Server 10.3OS X Server 10.4OS X Server 10.5Mountain Lion Server (10.6)Lion Server (10.7)Server 2 (10.8)Server 3 (10.9)Server 4 (10.10)Server 5 (10.11)macOS Server 5.2 (10.12)
# of Services1091315192424221821212121
Web ServicesWebWebWebWebWebWebWebWebWebsitesWebsitesWebsitesWebsitesWebsites
Directory ServersNetInfoNetInfoDirectory ServicesOpen DirectoryOpen DirectoryOpen DirectoryOpen DirectoryOpen DirectoryOpen DirectoryOpen DirectoryOpen DirectoryOpen DirectoryOpen Directory
NetBoot ServicesNetBootNetBootNetBootNetBootNetBootNetBootNetBootNetBootNetInstallNetInstallNetInstallNetInstallNetInstall
Windows File Sharing/SMBWindowsWindowsWindowsSMBSMBSMBSMBSMBSMBSMBSMB
Mail ServicesMailMailMailMailMailMailMailMailMailMailMail
Software Update ServicesSoftware UpdateSoftware UpdateSoftware UpdateSoftware UpdateSoftware UpdateSoftware UpdateSoftware UpdateSoftware UpdateSoftware Update
Shared Calendars/CalDAViCaliCaliCalCalendarCalendarCalendarCalendarCalendar
Wiki and BlogsWikiWikiWikiWikiWikiWikiWikiWiki
Shared Contacts/CardDAVAddress BookAddress BookContactsContactsContactsContactsContacts
Backup ServicesTime MachineTime MachineTime MachineTime MachineTime MachineTime Machine
Management ServicesProfile ManagerProfile ManagerProfile ManagerProfile ManagerProfile ManagerProfile Manager
Storage NetworkingXsanXsanXsanXsanXsan
Content and Update Caching ServicesCachingCachingCachingCaching
Continuous Development ServicesXcodeXcodeXcodeXcode
OG Management ServicesMacintosh ManagerMacintosh Manager
Web ObjectsWeb Objects (separate media)Web ObjectsWeb ObjectsWeb Objects
Web Application ServicesApplication ServerApplication ServerTomcatTomcat
Printing ServicesPrintPrintPrintPrintPrintPrint
High Performance Computing ServicesXgridXgridXgridXgrid
PodcastingPodcast ProducerPodcast ProducerPodcast
Proxy ServicesMobile Access
Database ServingMySQL

October 14th, 2016

Posted In: Mac OS X Server

Tags: , , , , , ,

Next Page »