Script to add new network users to FileVault 2

mkolb
Contributor

Hello,

We are using FileVault2 on all our clients. During the onboarding-process we create a local service account, which is also enabled for FileVault of course. When a new user logs in for the first time with his ActiveDirectory credentials, the account will be created locally on the Mac (Mobile Account).

Our problem: After that, the user has to be enabled for FileVault manually, which causes a lot of unnecessary workload.

I tried to auomate this with a script:

#!/bin/sh

#############################################################################################################
# This script will add a new logged-in user to the FileVault enabled list, using the JSS.                   #
#                                                                                                           #
# by Marco Kolbas | Greentube I.E.S. GmbH | mkolbas@greentube.com                                           #
#                                                                                                           #
# Vers. 1.0 // July 2017                                                                                    #
#                                                                                                           #
#############################################################################################################


#This discovers the current user
currentuser=`stat -f%Su /dev/console`

read -r -d '' password <<'EOF'
   set dialogText to text returned of (display dialog "Please enter your password to enable the FileVault Disk Encryption for your user. ATTENTION! If you cancle this process, you won't be able to boot this client!" default answer "" with hidden answer)
   return dialogText
EOF


status=$(sudo fdesetup list | grep -F $currentuser)

if [ "$status" != "" ]
then
    echo "Nothing to do. User already enabled for FileVault."

else
    password=$(sudo -u $currentuser /usr/bin/osascript -e "$password");

    printf '%s
' $4 $password | sudo fdesetup add -usertoadd $currentuser

    echo "User $currentuser has been activated for FileVault Disk Encryption."

fi

exit 0

The idea was to run this script "Once per user per computer". The problem is, the script is executed by root, and I always got the error message "No User interaction allowed". If I modify the script to run the command as currentuser, I get the error message "Needs to be run as root"....

I would be really happy about any kind of input to this problem!

Thanks!

1 ACCEPTED SOLUTION

mkolb
Contributor

Thank you for your input regarding the XML file!

This solution works for me now:

#!/bin/sh

## Pass the credentials for an admin account that is authorized with FileVault 2
adminName=$4
adminPass=$5

if [ "${adminName}" == "" ]; then
echo "Username undefined. Please pass the management account username in parameter 4"
exit 1
fi

if [ "${adminPass}" == "" ]; then
echo "Password undefined. Please pass the management account password in parameter 5"
exit 2
fi

## Get the logged in user's name
userName=`stat -f%Su /dev/console`

## This first user check sees if the logged in account is already authorized with FileVault 2
userCheck=$(sudo fdesetup list | grep -F $userName)
if [ "$userCheck" != "" ]; then
echo "This user is already added to the FileVault 2 list."
exit 3
fi

## Check to see if the encryption process is complete
encryptCheck=`fdesetup status`
statusCheck=$(echo "${encryptCheck}" | grep "FileVault is On.")
expectedStatus="FileVault is On."
if [ "${statusCheck}" != "${expectedStatus}" ]; then
echo "The encryption process has not completed, unable to add user at this time."
echo "${encryptCheck}"
exit 4
fi

## Get the logged in user's password via a prompt
echo "Prompting ${userName} for their login password."

USERPASS=$(osascript -e '
tell application "Finder"
   display dialog "Enter your password please to enable FileVault" default answer "" with hidden answer
    set USERPASS to the (text returned of the result)
end tell')


echo "Adding user to FileVault 2 list."

# create the plist file:
echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Username</key>
<string>'$adminName'</string>
<key>Password</key>
<string>'$adminPass'</string> 
<key>AdditionalUsers</key>
<array>
    <dict>
        <key>Username</key>
        <string>'$userName'</string>
        <key>Password</key>
        <string>'$USERPASS'</string>
    </dict>
</array>
</dict>
</plist>' > /tmp/fvenable.plist

# now enable FileVault
fdesetup add -inputplist < /tmp/fvenable.plist

## This second user check sees if the logged in account was successfully added to the FileVault 2 list
userCheck=`fdesetup list | awk -v usrN="$userName" -F, 'index($0, usrN) {print $1}'`
if [ "${userCheck}" != "${userName}" ]; then
echo "Failed to add user to FileVault 2 list."
exit 5
fi

echo "${userName} has been added to the FileVault 2 list."

## clean up
if [[ -e /tmp/fvenable.plist ]]; then
    srm /tmp/fvenable.plist
fi
exit 0

I enter the credentials of our local admin account to the parameter fields four and five inside the JSS. I tested it with some test users on virtual test-clients and it worked like planned, so should do the job on physical clients too.

View solution in original post

3 REPLIES 3

thoule
Valued Contributor II

In order to interact with filevault, you'll need to provide a password of an existing FV user, or a recovery key. Therefor, you'll have to have that in a script in clear text. Then you have lost your security! :-(

However, if your fixed on this idea and damn security to hell, the process would look like the following. I don't know if your script above would work as it doesn't specify an existing FV user...

  1. create an XML file with the user you want to add in it (and the name/password of an existing FV user).
  2. feed that to filevault with 'fdesetup add -inputplist' command.

See example from Rich on this page on what that xml file looks like:
https://derflounder.wordpress.com/2015/02/02/managing-yosemites-filevault-2-with-fdesetup/

You can get the current user from looking at the console process so everything can be done without user interaction.

mkolb
Contributor

Thank you for your input regarding the XML file!

This solution works for me now:

#!/bin/sh

## Pass the credentials for an admin account that is authorized with FileVault 2
adminName=$4
adminPass=$5

if [ "${adminName}" == "" ]; then
echo "Username undefined. Please pass the management account username in parameter 4"
exit 1
fi

if [ "${adminPass}" == "" ]; then
echo "Password undefined. Please pass the management account password in parameter 5"
exit 2
fi

## Get the logged in user's name
userName=`stat -f%Su /dev/console`

## This first user check sees if the logged in account is already authorized with FileVault 2
userCheck=$(sudo fdesetup list | grep -F $userName)
if [ "$userCheck" != "" ]; then
echo "This user is already added to the FileVault 2 list."
exit 3
fi

## Check to see if the encryption process is complete
encryptCheck=`fdesetup status`
statusCheck=$(echo "${encryptCheck}" | grep "FileVault is On.")
expectedStatus="FileVault is On."
if [ "${statusCheck}" != "${expectedStatus}" ]; then
echo "The encryption process has not completed, unable to add user at this time."
echo "${encryptCheck}"
exit 4
fi

## Get the logged in user's password via a prompt
echo "Prompting ${userName} for their login password."

USERPASS=$(osascript -e '
tell application "Finder"
   display dialog "Enter your password please to enable FileVault" default answer "" with hidden answer
    set USERPASS to the (text returned of the result)
end tell')


echo "Adding user to FileVault 2 list."

# create the plist file:
echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Username</key>
<string>'$adminName'</string>
<key>Password</key>
<string>'$adminPass'</string> 
<key>AdditionalUsers</key>
<array>
    <dict>
        <key>Username</key>
        <string>'$userName'</string>
        <key>Password</key>
        <string>'$USERPASS'</string>
    </dict>
</array>
</dict>
</plist>' > /tmp/fvenable.plist

# now enable FileVault
fdesetup add -inputplist < /tmp/fvenable.plist

## This second user check sees if the logged in account was successfully added to the FileVault 2 list
userCheck=`fdesetup list | awk -v usrN="$userName" -F, 'index($0, usrN) {print $1}'`
if [ "${userCheck}" != "${userName}" ]; then
echo "Failed to add user to FileVault 2 list."
exit 5
fi

echo "${userName} has been added to the FileVault 2 list."

## clean up
if [[ -e /tmp/fvenable.plist ]]; then
    srm /tmp/fvenable.plist
fi
exit 0

I enter the credentials of our local admin account to the parameter fields four and five inside the JSS. I tested it with some test users on virtual test-clients and it worked like planned, so should do the job on physical clients too.

dcgagne
Contributor

Just to echo thoule, you'll need an existing FV user. One method would be to add the management account to the FV group, but that could cause some security concerns. You can also, using custom triggers, add the management account, make the changes you need, then remove the management account from FV, but that may require knowing the management account password for that device and could pose some security concerns. I use something similar to this leveraging the built in jamf parameters so the information is not saved to the device in the script:

#!/bin/sh

# JAMF Parameters
# $4 = Management account
# $5 = Management account password
# $6 = Account name to be added
# $7 = Password of new account being added

# create the FileVault plist file:
echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Username</key>
<string>'$4'</string>
<key>Password</key>
<string>'$5'</string>
<key>AdditionalUsers</key>
<array>
    <dict>
        <key>Username</key>
        <string>'$6'</string>
        <key>Password</key>
        <string>'$7'</string>
    </dict>
</array>
</dict>
</plist>' > /tmp/fvreadd.plist

# Imports the plist into FileVault

fdesetup add -inputplist < /tmp/fvreadd.plist

# remove fvenable.plist
rm /tmp/fvreadd.plist

exit 0

This is just a part of a more complicated process, but this snippet is used in several policies both customer facing and behind the scenes.