Instantly share code, notes, and snippets.

Embed
What would you like to do?
This script will try to determine a list of members of the given group and list all members (macOS)
#!/bin/bash
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
# allusers.sh
#
# written by Armin Briegel, Scripting OS X, 2018
#
# code is provided as is, with no guarantees that it will work etc.
# adapt and use as you will
#
#/ lists all users on macOS for given group
#/
#/ usage:
#/ allusers.sh groupname [node]
#/ - groupname: short name for the group to list users for
#/ - node: directory node path to search for user
#/ defaults to /Local/Default
#/
usage() {
grep '^#/' "$0" | cut -c4-
exit 0
}
groupmembers() { # $1: groupname
# get group members
members=$(dscl "$node" read /Groups/"$1" GroupMembership 2>/dev/null )
if [[ "$members" == GroupMembership* ]]; then
members=${members:17}
else
members=""
fi
#echo "Group: $1, members: $members"
userlist+=' '$members
# recurse with NestedGroups
nested=$(dscl "$node" read /Groups/"$1" NestedGroups 2>/dev/null )
if [[ "$nested" == NestedGroups* ]]; then
nested=${nested:14}
else
nested=""
fi
for uuid in $nested ; do
gname=$(dscl /Search list /Groups GeneratedUID | awk '$2 == "'$uuid'" {print $1;}')
# warn on calculated Groups
if [[ "$calculatedgroups" == *"$gname"* ]]; then
>&2 echo "WARNING: '$gname' is a calculated group and cannot be resolved by this script"
# but keep going
else
groupmembers "$gname"
fi
done
}
# first see if $1 is valid
if [[ -z "$1" ]]; then
usage
exit 1
fi
group="$1"
if ! dscl /Search read /Groups/"$group" 1>/dev/null 2>&1; then
echo "no group named $group"
usage
exit 1
fi
node=${2:-"/Local/Default"}
# get a list of calculated groups, from the local directory only
calculatedgroups=$(dscl "/Local/Default" list /Groups Comment | awk '/calculated/ { print $1; }')
# warn on calculated Groups
if [[ "$calculatedgroups" == *"$group"* ]]; then
>&2 echo "WARNING: '$group' is a calculated group and cannot be resolved by this script"
exit 1
fi
# get gid for group
gid=$(dscl "$node" read /Groups/"$group" PrimaryGroupID | cut -d ' ' -f 2)
#echo "gid: $gid"
# get users matching PrimaryGroupID
gidusers=$(dscl "$node" list /Users PrimaryGroupID | awk '$2=='"$gid"' { print $1; }')
userlist=$gidusers
# get group members
groupmembers "$group"
# replace whitespace with new line, sort and uniquify
echo "$userlist" | tr -s '[:space:]' $'\n' | sort | uniq
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment