Richard York

Web Developer, Author, and Artist

A Closer Look at Mac OS X's dscl Command

A Closer Look at Mac OS X's dscl Command

November 5, 2011 by Richard

dscl is a directory utility included in both Mac OS X client and server. You'll find a great deal of information about this command simply reading the man page:

man dscl

Following are my personal notes on this command.

Creating a new user

# dscl . -create /Users/username

Immediately following the call to the dscl command is the path argument.

When the directory path is a dot, the user is created on the local Mac OS X instance only. (the user will not be a network user)

Creating a new user requires an administrator's account. To automate this process, you may include an administrator's username and password directly in the call to the command.

# dscl -u username -P password . -create /Users/username

Including the username and password in the command call will allow you to create scripts to create useres without a password prompt. If you do not wish to include the username and password in the command call, you can use sudo instead.

Creating a network user

Mac OS X provides excellent integration with both Open Directory and Microsoft Active Directory networks. Creating a network user requires only slight modifications to the dscl command.

Working with Open Directory

If joined to open directory, and you you wish to create a user in open directory, the command line call will look something like this:

# dscl -u username -P password /LDAPv3/ -create /Users/username is the hostname I use for my own Open Directory server, if you're running the command on the same server Open Directory resides, you might need to change the path argument to /LDAPv3/

When working with Open Directory, the username and password that you provide will be that of an Open Directory administrator.

Working with Active Directory

If joined to a Microsoft Active Directory domain, the directory path should be something like /Active Directory/All Domains

# dscl -u username -P password '/Active Directory/All Domains' -create /Users/username

This command will create a new user in the Microsoft Active Directory domain controller provided that the username and password that you provide to the argument is an Active Directory network user with privileges to do so.

The Mac OS X client or server instance MUST be joined to Active Directory prior to attempting to manipulate data in Active Directory.

Complete Creation of the User Account

Before the account will be created, you'll now need to run a series of commands to append additional meta data to the account. This will be done by specifying key value pairs for the new user account. Each of the following calls to the dscl command will need to be modified appropriately depending on whether you are working with a local user, an open directory user, or an active directory user. To keep things simple, I'll just stick with the syntax used to create a local user.

Set the user's default shell

The following command set's the user's default shell to bash.

# dscl . -create /Users/username UserShell /bin/bash
Set the user's full name

Aside from the shortname that you assigned to the user, the user's 'RealName' attribute can also be used at the login prompt to login to Mac OS X.

# dscl . -create /Users/username RealName "Dr. First Last"

Note that any time spaces or special characters appear in an argument, that argument can be enclosed with either single or double quotes, or the spaces can be escaped using the backslash character.

Set the user's unique user id

The user's unique user id will be a unique number assigned to the user. To find out what user ids are already used you can run the following command:

# dscacheutil -q user

The unique id will be the uid value, you'll want to create a new uid that's not already in use. To assign a new uid run the following:

# dscl . -create /Users/username UniqueID 506
Set the user's primary group id

Each user will need to have a primary group. On Mac OS X systems, usually you want each user's primary group to be the 'staff' group. In order to assign a group id, you need to know the gid value, like the uid, the gid is a unique number assigned to each group. You can list all groups using the following command:

# dscacheutil -q group

In my case, the gid of the group staff is 20, so I now run the following command to assign that gid to become my user's primary group id.

# dscl . -create /Users/username PrimaryGroupID 20
Set the user's home directory

Upon logging into Mac OS X, each user will need his or her own home folder on the system. Setting a user's home directory can be done with the following command:

# dscl . -create /Users/username NFSHomeDirectory /Users/username
Setting the user's password

This one is easy enough. Again, if special characters are involved, simply enclose the password in quotations marks or escape using the backslash character.

# dscl . -passwd /Users/username newPassword

Making a user an admin

If you would like a user to have admin privileges on the machine, that can be done with the following command:

# dscl . -append /Groups/admin GroupMembership username

Giving a user SSH access

If you would like a user to have the ability to login remotely via SSH, that can be done with the following command:

# dscl . -append /Groups/ GroupMembership username

Updating Records in either Open Directory or Active Directory

To get an idea of what you can modify in either Open Directory or Active Directory user accounts, first, it is useful to be able to list a user's entire account. That can be done with the following command:

# dscl '/Active Directory/All Domains' -read /Users/username

This command will print a very long list of information associated with a user account, including useful things you might need to modify, such as:

  • City
  • Comment
  • Company
  • EMailAddress
  • JobTitle
  • FirstName
  • LastName
  • NickName
  • PostalCode
  • PhoneNumber
  • RealName
  • State
  • Street
  • And many others...

To create a key for a user account when the key does not already exist, you use the following command:

# dscl
-u authorizedDomainUser
-P authorizedDomainPassword
'/Active Directory/All Domains'
'My Name'

To update a key for a user account when the key already exists, you use the following command:

# dscl
-u authorizedDomainUser
-P authorizedDomainPassword
'/Active Directory/All Domains'
'My Name'

To remove a key from a user account, you use the following command:

# dscl
-u authorizedDomainUser
-P authorizedDomainPassword
'/Active Directory/All Domains'

Reading Keys

Finally, it is also useful to read a single key value pair for a given user account. That can be done using the following command:

# dscl
-u authorizedDomainUser
-P authorizedDomainPassword
'/Active Directory/All Domains'

If the key does not exist, the result will contain the string 'No such key', which you can then use to determine whether or not you need to update a key that already exists or create a new key.

Authenticating Users

The dscl command can also be used to authenticate users. This is done with the following command:

# dscl "/Active Directory/All Domains" -authonly 'username' 'password'

If authentication is successful, there will be NULL output to the terminal, if authentication was not successful, something along the lines of:

Authentication for node /Local/Default failed. (-14090, eDSAuthFailed) DS Error: -14090 (eDSAuthFailed)

