Tutorial

Novas atualizações e melhorias para a Macfleet.

Aviso importante

Os exemplos de código e scripts fornecidos nestes tutoriais são apenas para fins educacionais. A Macfleet não é responsável por quaisquer problemas, danos ou vulnerabilidades de segurança que possam surgir do uso, modificação ou implementação destes exemplos. Sempre revise e teste o código em um ambiente seguro antes de usá-lo em sistemas de produção.

User Account Management on macOS

Master user account creation and management on your MacFleet devices using powerful command-line tools. This tutorial covers admin and standard user creation, password management, account configuration, and advanced user lifecycle management for enterprise deployments.

Understanding macOS User Management

macOS provides several command-line tools for user account management:

  • sysadminctl - Modern user account management tool (macOS 10.10+)
  • dscl - Directory Services command-line utility for advanced operations
  • passwd - Password management and changes
  • id - User and group information display
  • whoami - Current user identification

Basic User Account Creation

Create Admin User Account

#!/bin/sh

# Set PATH environment variable
export PATH=/usr/bin:/bin:/usr/sbin:/sbin

# Admin user configuration
USERNAME="Daniel"
FULLNAME="Daniel.Hector"
PASSWORD="One@Two#8"
PASSWORDHINT="One to Eight"

# Create admin user account
sysadminctl -addUser "$USERNAME" -fullName "$FULLNAME" -password "$PASSWORD" -hint "$PASSWORDHINT" -admin

echo "Admin user account '$USERNAME' created successfully"

Create Standard User Account

#!/bin/sh

# Set PATH environment variable
export PATH=/usr/bin:/bin:/usr/sbin:/sbin

# Standard user configuration
USERNAME="Daniel"
FULLNAME="Daniel.Hector"
PASSWORD="One@Two#8"
PASSWORDHINT="One to Eight"

# Create standard user account (no -admin flag)
sysadminctl -addUser "$USERNAME" -fullName "$FULLNAME" -password "$PASSWORD" -hint "$PASSWORDHINT"

echo "Standard user account '$USERNAME' created successfully"

Enhanced User Creation with Validation

#!/bin/bash

# Enhanced user creation with validation
create_user_account() {
    local username="$1"
    local fullname="$2"
    local password="$3"
    local hint="$4"
    local is_admin="${5:-false}"
    
    # Validate inputs
    if [[ -z "$username" || -z "$fullname" || -z "$password" ]]; then
        echo "Error: Username, full name, and password are required"
        return 1
    fi
    
    # Check if user already exists
    if id "$username" &>/dev/null; then
        echo "Error: User '$username' already exists"
        return 1
    fi
    
    # Set PATH environment
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    # Build sysadminctl command
    local cmd="sysadminctl -addUser \"$username\" -fullName \"$fullname\" -password \"$password\""
    
    if [[ -n "$hint" ]]; then
        cmd="$cmd -hint \"$hint\""
    fi
    
    if [[ "$is_admin" == "true" ]]; then
        cmd="$cmd -admin"
        echo "Creating admin user: $username"
    else
        echo "Creating standard user: $username"
    fi
    
    # Execute user creation
    if eval "$cmd"; then
        echo "✓ User '$username' created successfully"
        
        # Display user information
        echo "User details:"
        id "$username"
        return 0
    else
        echo "✗ Failed to create user '$username'"
        return 1
    fi
}

# Usage examples
create_user_account "daniel" "Daniel Hector" "SecurePass123!" "Password hint" "true"
create_user_account "jane" "Jane Smith" "UserPass456!" "Another hint" "false"

Advanced User Management

Batch User Creation

#!/bin/bash

# Batch user creation from configuration
batch_create_users() {
    local config_file="$1"
    
    if [[ ! -f "$config_file" ]]; then
        echo "Error: Configuration file not found: $config_file"
        return 1
    fi
    
    echo "=== Batch User Creation ==="
    
    local success_count=0
    local error_count=0
    
    # Read configuration file (format: username,fullname,password,hint,admin)
    while IFS=',' read -r username fullname password hint is_admin; do
        # Skip empty lines and comments
        [[ -z "$username" || "$username" =~ ^# ]] && continue
        
        echo "Processing user: $username"
        
        if create_user_account "$username" "$fullname" "$password" "$hint" "$is_admin"; then
            ((success_count++))
        else
            ((error_count++))
        fi
        
        echo "---"
    done < "$config_file"
    
    echo "Batch creation completed:"
    echo "✓ Success: $success_count users"
    echo "✗ Errors: $error_count users"
}

# Create sample configuration file
create_user_config() {
    local config_file="/tmp/users_config.csv"
    
    cat > "$config_file" << EOF
# Format: username,fullname,password,hint,admin(true/false)
daniel,Daniel Hector,SecurePass123!,Password hint,true
jane,Jane Smith,UserPass456!,Another hint,false
alex,Alex Johnson,TempPass789!,Temporary password,false
admin,System Administrator,AdminPass000!,Admin access,true
EOF
    
    echo "Sample configuration created: $config_file"
    echo "$config_file"
}

# Usage
config_file=$(create_user_config)
batch_create_users "$config_file"

User Account Modification

#!/bin/bash

# Modify existing user accounts
modify_user_account() {
    local username="$1"
    local action="$2"
    local value="$3"
    
    # Verify user exists
    if ! id "$username" &>/dev/null; then
        echo "Error: User '$username' does not exist"
        return 1
    fi
    
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    case "$action" in
        "password")
            echo "Changing password for user: $username"
            if sysadminctl -resetPasswordFor "$username" -newPassword "$value"; then
                echo "✓ Password changed successfully"
            else
                echo "✗ Failed to change password"
                return 1
            fi
            ;;
        "fullname")
            echo "Changing full name for user: $username"
            if dscl . -change "/Users/$username" RealName "$(dscl . -read "/Users/$username" RealName | cut -d: -f2 | xargs)" "$value"; then
                echo "✓ Full name changed to: $value"
            else
                echo "✗ Failed to change full name"
                return 1
            fi
            ;;
        "admin")
            if [[ "$value" == "true" ]]; then
                echo "Granting admin privileges to: $username"
                if dseditgroup -o edit -a "$username" -t user admin; then
                    echo "✓ Admin privileges granted"
                else
                    echo "✗ Failed to grant admin privileges"
                    return 1
                fi
            else
                echo "Removing admin privileges from: $username"
                if dseditgroup -o edit -d "$username" -t user admin; then
                    echo "✓ Admin privileges removed"
                else
                    echo "✗ Failed to remove admin privileges"
                    return 1
                fi
            fi
            ;;
        "enable")
            echo "Enabling user account: $username"
            if dscl . -create "/Users/$username" AuthenticationAuthority; then
                echo "✓ User account enabled"
            else
                echo "✗ Failed to enable user account"
                return 1
            fi
            ;;
        "disable")
            echo "Disabling user account: $username"
            if dscl . -delete "/Users/$username" AuthenticationAuthority; then
                echo "✓ User account disabled"
            else
                echo "✗ Failed to disable user account"
                return 1
            fi
            ;;
        *)
            echo "Error: Unknown action '$action'"
            echo "Available actions: password, fullname, admin, enable, disable"
            return 1
            ;;
    esac
}

# Usage examples
modify_user_account "daniel" "password" "NewSecurePass123!"
modify_user_account "jane" "admin" "true"
modify_user_account "alex" "fullname" "Alexander Johnson"

User Account Deletion

#!/bin/bash

# Delete user accounts with options
delete_user_account() {
    local username="$1"
    local delete_home="${2:-true}"
    local backup_home="${3:-false}"
    
    # Verify user exists
    if ! id "$username" &>/dev/null; then
        echo "Error: User '$username' does not exist"
        return 1
    fi
    
    # Prevent deletion of critical system users
    local system_users=("root" "daemon" "nobody" "_www" "_mysql" "_postgresql")
    for sys_user in "${system_users[@]}"; do
        if [[ "$username" == "$sys_user" ]]; then
            echo "Error: Cannot delete system user '$username'"
            return 1
        fi
    done
    
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    echo "Preparing to delete user: $username"
    
    # Backup home directory if requested
    if [[ "$backup_home" == "true" ]]; then
        local backup_dir="/var/backups/deleted_users"
        local timestamp=$(date +%Y%m%d_%H%M%S)
        local backup_path="$backup_dir/${username}_${timestamp}.tar.gz"
        
        mkdir -p "$backup_dir"
        
        echo "Backing up home directory to: $backup_path"
        if tar -czf "$backup_path" -C "/Users" "$username" 2>/dev/null; then
            echo "✓ Home directory backed up"
        else
            echo "⚠ Warning: Failed to backup home directory"
        fi
    fi
    
    # Delete user account
    local delete_cmd="sysadminctl -deleteUser \"$username\""
    
    if [[ "$delete_home" == "true" ]]; then
        delete_cmd="$delete_cmd -secure"
        echo "Deleting user and home directory..."
    else
        echo "Deleting user account only..."
    fi
    
    if eval "$delete_cmd"; then
        echo "✓ User '$username' deleted successfully"
        return 0
    else
        echo "✗ Failed to delete user '$username'"
        return 1
    fi
}

# Usage examples
delete_user_account "testuser" "true" "true"  # Delete with home, backup first
delete_user_account "tempuser" "false" "false"  # Delete user only, no backup

Enterprise User Management System

#!/bin/bash

# MacFleet User Management Tool
# Comprehensive user account management for fleet devices

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_users.log"
REPORT_DIR="/etc/macfleet/reports/users"
CONFIG_DIR="/etc/macfleet/users"
BACKUP_DIR="/var/backups/macfleet_users"

# Create directories if they don't exist
mkdir -p "$REPORT_DIR" "$CONFIG_DIR" "$BACKUP_DIR"

# User account categories
declare -A USER_CATEGORIES=(
    ["administrator"]="admin,full_privileges,system_access"
    ["developer"]="standard,sudo_group,development_access"
    ["standard_user"]="standard,basic_privileges,user_access"
    ["service_account"]="standard,no_login,service_access"
    ["temporary_user"]="standard,limited_time,restricted_access"
    ["guest_user"]="standard,guest_privileges,temporary_access"
    ["kiosk_user"]="standard,kiosk_mode,restricted_access"
    ["backup_operator"]="standard,backup_privileges,system_access"
    ["monitoring_user"]="standard,read_only,monitoring_access"
    ["deployment_user"]="admin,deployment_privileges,automated_access"
)

# User management policies
declare -A USER_POLICIES=(
    ["password_strength"]="minimum_8_chars,mixed_case,numbers,special_chars"
    ["password_expiry"]="90_days,180_days,365_days,never"
    ["account_lockout"]="3_attempts,5_attempts,10_attempts,disabled"
    ["session_timeout"]="15_minutes,30_minutes,60_minutes,4_hours"
    ["home_directory"]="local_only,network_shared,encrypted,no_home"
    ["shell_access"]="/bin/bash,/bin/zsh,/usr/bin/false,/sbin/nologin"
)

# Logging function
log_action() {
    local message="$1"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] $message" | tee -a "$LOG_FILE"
}

# Enhanced user creation with enterprise features
create_enterprise_user() {
    local username="$1"
    local fullname="$2"
    local password="$3"
    local category="${4:-standard_user}"
    local custom_options="$5"
    
    log_action "Creating enterprise user: $username (Category: $category)"
    
    # Validate inputs
    if [[ -z "$username" || -z "$fullname" || -z "$password" ]]; then
        log_action "ERROR: Username, full name, and password are required"
        return 1
    fi
    
    # Check if user already exists
    if id "$username" &>/dev/null; then
        log_action "ERROR: User '$username' already exists"
        return 1
    fi
    
    # Validate password strength
    if ! validate_password_strength "$password"; then
        log_action "ERROR: Password does not meet strength requirements"
        return 1
    fi
    
    # Generate unique UID
    local new_uid=$(get_next_available_uid)
    
    # Create user account based on category
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    local is_admin="false"
    local shell="/bin/bash"
    local home_dir="/Users/$username"
    
    # Parse category configuration
    IFS=',' read -ra CATEGORY_PARTS <<< "${USER_CATEGORIES[$category]}"
    local user_type="${CATEGORY_PARTS[0]}"
    local privileges="${CATEGORY_PARTS[1]}"
    local access_level="${CATEGORY_PARTS[2]}"
    
    [[ "$user_type" == "admin" ]] && is_admin="true"
    [[ "$privileges" == "no_login" ]] && shell="/usr/bin/false"
    
    # Create the user account
    local create_cmd="sysadminctl -addUser \"$username\" -fullName \"$fullname\" -password \"$password\" -UID \"$new_uid\""
    
    if [[ "$is_admin" == "true" ]]; then
        create_cmd="$create_cmd -admin"
    fi
    
    if eval "$create_cmd"; then
        log_action "SUCCESS: User '$username' created with UID $new_uid"
        
        # Apply additional configurations
        configure_user_environment "$username" "$category" "$custom_options"
        
        # Generate user report
        local report_file="$REPORT_DIR/user_creation_${username}_$(date +%Y%m%d_%H%M%S).json"
        generate_user_report "$username" "$report_file"
        
        echo "$report_file"
        return 0
    else
        log_action "ERROR: Failed to create user '$username'"
        return 1
    fi
}

# Password strength validation
validate_password_strength() {
    local password="$1"
    local min_length=8
    
    # Check minimum length
    if [[ ${#password} -lt $min_length ]]; then
        echo "Password must be at least $min_length characters long"
        return 1
    fi
    
    # Check for uppercase letter
    if [[ ! "$password" =~ [A-Z] ]]; then
        echo "Password must contain at least one uppercase letter"
        return 1
    fi
    
    # Check for lowercase letter
    if [[ ! "$password" =~ [a-z] ]]; then
        echo "Password must contain at least one lowercase letter"
        return 1
    fi
    
    # Check for digit
    if [[ ! "$password" =~ [0-9] ]]; then
        echo "Password must contain at least one digit"
        return 1
    fi
    
    # Check for special character
    if [[ ! "$password" =~ [^a-zA-Z0-9] ]]; then
        echo "Password must contain at least one special character"
        return 1
    fi
    
    return 0
}

# Get next available UID
get_next_available_uid() {
    local start_uid=1000
    local max_uid=65533
    
    for ((uid=start_uid; uid<=max_uid; uid++)); do
        if ! id -u "$uid" &>/dev/null; then
            echo "$uid"
            return 0
        fi
    done
    
    echo "65534"  # Fallback UID
}

# Configure user environment based on category
configure_user_environment() {
    local username="$1"
    local category="$2"
    local custom_options="$3"
    
    log_action "Configuring environment for user: $username (Category: $category)"
    
    case "$category" in
        "developer")
            # Add to developer group
            dseditgroup -o create -q developer 2>/dev/null
            dseditgroup -o edit -a "$username" -t user developer
            
            # Grant sudo access for development
            echo "$username ALL=(ALL) NOPASSWD: /usr/bin/xcodebuild, /usr/local/bin/brew" > "/etc/sudoers.d/$username"
            ;;
        "service_account")
            # Disable login shell
            dscl . -create "/Users/$username" UserShell /usr/bin/false
            
            # Hide from login window
            dscl . -create "/Users/$username" IsHidden 1
            ;;
        "kiosk_user")
            # Set up kiosk environment
            setup_kiosk_user "$username"
            ;;
        "temporary_user")
            # Set account expiration (30 days)
            local expiry_date=$(date -v +30d +%Y-%m-%d)
            dscl . -create "/Users/$username" AccountExpires "$expiry_date"
            ;;
    esac
    
    # Apply custom options if provided
    if [[ -n "$custom_options" ]]; then
        apply_custom_user_options "$username" "$custom_options"
    fi
}

# Set up kiosk user environment
setup_kiosk_user() {
    local username="$1"
    local kiosk_dir="/Users/$username/Desktop"
    
    # Create kiosk desktop environment
    mkdir -p "$kiosk_dir"
    
    # Create launchd plist for kiosk mode
    cat > "/Library/LaunchAgents/com.macfleet.kiosk.$username.plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.macfleet.kiosk.$username</string>
    <key>ProgramArguments</key>
    <array>
        <string>/System/Applications/Safari.app/Contents/MacOS/Safari</string>
        <string>--kiosk</string>
        <string>https://company-portal.example.com</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>UserName</key>
    <string>$username</string>
</dict>
</plist>
EOF
    
    chown "$username:staff" "/Library/LaunchAgents/com.macfleet.kiosk.$username.plist"
    chmod 644 "/Library/LaunchAgents/com.macfleet.kiosk.$username.plist"
}

# Generate user report
generate_user_report() {
    local username="$1"
    local report_file="$2"
    
    # Get user information
    local user_info=$(id "$username")
    local user_groups=$(groups "$username")
    local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory | cut -d: -f2 | xargs)
    local shell=$(dscl . -read "/Users/$username" UserShell | cut -d: -f2 | xargs)
    local real_name=$(dscl . -read "/Users/$username" RealName | cut -d: -f2 | xargs)
    
    cat > "$report_file" << EOF
{
    "user_report": {
        "username": "$username",
        "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "hostname": "$(hostname)",
        "script_version": "$SCRIPT_VERSION",
        "user_details": {
            "real_name": "$real_name",
            "home_directory": "$home_dir",
            "shell": "$shell",
            "user_info": "$user_info",
            "groups": "$user_groups"
        },
        "creation_status": "success",
        "security_settings": {
            "password_policy_applied": true,
            "account_restrictions": [],
            "group_memberships": []
        }
    }
}
EOF
    
    log_action "User report generated: $report_file"
}

# Fleet user management
manage_fleet_users() {
    local action="$1"
    local target_spec="$2"
    local options="$3"
    
    log_action "Fleet user management: $action"
    
    case "$action" in
        "audit")
            audit_fleet_users "$target_spec"
            ;;
        "sync")
            sync_fleet_users "$target_spec" "$options"
            ;;
        "cleanup")
            cleanup_fleet_users "$target_spec" "$options"
            ;;
        "report")
            generate_fleet_user_report
            ;;
    esac
}

# Audit all users on the system
audit_fleet_users() {
    local filter_pattern="$1"
    
    echo "=== Fleet User Audit ==="
    
    local audit_report="$REPORT_DIR/fleet_user_audit_$(date +%Y%m%d_%H%M%S).json"
    
    cat > "$audit_report" << EOF
{
    "audit_info": {
        "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "hostname": "$(hostname)",
        "filter_pattern": "$filter_pattern"
    },
    "user_accounts": [],
    "security_summary": {},
    "recommendations": []
}
EOF
    
    # Get all local users
    local users=($(dscl . -list /Users | grep -v "^_" | grep -v "daemon\|nobody\|root"))
    
    for user in "${users[@]}"; do
        if [[ -z "$filter_pattern" || "$user" =~ $filter_pattern ]]; then
            # Get detailed user information
            local uid=$(id -u "$user" 2>/dev/null)
            local gid=$(id -g "$user" 2>/dev/null)
            local groups=$(groups "$user" 2>/dev/null)
            local home=$(dscl . -read "/Users/$user" NFSHomeDirectory 2>/dev/null | cut -d: -f2 | xargs)
            local shell=$(dscl . -read "/Users/$user" UserShell 2>/dev/null | cut -d: -f2 | xargs)
            local last_login=$(last -1 "$user" | head -1 | awk '{print $4, $5, $6, $7}')
            
            # Check if user is admin
            local is_admin="false"
            if dseditgroup -o checkmember -m "$user" admin &>/dev/null; then
                is_admin="true"
            fi
            
            # Add to report
            jq --arg user "$user" \
               --arg uid "$uid" \
               --arg gid "$gid" \
               --arg groups "$groups" \
               --arg home "$home" \
               --arg shell "$shell" \
               --arg last_login "$last_login" \
               --arg is_admin "$is_admin" \
               '.user_accounts += [{
                   "username": $user,
                   "uid": $uid,
                   "gid": $gid,
                   "groups": $groups,
                   "home_directory": $home,
                   "shell": $shell,
                   "last_login": $last_login,
                   "is_admin": ($is_admin == "true")
               }]' "$audit_report" > "${audit_report}.tmp" && mv "${audit_report}.tmp" "$audit_report"
        fi
    done
    
    # Generate security summary
    local total_users=$(echo "${users[@]}" | wc -w)
    local admin_users=$(dseditgroup -o checkmember -m "" admin 2>/dev/null | wc -l)
    local inactive_users=0
    
    # Check for inactive users (no login in 90 days)
    for user in "${users[@]}"; do
        local last_login_timestamp=$(last -1 "$user" | head -1 | awk '{print $4, $5, $6, $7}')
        if [[ -n "$last_login_timestamp" ]]; then
            local days_since_login=$(( ($(date +%s) - $(date -j -f "%b %d %H:%M" "$last_login_timestamp" +%s 2>/dev/null || echo 0)) / 86400 ))
            if [[ $days_since_login -gt 90 ]]; then
                ((inactive_users++))
            fi
        fi
    done
    
    jq --argjson total "$total_users" \
       --argjson admins "$admin_users" \
       --argjson inactive "$inactive_users" \
       '.security_summary = {
           "total_users": $total,
           "admin_users": $admins,
           "inactive_users": $inactive,
           "security_score": (100 - ($admins * 10) - ($inactive * 5))
       }' "$audit_report" > "${audit_report}.tmp" && mv "${audit_report}.tmp" "$audit_report"
    
    log_action "Fleet user audit completed: $audit_report"
    echo "$audit_report"
}

# Main execution function
main() {
    local action="${1:-create}"
    local username="${2:-}"
    local fullname="${3:-}"
    local password="${4:-}"
    local options="${5:-}"
    
    log_action "=== MacFleet User Management Started ==="
    log_action "Action: $action, User: $username"
    
    case "$action" in
        "create")
            if [[ -z "$username" || -z "$fullname" || -z "$password" ]]; then
                echo "Usage: $0 create <username> <fullname> <password> [category]"
                exit 1
            fi
            create_enterprise_user "$username" "$fullname" "$password" "$options"
            ;;
        "modify")
            if [[ -z "$username" || -z "$fullname" ]]; then
                echo "Usage: $0 modify <username> <action> <value>"
                exit 1
            fi
            modify_user_account "$username" "$fullname" "$password"
            ;;
        "delete")
            if [[ -z "$username" ]]; then
                echo "Usage: $0 delete <username> [delete_home] [backup_home]"
                exit 1
            fi
            delete_user_account "$username" "$fullname" "$password"
            ;;
        "audit")
            audit_fleet_users "$username"
            ;;
        "fleet")
            manage_fleet_users "$username" "$fullname" "$password"
            ;;
        "help")
            echo "Usage: $0 [action] [options...]"
            echo "Actions:"
            echo "  create <username> <fullname> <password> [category] - Create user"
            echo "  modify <username> <action> <value> - Modify user"
            echo "  delete <username> [delete_home] [backup_home] - Delete user"
            echo "  audit [pattern] - Audit users"
            echo "  fleet <action> [pattern] [options] - Fleet management"
            echo "  help - Show this help"
            echo ""
            echo "Categories: ${!USER_CATEGORIES[*]}"
            ;;
        *)
            log_action "ERROR: Unknown action: $action"
            exit 1
            ;;
    esac
    
    log_action "=== User management completed ==="
}

# Execute main function
main "$@"

Common User Management Tasks

User Information Display

#!/bin/bash

# Display comprehensive user information
show_user_info() {
    local username="$1"
    
    if ! id "$username" &>/dev/null; then
        echo "User '$username' does not exist"
        return 1
    fi
    
    echo "=== User Information: $username ==="
    
    # Basic user information
    echo "User ID Information:"
    id "$username"
    
    # Group memberships
    echo -e "\nGroup Memberships:"
    groups "$username"
    
    # Home directory information
    local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory | cut -d: -f2 | xargs)
    echo -e "\nHome Directory: $home_dir"
    if [[ -d "$home_dir" ]]; then
        echo "Home directory size: $(du -sh "$home_dir" | cut -f1)"
    fi
    
    # Login shell
    local shell=$(dscl . -read "/Users/$username" UserShell | cut -d: -f2 | xargs)
    echo -e "\nLogin Shell: $shell"
    
    # Account status
    echo -e "\nAccount Status:"
    if dscl . -read "/Users/$username" AuthenticationAuthority &>/dev/null; then
        echo "Account: Enabled"
    else
        echo "Account: Disabled"
    fi
    
    # Admin status
    if dseditgroup -o checkmember -m "$username" admin &>/dev/null; then
        echo "Admin Privileges: Yes"
    else
        echo "Admin Privileges: No"
    fi
    
    # Last login
    echo -e "\nLast Login:"
    last -1 "$username" | head -1
}

# Usage
show_user_info "daniel"

Password Management

#!/bin/bash

# Comprehensive password management
manage_user_password() {
    local username="$1"
    local action="$2"
    local new_password="$3"
    
    if ! id "$username" &>/dev/null; then
        echo "User '$username' does not exist"
        return 1
    fi
    
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    case "$action" in
        "change")
            if [[ -z "$new_password" ]]; then
                echo "New password required"
                return 1
            fi
            
            if ! validate_password_strength "$new_password"; then
                return 1
            fi
            
            if sysadminctl -resetPasswordFor "$username" -newPassword "$new_password"; then
                echo "Password changed successfully for user: $username"
                
                # Force password change on next login (optional)
                # pwpolicy -u "$username" -setpolicy "newPasswordRequired=1"
            else
                echo "Failed to change password"
                return 1
            fi
            ;;
        "expire")
            echo "Expiring password for user: $username"
            if pwpolicy -u "$username" -setpolicy "newPasswordRequired=1"; then
                echo "Password expired - user must change on next login"
            else
                echo "Failed to expire password"
                return 1
            fi
            ;;
        "unlock")
            echo "Unlocking account for user: $username"
            if pwpolicy -u "$username" -setpolicy "isDisabled=0"; then
                echo "Account unlocked successfully"
            else
                echo "Failed to unlock account"
                return 1
            fi
            ;;
        *)
            echo "Unknown password action: $action"
            echo "Available actions: change, expire, unlock"
            return 1
            ;;
    esac
}

# Usage
manage_user_password "daniel" "change" "NewSecurePassword123!"

Group Management

#!/bin/bash

# User group management
manage_user_groups() {
    local username="$1"
    local action="$2"
    local group_name="$3"
    
    if ! id "$username" &>/dev/null; then
        echo "User '$username' does not exist"
        return 1
    fi
    
    case "$action" in
        "add")
            echo "Adding user '$username' to group '$group_name'"
            if dseditgroup -o edit -a "$username" -t user "$group_name"; then
                echo "✓ User added to group successfully"
            else
                echo "✗ Failed to add user to group"
                return 1
            fi
            ;;
        "remove")
            echo "Removing user '$username' from group '$group_name'"
            if dseditgroup -o edit -d "$username" -t user "$group_name"; then
                echo "✓ User removed from group successfully"
            else
                echo "✗ Failed to remove user from group"
                return 1
            fi
            ;;
        "list")
            echo "Groups for user '$username':"
            groups "$username"
            ;;
        *)
            echo "Unknown group action: $action"
            echo "Available actions: add, remove, list"
            return 1
            ;;
    esac
}

# Usage
manage_user_groups "daniel" "add" "developers"
manage_user_groups "daniel" "list"

Important Notes

  • Admin privileges required for user creation and modification
  • Password policies should enforce strong passwords for security
  • User validation - Always verify inputs before creating accounts
  • Home directory permissions - Ensure proper ownership and permissions
  • Backup user data before deletion operations
  • Test scripts on individual accounts before fleet deployment
  • Monitor user activities for security compliance

Tutorial

Novas atualizações e melhorias para a Macfleet.

Configurando um Runner do GitHub Actions em um Mac Mini (Apple Silicon)

Runner do GitHub Actions

GitHub Actions é uma plataforma poderosa de CI/CD que permite automatizar seus fluxos de trabalho de desenvolvimento de software. Embora o GitHub ofereça runners hospedados, runners auto-hospedados fornecem maior controle e personalização para sua configuração de CI/CD. Este tutorial o guia através da configuração e conexão de um runner auto-hospedado em um Mac mini para executar pipelines do macOS.

Pré-requisitos

Antes de começar, certifique-se de ter:

  • Um Mac mini (registre-se no Macfleet)
  • Um repositório GitHub com direitos de administrador
  • Um gerenciador de pacotes instalado (preferencialmente Homebrew)
  • Git instalado em seu sistema

Passo 1: Criar uma Conta de Usuário Dedicada

Primeiro, crie uma conta de usuário dedicada para o runner do GitHub Actions:

# Criar a conta de usuário 'gh-runner'
sudo dscl . -create /Users/gh-runner
sudo dscl . -create /Users/gh-runner UserShell /bin/bash
sudo dscl . -create /Users/gh-runner RealName "GitHub runner"
sudo dscl . -create /Users/gh-runner UniqueID "1001"
sudo dscl . -create /Users/gh-runner PrimaryGroupID 20
sudo dscl . -create /Users/gh-runner NFSHomeDirectory /Users/gh-runner

# Definir a senha para o usuário
sudo dscl . -passwd /Users/gh-runner sua_senha

# Adicionar 'gh-runner' ao grupo 'admin'
sudo dscl . -append /Groups/admin GroupMembership gh-runner

Mude para a nova conta de usuário:

su gh-runner

Passo 2: Instalar Software Necessário

Instale Git e Rosetta 2 (se estiver usando Apple Silicon):

# Instalar Git se ainda não estiver instalado
brew install git

# Instalar Rosetta 2 para Macs Apple Silicon
softwareupdate --install-rosetta

Passo 3: Configurar o Runner do GitHub Actions

  1. Vá para seu repositório GitHub
  2. Navegue para Configurações > Actions > Runners

Runner do GitHub Actions

  1. Clique em "New self-hosted runner" (https://github.com/<username>/<repository>/settings/actions/runners/new)
  2. Selecione macOS como imagem do runner e ARM64 como arquitetura
  3. Siga os comandos fornecidos para baixar e configurar o runner

Runner do GitHub Actions

Crie um arquivo .env no diretório _work do runner:

# arquivo _work/.env
ImageOS=macos15
XCODE_15_DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  1. Execute o script run.sh em seu diretório do runner para completar a configuração.
  2. Verifique se o runner está ativo e ouvindo por trabalhos no terminal e verifique as configurações do repositório GitHub para a associação do runner e status Idle.

Runner do GitHub Actions

Passo 4: Configurar Sudoers (Opcional)

Se suas ações requerem privilégios de root, configure o arquivo sudoers:

sudo visudo

Adicione a seguinte linha:

gh-runner ALL=(ALL) NOPASSWD: ALL

Passo 5: Usar o Runner em Fluxos de Trabalho

Configure seu fluxo de trabalho do GitHub Actions para usar o runner auto-hospedado:

name: Fluxo de trabalho de exemplo

on:
  workflow_dispatch:

jobs:
  build:
    runs-on: [self-hosted, macOS, ARM64]
    steps:
      - name: Instalar NodeJS
        run: brew install node

O runner está autenticado em seu repositório e rotulado com self-hosted, macOS, e ARM64. Use-o em seus fluxos de trabalho especificando estes rótulos no campo runs-on:

runs-on: [self-hosted, macOS, ARM64]

Melhores Práticas

  • Mantenha seu software do runner atualizado
  • Monitore regularmente os logs do runner para problemas
  • Use rótulos específicos para diferentes tipos de runners
  • Implemente medidas de segurança adequadas
  • Considere usar múltiplos runners para balanceamento de carga

Solução de Problemas

Problemas comuns e soluções:

  1. Runner não conectando:

    • Verifique conectividade de rede
    • Verifique validade do token GitHub
    • Certifique-se de permissões adequadas
  2. Falhas de build:

    • Verifique instalação do Xcode
    • Verifique dependências necessárias
    • Revise logs do fluxo de trabalho
  3. Problemas de permissão:

    • Verifique permissões do usuário
    • Verifique configuração sudoers
    • Revise permissões do sistema de arquivos

Conclusão

Agora você tem um runner auto-hospedado do GitHub Actions configurado em seu Mac mini. Esta configuração fornece mais controle sobre seu ambiente CI/CD e permite executar fluxos de trabalho específicos do macOS de forma eficiente.

Lembre-se de manter regularmente seu runner e mantê-lo atualizado com os patches de segurança e versões de software mais recentes.

Aplicativo Nativo

Aplicativo nativo do Macfleet

Guia de Instalação do Macfleet

Macfleet é uma solução poderosa de gerenciamento de frota projetada especificamente para ambientes Mac Mini hospedados na nuvem. Como provedor de hospedagem na nuvem Mac Mini, você pode usar o Macfleet para monitorar, gerenciar e otimizar toda sua frota de instâncias Mac virtualizadas.

Este guia de instalação o conduzirá através da configuração do monitoramento do Macfleet em sistemas macOS, Windows e Linux para garantir supervisão abrangente de sua infraestrutura na nuvem.

🍎 macOS

  • Baixe o arquivo .dmg para Mac aqui
  • Clique duas vezes no arquivo .dmg baixado
  • Arraste o aplicativo Macfleet para a pasta Aplicativos
  • Ejete o arquivo .dmg
  • Abra Preferências do Sistema > Segurança e Privacidade
    • Aba Privacidade > Acessibilidade
    • Marque Macfleet para permitir monitoramento
  • Inicie o Macfleet a partir de Aplicativos
  • O rastreamento inicia automaticamente

🪟 Windows

  • Baixe o arquivo .exe para Windows aqui
  • Clique com o botão direito no arquivo .exe > "Executar como administrador"
  • Siga o assistente de instalação
  • Aceite os termos e condições
  • Permita no Windows Defender se solicitado
  • Conceda permissões de monitoramento de aplicativo
  • Inicie o Macfleet a partir do Menu Iniciar
  • O aplicativo começa o rastreamento automaticamente

🐧 Linux

  • Baixe o pacote .deb (Ubuntu/Debian) ou .rpm (CentOS/RHEL) aqui
  • Instale usando seu gerenciador de pacotes
    • Ubuntu/Debian: sudo dpkg -i Macfleet-linux.deb
    • CentOS/RHEL: sudo rpm -ivh Macfleet-linux.rpm
  • Permita permissões de acesso X11 se solicitado
  • Adicione o usuário aos grupos apropriados se necessário
  • Inicie o Macfleet a partir do menu Aplicativos
  • O aplicativo começa o rastreamento automaticamente

Nota: Após a instalação em todos os sistemas, faça login com suas credenciais do Macfleet para sincronizar dados com seu painel de controle.