Created
September 16, 2025 23:34
-
-
Save okikio/e4e3669c74e4f43c8a0131d4d958b771 to your computer and use it in GitHub Desktop.
Automates the conversion of traditional Linux users to systemd-homed management, preserving everything that matters - UIDs, groups, and home directories - with safety backups along the way.
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
| #!/bin/bash | |
| # Function to check if the script is run with sudo (root privileges) | |
| check_root() { | |
| if [[ $EUID -ne 0 ]]; then | |
| echo "This script must be run as root (use sudo)." | |
| exit 1 | |
| fi | |
| } | |
| # Function to display help message | |
| show_help() { | |
| echo "This script automates the process of converting a traditional user account to a systemd-homed managed user." | |
| echo "It also supports adding additional arguments for shell, timezone, language, and other customizations." | |
| echo "" | |
| echo "Usage:" | |
| echo " sudo ./convert_to_homed.sh <username> [--shell=<shell>] [--timezone=<timezone>] [--language=<language>] [additional arguments]" | |
| echo " sudo ./convert_to_homed.sh --help - Displays this help message." | |
| exit 0 | |
| } | |
| # Function to convert an existing user to systemd-homed managed user | |
| convert_user() { | |
| local username=$1 | |
| shift # Remove the username from the arguments to handle other arguments | |
| local user_home="/home/$username" | |
| local user_home_backup="/home/$username.saved" | |
| # Check if the user exists | |
| if ! getent passwd "$username" > /dev/null; then | |
| echo "Error: User '$username' does not exist." | |
| exit 1 | |
| fi | |
| # Backup the current home directory | |
| echo "Backing up the home directory for $username..." | |
| mv "$user_home" "$user_home_backup" || { echo "Failed to move home directory."; exit 1; } | |
| # Get user details | |
| user_details=$(getent passwd "$username") | |
| user_uid=$(echo "$user_details" | cut -d: -f3) # UID | |
| user_gecos=$(echo "$user_details" | cut -d: -f5) # GECOS field | |
| user_gid=$(echo "$user_details" | cut -d: -f4) # GID | |
| # Get the group name for the user | |
| user_group=$(getent group "$user_gid" | cut -d: -f1) | |
| echo "User details for $username: UID=$user_uid, GECOS=$user_gecos, GID=$user_gid, Group=$user_group" | |
| # Get all groups the user is a part of | |
| user_groups=$(id -Gn "$username" | tr ' ' ',') # Convert space-separated list to comma-separated | |
| # Check for optional arguments like shell, timezone, and language | |
| user_shell="" | |
| user_timezone="" | |
| user_language="" | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| --shell=*) | |
| user_shell="${1#*=}" | |
| shift | |
| ;; | |
| --timezone=*) | |
| user_timezone="${1#*=}" | |
| shift | |
| ;; | |
| --language=*) | |
| user_language="${1#*=}" | |
| shift | |
| ;; | |
| *) | |
| echo "Unknown argument: $1" | |
| shift | |
| ;; | |
| esac | |
| done | |
| # Remove the user entry from /etc/passwd, /etc/shadow, and /etc/group | |
| echo "Removing the old user account from /etc/passwd, /etc/shadow, and /etc/group..." | |
| vipw -s -u "$username" && vipw -s -g "$user_group" && vigr -s -g "$user_group" && vigr -s -u "$username" | |
| # Create the systemd-homed user with the same UID and GECOS, and include user groups | |
| echo "Creating the systemd-homed user $username..." | |
| homectl create "$username" --uid="$user_uid" --real-name="$user_gecos" --member-of="$user_groups" \ | |
| ${user_shell:+--shell="$user_shell"} \ | |
| ${user_timezone:+--timezone="$user_timezone"} \ | |
| ${user_language:+--language="$user_language"} || { echo "Failed to create homed user."; exit 1; } | |
| # Migrate the old home directory to the new systemd-homed user directory | |
| echo "Migrating the old home directory..." | |
| homectl with "$username" -- rsync -aHANUXv --remove-source-files "$user_home_backup/" /home/"$username" || { echo "Failed to migrate home directory."; exit 1; } | |
| # Clean up the old home directory backup | |
| echo "Removing old home directory backup..." | |
| rmdir "$user_home_backup" || { echo "Failed to remove backup directory."; exit 1; } | |
| # Restart NetworkManager for any changes to take effect | |
| echo "Restarting NetworkManager..." | |
| systemctl restart NetworkManager | |
| echo "User '$username' has been successfully converted to a systemd-homed managed user!" | |
| } | |
| # Main logic of the script | |
| check_root # Ensure the script is run with root privileges | |
| # Handle arguments | |
| if [[ "$1" == "--help" ]]; then | |
| show_help # Display help message and exit | |
| fi | |
| # Ensure a username is provided | |
| if [[ -z "$1" ]]; then | |
| echo "Error: You must provide a username to convert to systemd-homed." | |
| exit 1 | |
| fi | |
| # Convert the user to systemd-homed | |
| convert_user "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment