Skip to content

Instantly share code, notes, and snippets.

@okikio
Created September 16, 2025 23:34
Show Gist options
  • Select an option

  • Save okikio/e4e3669c74e4f43c8a0131d4d958b771 to your computer and use it in GitHub Desktop.

Select an option

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.
#!/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