create user using "Script Object"

hi,

i read with great interest JJ & Adam Bell’s article on script objects and thought i might try my hand at creating users in OS X with AppleScript and using the Script Object.

here’s the code:

-- createUser  creates a user using the niutil command line utility
--   and uses Expect to create the password

doMain()

on doMain()
	-- we get the highest user id in the 500 range, which we'll later increment and use for our new user
	set getHighUID to (do shell script "/usr/bin/nireport / /users uid | /usr/bin/grep \"5[0-9][0-9]\"")
	set howMany to number of words of getHighUID
	set i to 1
	set currWord to 0
	set highWord to 0
	repeat while i ≤ howMany
		set currWord to word i of getHighUID
		if currWord > highWord then
			set highWord to currWord
		end if
		set i to (i + 1)
	end repeat
	
	set userID to (highWord + 1)
	
	-- get the list of users so we can compare the new user and reject if they already exist
	set getUsers to text of (do shell script "/usr/bin/nireport / /users name")
	-- get the username and password (twice) as input from the user
	set newUser to text returned of (display dialog "What is the name of the User you would like to add?" default answer "")
	set userPass to text returned of (display dialog "What will be the password for this user?" default answer "" with hidden answer)
	set userPassComp to text returned of (display dialog "Please reenter the password." default answer "" with hidden answer)
	
	-- if the user already exists we need to error out.  no need to be fancy.
	-- if not, we will create the user, home directory & contents, plus the password.
	if userPass is not userPassComp then
		display dialog "Those two passwords don't match.  Please try again."
		doMain()
	else
		if newUser is in getUsers then
			display dialog "That User already exists.  Please try again."
			doMain()
		else if space is in newUser then
			display dialog "The Username cannot contain a space, please try again"
			doMain()
		else
			set ourU to buildProtype(newUser, userPass, userID)
			tell ourU to mkU()
			--if our Expect script exists, delete it.
			do shell script "/bin/rm -rf /tmp/expectPass" with administrator privileges
			display dialog "Finished"
		end if
	end if
end doMain


to buildProtype(newUser, userPass, userID)
	script prototype
		-- these next few lines are the contents of a file we will create to set the password
		property myExpect : "#!/usr/bin/expect 
spawn passwd [lindex \\$argv 0]
set password [lindex \\$argv 1]
expect \"password:\"
send \"\\$password\\r\"
expect \"password:\"
send \"\\$password\\r\"
expect eof"
		property nu : newUser
		property xx : userPass
		property uID : userID
		property mkPass : myExpect
		property createNU : "/usr/bin/niutil -create / /users/"
		property genProp : "/usr/bin/niutil -createprop / /users/"
		property genHome : "/usr/sbin/createhomedir -u "
		property doPass : "/bin/cat > /tmp/expectPass << EOF
" & myExpect & "
EOF"
		to mkU()
			do shell script createNU & nu with administrator privileges
			do shell script genProp & nu & " realname " & nu with administrator privileges
			do shell script genProp & nu & " uid " & uID with administrator privileges
			do shell script genProp & nu & " home /Users/" & nu with administrator privileges
			do shell script genHome & nu with administrator privileges
			do shell script genProp & nu & " shell \"/bin/bash\"" with administrator privileges
			do shell script genProp & nu & " gid 20" with administrator privileges
			do shell script genProp & nu & " passwd \"*\"" with administrator privileges
			do shell script doPass with administrator privileges
			do shell script "/bin/chmod +x /tmp/expectPass" with administrator privileges
			do shell script "/tmp/expectPass " & nu & space & xx with administrator privileges
			set loginPref to button returned of (display dialog "The new user " & nu & " has been created.  Would you like to configure this user as the AutoLogin default?" buttons {"Yes", "No"})
			if loginPref is "Yes" then
				do shell script "/usr/bin/defaults write /Library/Preferences/com.apple.loginwindow autoLoginUser " & quoted form of nu with administrator privileges
				do shell script "/usr/bin/defaults write /Library/Preferences/com.apple.loginwindow autoLoginUserUID " & uID with administrator privileges
			end if
		end mkU
	end script
end buildProtype

comments welcome!

not one comment? ah well…

i’ve added some lines to give the user administrative privileges:

-- createUser  creates a user using the niutil command line utility
--   and uses Expect to create the password

doMain()

on doMain()
	-- we get the highest user id in the 500 range, which we'll later increment and use for our new user
	set getHighUID to (do shell script "/usr/bin/nireport / /users uid | /usr/bin/grep \"5[0-9][0-9]\"")
	set howMany to number of words of getHighUID
	set i to 1
	set currWord to 0
	set highWord to 0
	repeat while i ≤ howMany
		set currWord to word i of getHighUID
		if currWord > highWord then
			set highWord to currWord
		end if
		set i to (i + 1)
	end repeat
	
	set userID to (highWord + 1)
	
	-- get the list of users so we can compare the new user and reject if they already exist
	set getUsers to text of (do shell script "/usr/bin/nireport / /users name")
	-- get the username and password (twice) as input from the user
	set newUser to text returned of (display dialog "What is the name of the User you would like to add?" default answer "")
	set userPass to text returned of (display dialog "What will be the password for this user?" default answer "" with hidden answer)
	set userPassComp to text returned of (display dialog "Please reenter the password." default answer "" with hidden answer)
	
	-- if the user already exists we need to error out.  no need to be fancy.
	-- if not, we will create the user, home directory & contents, plus the password.
	if userPass is not userPassComp then
		display dialog "Those two passwords don't match.  Please try again."
		doMain()
	else
		if newUser is in getUsers then
			display dialog "That User already exists.  Please try again."
			doMain()
		else if space is in newUser then
			display dialog "The Username cannot contain a space, please try again"
			doMain()
		else
			set ourU to buildProtype(newUser, userPass, userID)
			tell ourU to mkU()
			--if our Expect script exists, delete it.
			do shell script "/bin/rm -rf /tmp/expectPass" with administrator privileges
			display dialog "Finished"
		end if
	end if
end doMain


to buildProtype(newUser, userPass, userID)
	script prototype
		-- these next few lines are the contents of a file we will create to set the password
		property myExpect : "#!/usr/bin/expect 
spawn passwd [lindex \\$argv 0]
set password [lindex \\$argv 1]
expect \"password:\"
send \"\\$password\\r\"
expect \"password:\"
send \"\\$password\\r\"
expect eof"
		property nu : newUser
		property xx : userPass
		property uID : userID
		property createNU : "/usr/bin/niutil -create / /users/"
		property genProp : "/usr/bin/niutil -createprop / /users/"
		property adminPriv : "/usr/bin/niutil -appendprop / /groups/admin users "
		property genHome : "/usr/sbin/createhomedir -u "
		property doPass : "/bin/cat > /tmp/expectPass << EOF
" & myExpect & "
EOF"
		to mkU()
			do shell script createNU & nu with administrator privileges
			do shell script genProp & nu & " realname " & nu with administrator privileges
			do shell script genProp & nu & " uid " & uID with administrator privileges
			do shell script genProp & nu & " home /Users/" & nu with administrator privileges
			do shell script genHome & nu with administrator privileges
			do shell script genProp & nu & " shell \"/bin/bash\"" with administrator privileges
			do shell script genProp & nu & " gid 20" with administrator privileges
			do shell script genProp & nu & " passwd \"*\"" with administrator privileges
			do shell script doPass with administrator privileges
			do shell script "/bin/chmod +x /tmp/expectPass" with administrator privileges
			do shell script "/tmp/expectPass " & nu & space & xx with administrator privileges
			set adminPref to button returned of (display dialog "The new user " & nu & " has been created.  Would you like to allow this user to administer this computer?" buttons {"Yes", "No"})
			if adminPref is "Yes" then
				do shell script adminPriv & nu with administrator privileges
			end if
			set loginPref to button returned of (display dialog "Would you like to configure " & nu & " as the AutoLogin default?" buttons {"Yes", "No"})
			if loginPref is "Yes" then
				do shell script "/usr/bin/defaults write /Library/Preferences/com.apple.loginwindow autoLoginUser " & quoted form of nu with administrator privileges
				do shell script "/usr/bin/defaults write /Library/Preferences/com.apple.loginwindow autoLoginUserUID " & uID with administrator privileges
			end if
		end mkU
	end script
end buildProtype