Skip to content

Instantly share code, notes, and snippets.

@talkingmoose
Last active July 20, 2021 15:30
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save talkingmoose/7f3d4b75c22e21332a11117937765247 to your computer and use it in GitHub Desktop.
Save talkingmoose/7f3d4b75c22e21332a11117937765247 to your computer and use it in GitHub Desktop.
Generate a randome EFI firmware password for each Mac and store in Jamf Pro. Note: This will be completely visible to all Jamf Pro users whose permissions allow access to Computers. Create an extension attritute with the first script.
#!/bin/bash
function logresult() {
if [ $? = "0" ] ; then
echo "$1"
else
echo "$2"
exit 1
fi
}
# verify whether a firmware password is set
echo "Checking for existing firmware password"
checkFirmwarePassword=$( /usr/sbin/firmwarepasswd -check )
# if a firmware password is already set, stop the script and report failure in Jamf Pro
if [ "$checkFirmwarePassword" != "Password Enabled: No" ] | [ -d /private/tmp/.fp ]; then
echo "A firmware password is already set. Doing nothing."
exit 0
else
echo "No firmware password set"
fi
# create obscure directory
fpdirectory="/private/var/.fp"
/bin/mkdir -p "$fpdirectory"
logresult "Creating \"$fpdirectory\" directory" "Failed creating \"$fpdirectory\" directory"
# generate random password
randpassword=$( /usr/bin/openssl rand -hex 6 )
logresult "Generating 8-character firmware passcode: $randpassword" "Failed generating 8-character firmware passcode."
# write random password to temporary file
/usr/bin/touch "$fpdirectory/$randpassword"
logresult "Writing password to file \"$fpdirectory/$randpassword\"" "Failed writing password to file \"$fpdirectory/$randpassword\""
# update Jamf Pro computer record with firmware password and set only if inventory was updated
/usr/local/bin/jamf recon && /usr/local/bin/jamf setOFP -mode command -password "$randpassword"
# set the firmware password only after a successful inventory update to Jamf Pro
if [ $? = "0" ]; then
echo "Updating Jamf Pro inventory to upload firmware password"
echo "Setting firmware password"
exit 0
else
echo "Failed setting firmware password"
exit 1
fi
#!/bin/bash
echo "<result>$( ls /private/var/.fp )</result>"
exit 0
@to-jundulas1
Copy link

I've created extension attribute with data type 'string' and input type 'script': Jamf Pro Extension Attribute. I've created a policy with the script 'Generate Random Firmware Password.bash' but firmwarepass was not set - Password Enabled: No
If I execute command:
/usr/local/bin/jamf recon && /usr/bin/expect -c "spawn /usr/sbin/firmwarepasswd -setpasswd ; expect ":" ; send "mypassword\n" ; expect ":" ; send "mypassword\n" ; interact"
manually in the terminal - I get 'reboot is needed, and after reboot password is set.
Did I smth wrong?

@talkingmoose
Copy link
Author

@TomasJundulas, enabling the firmware does indeed require a restart, however, Jamf Pro should already have the password recorded in the computer record before that. After the script runs, do you see the password yet in Jamf Pro? If so, everything is probably working fine. Just go ahead and reboot the computer.

@to-jundulas1
Copy link

I have enabled the policy on 2 computers, for both computers in Jamf I see no password. Restart makes no change: firmwarepasswd -check gives Password Enabled: No

@talkingmoose
Copy link
Author

@TomasJundulas, first, here's the order of steps that occur:

  1. Verify whether a firmware password is enabled. Stop, if there is.
  2. Create a temp working directory.
  3. Generate a random password.
  4. Write the password to a file in the temp working directory.
  5. Update inventory to populate the password into the Extension Attribute in Jamf
  6. And only if the inventory completes successfully, set the firmware password.
  7. Delete the temp directory and its contents.

Sounds like something isn't working between steps 2-5.

I've added some more reporting that should get displayed in the policy log after it runs. Can you update your script and test again? Then review the policy log for the failed device and let's troubleshoot from there.

@to-jundulas1
Copy link

I tried your updated script, the result was the same as before.
I commented a couple of lines - to not delete the temporary file, and run it again.
so the log:
...
Script exit code: 0
Script result: Checking for existing firmware password
No firmware password set
Creating temporary working directory /private/tmp/Random Firmware Password v2.p6L0ok
Generating 8-character firmware passcode: a4779600
Writing password to temporary text file
Retrieving inventory preferences from https://my-org.jamfcloud.com/...
Finding extension attributes...
Locating accounts...
Locating hard drive information...
Locating applications...
Locating package receipts...
Searching path: /System/Applications
Locating printers...
Searching path: /Applications
Locating hardware information (Mac OS X 10.15.4)...
Gathering application usage information...
Submitting data to https://my-org.jamfcloud.com/...
<computer_id>2</computer_id>
spawn /usr/sbin/firmwarepasswd -setpasswd
Setting Firmware Password
Enter new password:
Re-enter new password:
Updating Jamf Pro inventory to upload firmware password
Setting firmware password
...
So this time I can see the password in JAMF.
I checked the password in the computer tmp directory - it was different - not a4779600, as it's in log and jamf.
After the computer restart, this tmp folder is gone. But when checking 'sudo firmwarepasswd -check' still gives Password Enabled: No

@ZJPat
Copy link

ZJPat commented Apr 24, 2020

I'm facing issues with this script as well. After ugprading to JAMF 10.21, I can no longer find record for my TEST machine EA password.
I tried the reboot and made sure followed through the settings.

There may have been a change in 10.15.4 or within JAMF that broke this.

@talkingmoose
Copy link
Author

Updating here that issues with returning the firmware password to Jamf Pro appear to be resolved with the current script's revisions. It also adds more logging that gets returned in the policy log.

@to-jundulas1
Copy link

Thank you, William, for the help and your time. The problem was that my policy trigger was set on login and startup only, but when I checked on 'Recurring Check-in' and run the script - it worked out. Thanks again for the great script.

@dev-yeet
Copy link

just tested this out and wanted to point this out:

I have a firmware password enabled and this script as is will still generate one, set it, and recon it to jamf i'm assuming due to it checking for /private/tmp/.fp and not /private/var/.fp

If you don't remove the recovery key generated , when the updated script/policy runs again the machine will show having a firmware password but because the script ran prior, there exists a firmware password on the machine that will still populate that machine's EA during a normal recon.

@peterlewis
Copy link

This is awesome and thank you @talkingmoose!

One thing that I am thinking of though, is that if a device was to be re-imaged then that firmware password EA would blank itself out on re-enrolment.

Have you any thoughts as to a potential "part 2" for this, in terms of ensuring that the firmware password is escrowed safely to a less ephemeral location?

Thanks again! :)

@talkingmoose
Copy link
Author

@peterlewis, unfortunately, this is the pitfall of how Jamf's Extension Attribute via script works. Even if the script terminates itself without echoing a result, Jamf Pro still considers this an empty response or <result></result>, which clears the data.

I haven't tested whether disabling Settings > Global Management > Re-enrollment > Clear extension attribute values on computers and mobile devices will preserve the data in Jamf Pro.

@PascalAD
Copy link

@talkingmoose
In the company I work, your solution has been implemented (before I joined) and works fine.
The only drawback I've just experienced is when you "startosinstall --eraseinstall" and re-enroll as pre-staged. The script worked as if no EFI password had been generated although there was one already. A new random key was created and uploaded in EA. But I have no trace of the original EFI password now.
Although there's a safety in the code to exit if it's Password Enabled, it does not seem to have worked for me. I've just earned the privilege of going to an AASP to have the computers reset.

@dev-yeet
Copy link

@PascalAD if it's a t2 macbook, you should be able to revive the mac without data loss. But you're right, as said earlier this is a limitation of the script where jamf will delete it out if a machine is re-enrolled. If you use this, I would probably make use of a script that backs up your firmware passwords using api daily. Either that, or uploading it as an attachment

@PascalAD
Copy link

@dev-yeet thank you very much for the tip. I needed to go to the restore step. But now I don't EFI password anymore.

@dev-yeet
Copy link

:/ you're right, I remembered wrong; dropping link in case it helps anyone else in the future.

https://mrmacintosh.com/how-to-remove-mac-firmware-password-new-way-if-you-have-a-2018-2020-t2-mac/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment