Created
February 3, 2026 17:06
-
-
Save p120ph37/058e26a1d4c8e8af8ad20b8286a4dd8b to your computer and use it in GitHub Desktop.
A script that cycles through 25 password changes to clear your password history.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/expect -f | |
| # Script to cycle through password history on macOS | |
| # Usage: ./cycle_passwords.exp <current_password> <target_password> | |
| if {$argc != 2} { | |
| puts "Usage: $argv0 <current_password> <target_password>" | |
| puts "This script will change your password 25 times to clear history," | |
| puts "then set it to your target password." | |
| exit 1 | |
| } | |
| set current_pass [lindex $argv 0] | |
| set target_pass [lindex $argv 1] | |
| set username [exec whoami] | |
| # Generate 24 temporary passwords (we'll use target as #25) | |
| proc generate_temp_password {index} { | |
| return "TempPass${index}![clock seconds]" | |
| } | |
| puts "=========================================" | |
| puts "Starting password history cycling for user: $username" | |
| puts "This will perform 25 password changes" | |
| puts "=========================================" | |
| puts "" | |
| set timeout 10 | |
| # Function to change password | |
| proc change_password {old_pw new_pw iteration} { | |
| global username | |
| puts "Attempt $iteration/25: Changing password..." | |
| puts " New password: $new_pw" | |
| spawn passwd | |
| expect { | |
| timeout { | |
| puts "ERROR: Timeout waiting for Old Password prompt" | |
| exit 1 | |
| } | |
| "Old Password:" { | |
| send "$old_pw\r" | |
| } | |
| } | |
| expect { | |
| timeout { | |
| puts "ERROR: Timeout waiting for New Password prompt" | |
| exit 1 | |
| } | |
| "New Password:" { | |
| send "$new_pw\r" | |
| } | |
| } | |
| expect { | |
| timeout { | |
| puts "ERROR: Timeout waiting for Retype New Password prompt" | |
| exit 1 | |
| } | |
| "Retype New Password:" { | |
| send "$new_pw\r" | |
| } | |
| } | |
| # Wait for the warning message and command completion | |
| expect { | |
| timeout { | |
| puts "ERROR: Timeout waiting for completion" | |
| exit 1 | |
| } | |
| -re ".*WARNING.*" { | |
| # Got the keychain warning, wait for prompt to return | |
| expect { | |
| -re "\[#$%>\] $" { | |
| # Back at shell prompt | |
| } | |
| timeout { | |
| # Warning displayed but prompt detection failed, that's ok | |
| } | |
| } | |
| } | |
| -re "\[#$%>\] $" { | |
| # Back at shell prompt (in case warning doesn't appear) | |
| } | |
| } | |
| # Small delay to ensure change is committed | |
| sleep 0.5 | |
| puts " ✓ Successfully changed (iteration $iteration)" | |
| puts "" | |
| return $new_pw | |
| } | |
| # Perform 24 intermediate changes | |
| for {set i 1} {$i <= 24} {incr i} { | |
| set temp_pass [generate_temp_password $i] | |
| set current_pass [change_password $current_pass $temp_pass $i] | |
| } | |
| # Final change to target password | |
| puts "Final change (25/25): Setting to target password..." | |
| puts " New password: $target_pass" | |
| change_password $current_pass $target_pass 25 | |
| puts "" | |
| puts "=========================================" | |
| puts "SUCCESS: Password history cleared" | |
| puts "Your password is now set to: $target_pass" | |
| puts "Entra sync should now succeed" | |
| puts "=========================================" | |
| puts "" | |
| puts "NOTE: The login keychain password was NOT updated by this script." | |
| puts "If needed, run: security set-keychain-password" | |
| exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment