List the local user accounts whose UIDs are greater than 100

Here’s an example of how you can use the DirectoryService dscl utility to find which local user accounts have UIDs greater than 100. These users are by convention most likely to be non-system accounts, and therefore of interest for some tasks in a tool like Applejack. (I pulled this example from some comments in the Applejack 1.4.3 source.)

$ dscl /Local/Default -list /Users UniqueID | awk '$2 >= 100 { print $1; }'
supersecretadminaccount
christen
jeremy
elijah
demoguy

What’s going on in this example?

I’m getting a list of users from the default local DirectoryService node, whose path is /Local/Default. The output of this step gives you all of the local user accounts’ short usernames, followed by their UIDs, because that’s the property I was requesting. The data is arranged in two columns.

A drop into awk can make quick work of processing this columnar data, so I pipe the output of the first command in. Taking the output of dscl, I wanted to find whether the number in the second column was greater than or equal to 100, so I compare $2 to the desired number. When the UID column’s data matches, I print out only the short username from the first column, $1.

This gives you a list of usernames whose UIDs are greater than or equal to 100. The output is one per line, which is what you want if you have further processing steps.

“UniqueID” is the DirectoryService record type for UID. You could also use “uid” instead, and in this instance I’ve found that it works equally well.

$ dscl /Local/Default -list /Users uid | awk '$2 >= 100 { print $1; }'
supersecretadminaccount
christen
jeremy
elijah
demoguy

Substituting “uid” for “UniqueID” may not always work. It probably will in most cases, since the output is formatted similarly, but it depends on what subsequent processing steps are expecting. If those steps are splitting the columns/fields by whitespace, they should be fine either way.

$ dscl /Local/Default -read /Users/jeremy uid
dsAttrTypeNative:uid: 503
$ dscl /Local/Default -read /Users/jeremy UniqueID
UniqueID: 503

Another point of interest would be accounts greater than 500, as the Mac OS X Setup Assistant and Accounts System Preferences pane create local accounts starting with UIDs 501 by convention. Whether you choose greater than or greater than or equal to 500 is up to you. I’ve come across some situations where ID 500 gets used (somewhat unexpectedly), so you may want to find such UIDs or GIDs if it suits your purposes.

The difference between those accounts whose UIDs are greater than or equal to 100 and those greater than or equal to 500 would yield a list non-system accounts that are hidden by default from the login window or Accounts System Preferences pane. While you could generate two lists and compare with sort and uniq, you could just add to your awk statement.

$ dscl /Local/Default -list /Users UniqueID | awk '$2 >= 100 && $2 < 500 { print $1; }'

On most Mac OS X systems (as of this writing at least), there will be no accounts listed from the above statement. So, you’ll just get your command prompt back.

This should work in Tiger and Leopard, since dscl first became available in Tiger and replaced the NetInfo nicl utility entirely in Leopard.