...will be output to stderr.


  • June 12, 2012 Kevin says:

    I've tried to use the command dscl "'/Active Directory/All Domains' -read /Users/username" but comes back with an error and don't know what to put in place of this.. Here's the error: Data source (/Active Directory/All Domains) is not valid. Thanks, help is greatly appreciated!
  • June 12, 2012 Richard York says:

    Kevin, Is your Mac joined to the Active Directory domain? It won't work unless the computer is joined to the domain. You can do that through System Preferences -> Users & Groups -> Login Options -> Edit (next to "Network Account Server"). If it is joined to the domain, you also have to use an Active Directory user that is authorized to perform the tasks that you're trying to accomplish, in your case, the ability to read a given user's AD record. How to authenticate with an Active Directory user in order to perform tasks with dscl is documented in my post above.
  • June 12, 2012 Richard York says:

    Another thing you may want to consider is how the network is structured. For example '/Active Directory/All Domains' might work for a majority of people, but if you have multiple domains, you may want to modify that argument to point to a specific domain controller. Having never done this, I'm not sure how the argument would be written. But, having done similar tasks with Open Directory, I imagine that the argument changes are similar. For example, to reference an Open Directory server, you'd put in '/LDAPv3/' or '/LDAPv3/' (whatever the IP or hostname really is). In an Active Directory network, I imagine it would be '/Active Directory/' (substitute with the real IP), and I imagine a hostname argument would work there too, but having never tried it, I don't know for certain. Hope that helps!
  • July 9, 2012 David D. says:

    How can you get Mac OS to list computers listed in Active Directory? Our Macs are bound to both AD and OD and we'd like to generate a report of computers added to domain. Thanks ~David
  • July 9, 2012 Richard York says:

    dscl "/Active Directory/All Domains" list /Computers
    You'd use /Users if listing only users, /Groups if listing groups, and /Computers if listing computers. Everything is a path, you just have to know the right path.
  • July 9, 2012 David D. says:

    Thanks.. Cool... I am not able to see computer in the root OU using
    dscl "/Active Directory/" -list Computers
    (we are a mac school) In the root out there are hundreds of OUs and sub OUs, one for each school, type of site (senior,middle, etc.). "ou=4531,ou=Elementary,dc=school,dc=net" is its format.. I just want to list computers in the "ou=4531", not all the rest of the districts computers. Tried this:
    dscl "/Active Directory/" -list Computers "ou=4531,ou=Elementary,dc=school,dc=net"
    There is a pause, but nothing displayed. Thanks for the point the the right direction, big help. ~David
  • July 9, 2012 Richard York says:

    I'm not really certain that you can use the list switch in conjunction with limiting by a value like that. Have you successfully used it that way before? On the other hand, this is certainly territory I'm not personally familiar with anyway, so if I'm wrong I apologize. I've seen some examples online that have more in the directory path, and you can further limit the scope of what you're listing that way. e.g.:
    /Active Directory/All Domains/EXAMPLE.COM
    When I try /Active Directory/EXAMPLE.COM it doesn't work for me. I've seen some examples elsewhere that have more stuff in that path, and they seem to be limiting the scope of the inquiry that way. Anyway, I can do that, and then list the details of an individual machine like this:
    dscl "/Active Directory/All Domains/EXAMPLE.COM" -read /Computers/SomeonesPC
    And that prints all sorts of things about that one machine. Heck, I can even tell it to print a PLIST XML file instead, which would be very easy to parse. Using this combination of commands though, it would be very remedial to whip up a shell script in PHP or whatever your language of choice is and identify specific machines by scanning the contents of a particular field, like the distinguished name or whatever.
  • July 10, 2012 Kirk B says:

    Hi, Great article, and well detailed. The issue we have is if we leave a standard OS install with the fields as UniqueID, primaryGroupID, gudNumber listed in the Directory Utility>Mappings, then we do get the user account found, and information dislplayed. But the numbers it creates for each of these are not what are listed in AD. We could change or install image so that it points to the msSFU30 versions of the fields, but we would prefer to leave the standard install as is for as much as possible. All does work as it should with the mssFU30 fields in there, and the right names of groups, and proper ID numbers shown. The computer, user, all is fine in the domain, and we have had it this way for years. We replicate the mssFU30 fields to the regular matching AD Unix related fields, gidNumber, unixHomeDirectory, loginShell, name, memberOf, and uidNumber also uid. I have read that one should "extended to support Apple objects and attributes" and add fields like dsAttrTypeStandard:HomeDirectory, dsAttrTypeNative:homeDirectory, dsAttrTypeStandard:SMBHomeDirectory as stated here: ... and I guess there are more, but I haven't found a clear way to do describe that... for those that want to go this route. We tried extending the active directory before, then with upgrades the information was all lost, and objects would have had to been added again... so we are not going to work with the option of extending it again in 2008 RC2 So the question.. Where exactly is apple directory service looking for this info? which AD fields exactly? It seams to find the user, find their groups, home directory, etc, from the default AD fields we populate with info from mssFU30 fields, but it makes its own numbers for gid, etc from the information, it finds from the AD. Thanks for any help, Sincerely, Kirk B
  • July 10, 2012 Richard York says:

    Sorry Kirk, I don't know the answer to the question, where does it get the information it has? Whatever I've learned about Active Directory and Open Directory I've put on this blog. Admittedly, it hasn't been much. But even saying that, what I know now hasn't been too difficult to figure out. That said, I can oblige you with a heaping plateful of somewhat educated speculation. If I were to guess, I'd say the uid and gid are probably generated locally by the local directory (each OS X machine on its own is like its own local Open Directory install), and the rest of that information comes from Active Directory, at least the information that is obvious to have come from there. The local directory probably assumes that Active Directory doesn't know about Unix, doesn't have 'Services for Unix' installed. Because, that did use to be the case, by default. I don't know if MS has changed the default behavior since then. You can *probably* go into the OS X side and configure that stuff though, with regards to uid and gid and where it gets that information and/or how they're generated. I know that OS X used to use Samba and Winbind just like any Linux distro, but Apple has since rolled its own solution for Windows network integration. At least when it was samba or winbind, I recall there being options to generate or to use a directory for uid/gid. With regards to Apple's newer stuff, I'm not up-to-date on what they did to replace samba / Winbind, or what you might need to do there. I want to say it started with Lion, though, but I could be wrong about that. I'm sorry I don't have the actual, specific information that you need here. And hey, if you figure it out, please come back and write it up. Good luck!
  • August 3, 2012 Tausif says:

    Hi, My requirement is to find out the SID for normal user who has logged to mac machine which is added to windows domain. The user who is not part of admin group should be able to retreive his own SID. Also how can I achieve the same target by programmatically in objective-c. Please guide me on this. Tausif.

There are no comments posted at this time.

Leave a Comment

Simple HTML is allowed: <code>, <b>, <i>, <u>, <var>, <strong>, <em>, <blockquote>, <ul>, <ol>, <li>, <p> (no attributes). All spacing and line breaks in your comment will be preserved.

* All comments are moderated and are subject to approval.
Your comment will appear once it has been approved.
Posting multiple times will not expedite the approval process.


© Copyright 2014 Hot Toddy, All Rights Reserved.