Skip to main content
Question

Reset Keychain with Swift Dialog UI

  • February 10, 2025
  • 1 reply
  • 0 views

Forum|alt.badge.img+9

borrowed the script from @bwoods and put some nice Swift Dialog UI on it.  Gives user notification of what is about to happen and notifications along the way.

 

#!/bin/zsh ###################################################################################################### # # Gobal "Common" variables (do not change these!) # ###################################################################################################### export PATH=/usr/bin:/bin:/usr/sbin:/sbin LOGGED_IN_USER=$( scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ && ! /loginwindow/ { print $3 }' ) USER_DIR=$( dscl . -read /Users/${LOGGED_IN_USER} NFSHomeDirectory | awk '{ print $2 }' ) OS_PLATFORM=$(/usr/bin/uname -p) [[ "$OS_PLATFORM" == 'i386' ]] && HWtype="SPHardwareDataType.0.cpu_type" || HWtype="SPHardwareDataType.0.chip_type" SYSTEM_PROFILER_BLOB=$( /usr/sbin/system_profiler -json 'SPHardwareDataType') MAC_SERIAL_NUMBER=$( echo $SYSTEM_PROFILER_BLOB | /usr/bin/plutil -extract 'SPHardwareDataType.0.serial_number' 'raw' -) MAC_CPU=$( echo $SYSTEM_PROFILER_BLOB | /usr/bin/plutil -extract "${HWtype}" 'raw' -) MAC_HADWARE_CLASS=$( echo $SYSTEM_PROFILER_BLOB | /usr/bin/plutil -extract 'SPHardwareDataType.0.machine_name' 'raw' -) MAC_RAM=$( echo $SYSTEM_PROFILER_BLOB | /usr/bin/plutil -extract 'SPHardwareDataType.0.physical_memory' 'raw' -) FREE_DISK_SPACE=$(($( /usr/sbin/diskutil info / | /usr/bin/grep "Free Space" | /usr/bin/awk '{print $6}' | /usr/bin/cut -c 2- ) / 1024 / 1024 / 1024 )) MACOS_VERSION=$( sw_vers -productVersion | xargs) # Swift Dialog version requirements SW_DIALOG="/usr/local/bin/dialog" [[ -e "${SW_DIALOG}" ]] && SD_VERSION=$( ${SW_DIALOG} --version) || SD_VERSION="0.0.0" MIN_SD_REQUIRED_VERSION="2.3.3" DIALOG_INSTALL_POLICY="install_SwiftDialog" SUPPORT_FILE_INSTALL_POLICY="install_SymFiles" ################################################### # # App Specfic variables (Feel free to change these) # ################################################### SUPPORT_DIR="/Library/Application Support/GiantEagle" SD_BANNER_IMAGE="${SUPPORT_DIR}/SupportFiles/GE_SD_BannerImage.png" LOG_DIR="${SUPPORT_DIR}/logs" LOG_FILE="${LOG_DIR}/ResetKeychain.log" LOG_STAMP=$(echo $(/bin/date +%Y%m%d)) ICON_FILES="/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/" JSON_OPTIONS=$(mktemp /var/tmp/ResetKeychain.XXXXX) BANNER_TEXT_PADDING=" " #5 spaces to accomodate for icon offset SD_INFO_BOX_MSG="" SD_WINDOW_TITLE="${BANNER_TEXT_PADDING}Reset Login Keychain" SD_DIALOG_GREETING=$((){print Good ${argv[2+($1>11)+($1>18)]}} ${(%):-%D{%H}} morning afternoon evening) # Define the target directory KEYCHAIN_DIR="$USER_DIR/Library/Keychains" KEYCHAIN_BACKUP_DIR="$USER_DIR/Library/Keychains Copy" RESTART_TIMER=30 ################################################## # # Passed in variables # ################################################# JAMF_LOGGED_IN_USER=$3 # Passed in by JAMF automatically SD_FIRST_NAME="${(C)JAMF_LOGGED_IN_USER%%.*}" #################################################################################################### # # Functions # #################################################################################################### function create_log_directory () { # Ensure that the log directory and the log files exist. If they # do not then create them and set the permissions. # # RETURN: None # If the log directory doesnt exist - create it and set the permissions [[ ! -d "${LOG_DIR}" ]] && /bin/mkdir -p "${LOG_DIR}" /bin/chmod 755 "${LOG_DIR}" # If the log file does not exist - create it and set the permissions [[ ! -f "${LOG_FILE}" ]] && /usr/bin/touch "${LOG_FILE}" /bin/chmod 644 "${LOG_FILE}" } function logMe () { # Basic two pronged logging function that will log like this: # # 20231204 12:00:00: Some message here # # This function logs both to STDOUT/STDERR and a file # The log file is set by the $LOG_FILE variable. # # RETURN: None echo "${1}" 1>&2 echo "$(/bin/date '+%Y-%m-%d %H:%M:%S'): ${1}" | tee -a "${LOG_FILE}" } function check_swift_dialog_install () { # Check to make sure that Swift Dialog is installed and functioning correctly # Will install process if missing or corrupted # # RETURN: None logMe "Ensuring that swiftDialog version is installed..." if [[ ! -x "${SW_DIALOG}" ]]; then logMe "Swift Dialog is missing or corrupted - Installing from JAMF" install_swift_dialog SD_VERSION=$( ${SW_DIALOG} --version) fi if ! is-at-least "${MIN_SD_REQUIRED_VERSION}" "${SD_VERSION}"; then logMe "Swift Dialog is outdated - Installing version '${MIN_SD_REQUIRED_VERSION}' from JAMF..." install_swift_dialog else logMe "Swift Dialog is currently running: ${SD_VERSION}" fi } function install_swift_dialog () { # Install Swift dialog From JAMF # PARMS Expected: DIALOG_INSTALL_POLICY - policy trigger from JAMF # # RETURN: None /usr/local/bin/jamf policy -trigger ${DIALOG_INSTALL_POLICY} } function check_support_files () { [[ ! -e "${SD_BANNER_IMAGE}" ]] && /usr/local/bin/jamf policy -trigger ${SUPPORT_FILE_INSTALL_POLICY} } function create_infobox_message () { ################################ # # Swift Dialog InfoBox message construct # ################################ SD_INFO_BOX_MSG="## System Info ##<br>" SD_INFO_BOX_MSG+="${MAC_CPU}<br>" SD_INFO_BOX_MSG+="${MAC_SERIAL_NUMBER}<br>" SD_INFO_BOX_MSG+="${MAC_RAM} RAM<br>" SD_INFO_BOX_MSG+="${FREE_DISK_SPACE}GB Available<br>" SD_INFO_BOX_MSG+="macOS ${MACOS_VERSION}<br>" } function display_msg () { # Expected Parms # # Parm $1 - Message to display # Parm $2 - Button text # Parm $3 - Overlay Icon to display # Parm $4 - Welcome message (Yes/No) [[ "${4}" == "Yes" ]] && message="${SD_DIALOG_GREETING} ${SD_FIRST_NAME}. $1" || message="$1" if [[ "${MACOS_VERSION}" >= "15" ]]; then icon="/System/Library/CoreServices/Applications/Keychain Access.app" else icon="/System/Applications/Utilities/Keychain access.app" fi MainDialogBody=( --message "${message}" --ontop --icon "$icon" --overlayicon "$3" --bannerimage "${SD_BANNER_IMAGE}" --bannertitle "${SD_WINDOW_TITLE}" --infobox "${SD_INFO_BOX_MSG}" --width 760 --height 480 --ignorednd --quitkey 0 --button1text "$2" ) # Add items to the array depending on what info was passed [[ "${2}" == "OK" ]] && { MainDialogBody+='--button2text' ; MainDialogBody+='Cancel' ; } [[ "${2}" == "Restart" ]] && { MainDialogBody+="--timer" ; MainDialogBody+=$RESTART_TIMER ; } "${SW_DIALOG}" "${MainDialogBody[@]}" 2>/dev/null returnCode=$? [[ $returnCode == 2 || $returnCode == 10 ]] && cleanup_and_exit } function cleanup_and_exit () { [[ -f ${JSON_OPTIONS} ]] && /bin/rm -rf ${JSON_OPTIONS} [[ -f ${TMP_FILE_STORAGE} ]] && /bin/rm -rf ${TMP_FILE_STORAGE} [[ -f ${DIALOG_COMMAND_FILE} ]] && /bin/rm -rf ${DIALOG_COMMAND_FILE} exit 0 } function perform_reset () { typeset -i success_count && success_count=0 typeset -i fail_count && fail_count=0 # Close the Keychain Access app logMe "Closing Keychain Access application." pkill -x "Keychain Access" # Check if the target directory exists if [[ ! -d "$KEYCHAIN_DIR" ]]; then display_msg "Your personal Keychain does not exist in the expected directory!" "OK" "stop" logMe "Target directory does not exist. No actions were taken." exit 0 fi logMe "Creating a backup of User Keychain Files" mkdir -p "${KEYCHAIN_BACKUP_DIR}" cp -rf "${KEYCHAIN_DIR}" "${KEYCHAIN_BACKUP_DIR}" logMe "Starting cleanup of directories in $KEYCHAIN_DIR" # Find all directories within the target directory and delete them, logging each action find "$KEYCHAIN_DIR" -mindepth 1 -print0 | while IFS= read -r -d $'\\0' dir; do rm -rf "$dir" if [[ $? -eq 0 ]]; then logMe "Successfully deleted file / directory: $dir" ((success_count++)) else logMe "Failed to delete file / directory: $dir" ((fail_count++)) fi done if [[ $fail_count -eq 0 ]]; then display_msg "The keychain reset was successful. Your system must be restarted to finish this process. Restart will occur in $RESTART_TIMER seconds. After it restarts, you will need to run the 'Register with EntraID' from Self Service." "Restart" "computer" logMe "Initiating forced restart with $RESTART_TIMER second delay." shutdown -r now "Script-initiated forced restart." else display_msg "Errors have occured while trying to reset your keychian!" "OK" "stop" logMe "Cleanup completed with $fail_count failures. Restart aborted." fi } #################################################################################################### # # Main Script # #################################################################################################### autoload 'is-at-least' check_swift_dialog_install check_support_files create_infobox_message display_msg "If you are experiencing issues with items in your keychain, this utility will backup your current keychain and then reset it. <br><br>You will need to restart your computer after running this process." "OK" "caution" "Yes" perform_reset cleanup_and_exit

 

Screenshot of "Welcome" screen:

and the screen if everything was successful.  Timer can be changed inside the script..if you don't use Azure/Entra, you will need to change the message about run the register command...

1 reply

bwoods
Forum|alt.badge.img+14
  • Honored Contributor
  • 473 replies
  • March 31, 2025

Awesome implementation Scott!


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings