أتمتة إنشاء المستخدمين والمجموعات
أنشئ الحسابات وعدّلها ودقّقها بكميات كبيرة باستخدام useradd وchage وإدارة أجزاء sudoers
أتمتة إنشاء المستخدمين والمجموعات درس مجاني في DevOps Bootcamp على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في DevOps Bootcamp، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة DevOps Bootcamp 4 دروس في المجموع.
لماذا نؤتمت إنشاء حسابات المستخدمين؟
يعمل تدبير المستخدمين واحدًا تلو الآخر باستخدام useradd بشكل جيد عند التعامل مع عدد قليل من الحسابات، لكن بيئات المؤسسات تستقبل عادةً عشرات المستخدمين أو مئاتهم في الوقت نفسه. وتصبح الأوامر اليدوية عرضة للأخطاء وغير متسقة ويصعب تدقيقها.
تتيح لكم برمجة Bash ما يلي:
- إنشاء المستخدمين بإعدادات موحّدة في كل مرة (الصدفة، والدليل المنزلي، وسياسة كلمات المرور)
- قراءة ملف CSV أو ملف نصي يحتوي على الموظفين الجدد وإنشاء حساباتهم في تشغيل واحد
- تسجيل كل إجراء لتوفير سجل تدقيق لأغراض الامتثال
- التكامل مع مسارات إدارة الإعدادات (Ansible وChef وJenkins)
يشرح هذا الدرس كيفية بناء برنامج نصي احترافي لإنشاء حسابات المستخدمين من الصفر، مع تغطية useradd وchage وusermod وإدارة المجموعات وملفات الإضافة إلى sudoers والتدقيق بعد التشغيل.
قراءة قائمة مستخدمين بالجملة
التنسيق القياسي للإدخال عند إنشاء الحسابات بالجملة هو ملف نصي محدد الفواصل — سجل واحد في كل سطر. وقد يبدو ملف CSV نموذجي كما يلي:
username,full_name,group,shell
alice,Alice Smith,developers,/bin/bash
bob,Bob Jones,ops,/bin/zshاستخدموا IFS وread داخل حلقة while لتحليل الملف بأمان. ويساعد تخطي سطر العناوين باستخدام tail -n +2 في إبقاء المنطق واضحًا.
ممارسات الحماية الأساسية:
- إزالة المسافات البيضاء في بداية كل حقل ونهايته
- تخطي الأسطر الفارغة وأسطر التعليقات التي تبدأ بالرمز
# - التحقق من أن الحقول الإلزامية غير فارغة قبل استدعاء أي أوامر للنظام
#!/usr/bin/env bash
# parse_users.sh — safely read a CSV of users
set -euo pipefail
USER_FILE="${1:-users.csv}"
[[ -f "$USER_FILE" ]] || { echo "ERROR: $USER_FILE not found"; exit 1; }
tail -n +2 "$USER_FILE" | while IFS=',' read -r username full_name group shell; do
# trim whitespace
username="${username// /}"
[[ -z "$username" || "$username" == \#* ]] && continue
echo "Parsed -> user=$username group=$group shell=$shell"
doneإنشاء المستخدمين باستخدام useradd
تُعدّ useradd أداة منخفضة المستوى تكتب إلى /etc/passwd و/etc/shadow و/etc/group. وأهم الخيارات المستخدمة في البرمجة النصية هي:
-m— إنشاء الدليل المنزلي-s— تعيين صدفة تسجيل الدخول-c— حقل التعليق في GECOS (الاسم الكامل)-G— المجموعات الإضافية (مفصولة بفواصل)-e— تاريخ انتهاء الحساب (YYYY-MM-DD)
تحققوا دائمًا من وجود المستخدم مسبقًا باستخدام id قبل استدعاء useradd؛ إذ يؤدي تشغيلها على مستخدم موجود إلى إرجاع رمز الخروج 9 وطباعة خطأ قد يسبب ازدحامًا في السجلات.
ملاحظة: تتطلب useradd صلاحيات المستخدم الجذر. أحيطوا البرنامج النصي بفحص للصلاحيات في بدايته.
#!/usr/bin/env bash
# create_user.sh — idempotent single-user creation
set -euo pipefail
[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }
USERNAME="$1"
FULL_NAME="${2:-}"
GROUP="${3:-staff}"
SHELL="${4:-/bin/bash}"
if id "$USERNAME" &>/dev/null; then
echo "[SKIP] User $USERNAME already exists"
else
useradd \
--create-home \
--shell "$SHELL" \
--comment "$FULL_NAME" \
--groups "$GROUP" \
"$USERNAME"
echo "[OK] Created $USERNAME"
fiتعيين كلمات المرور الأولية بأمان
لا تضعوا كلمات المرور بشكل ثابت في البرامج النصية. هناك طريقتان آمنتان لإنشاء الحسابات بالجملة:
- إنشاء كلمة مرور أولية عشوائية باستخدام
openssl randأو/dev/urandom، وطباعتها مرة واحدة، وإجبار المستخدم على تغييرها عند أول تسجيل دخول - تعيين كلمة مرور مجزأة مسبقًا باستخدام
usermod -pمع تجزئة SHA-512، بحيث لا تظهر كلمة المرور النصية في قائمة العمليات
تُعدّ chpasswd الأداة الموصى بها لتعيين كلمات المرور في البرامج النصية — فهي تقرأ أزواج username:password من الإدخال القياسي، ولذلك لا تظهر كلمة المرور في وسائط سطر الأوامر (المرئية عبر ps).
بعد تعيين كلمة المرور، استخدموا chage -d 0 لفرض إعادة تعيينها فورًا عند تسجيل الدخول التالي.
#!/usr/bin/env bash
# set_temp_password.sh
set -euo pipefail
[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }
USERNAME="$1"
# Generate a 16-char random password (alphanumeric only)
TMP_PASS=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 16)
# Set password via chpasswd (password never in argv)
echo "${USERNAME}:${TMP_PASS}" | chpasswd
# Force password change on next login
chage -d 0 "$USERNAME"
echo "[OK] Temporary password for $USERNAME: $TMP_PASS"
echo "[OK] User must change password on first login"إدارة تقادم كلمات المرور باستخدام chage
تتحكم chage (تغيير التقادم) في سياسة تقادم كلمات المرور المخزنة في /etc/shadow. وتنص سياسات أمان المؤسسات عادةً على ما يلي:
- الحد الأقصى لعمر كلمة المرور (مثلًا 90 يومًا)
- الحد الأدنى لعدد الأيام قبل إمكانية تغيير كلمة المرور مجددًا
- فترة التحذير قبل انتهاء الصلاحية
- قفل الحساب عند عدم النشاط بعد آخر استخدام لكلمة المرور
خيارات chage الأساسية:
-M <days>— الحد الأقصى لعمر كلمة المرور-m <days>— الحد الأدنى لعمر كلمة المرور-W <days>— عدد أيام التحذير قبل انتهاء الصلاحية-I <days>— عدد أيام عدم النشاط قبل قفل الحساب-E <date>— انتهاء صلاحية الحساب في تاريخ محدد-l— عرض الإعدادات الحالية لمستخدم
#!/usr/bin/env bash
# apply_password_policy.sh — enforce org-wide ageing policy
set -euo pipefail
[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }
# Policy constants
MAX_AGE=90
MIN_AGE=1
WARN_DAYS=14
INACTIVE_DAYS=30
apply_policy() {
local user="$1"
chage \
-M "$MAX_AGE" \
-m "$MIN_AGE" \
-W "$WARN_DAYS" \
-I "$INACTIVE_DAYS" \
"$user"
echo "[OK] Policy applied to $user"
}
# Apply to all non-system users (UID >= 1000)
awk -F: '$3 >= 1000 && $3 < 65534 { print $1 }' /etc/passwd | while read -r user; do
apply_policy "$user"
doneإدارة المجموعات بالجملة
تُعدّ المجموعات الآلية الأساسية للتحكم في الوصول إلى الموارد. ويجب على برنامج إنشاء الحسابات التأكد من وجود المجموعات المطلوبة قبل إضافة المستخدمين إليها — إذ سيفشل useradd -G nonexistent.
استخدموا groupadd بطريقة آمنة قابلة لإعادة التنفيذ من خلال التحقق من رمز الخروج: فهي تُرجع 9 إذا كانت المجموعة موجودة مسبقًا. ويُعدّ التعبير getent group <name> بديلًا محمولًا وواضحًا عن البحث باستخدام grep في /etc/group.
تضيف gpasswd -a مستخدمًا إلى مجموعة من دون استبدال عضوياته الحالية (بخلاف usermod -G التي تستبدل قائمة المجموعات الإضافية).
#!/usr/bin/env bash
# ensure_groups.sh — create groups if missing, then add users
set -euo pipefail
[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }
REQUIRED_GROUPS=(developers ops security auditors)
for grp in "${REQUIRED_GROUPS[@]}"; do
if getent group "$grp" &>/dev/null; then
echo "[SKIP] Group $grp already exists"
else
groupadd "$grp"
echo "[OK] Created group $grp"
fi
done
# Safely add a user to a group (append, don't replace)
add_to_group() {
local user="$1" group="$2"
gpasswd -a "$user" "$group" 2>/dev/null && echo "[OK] $user -> $group"
}البرنامج النصي الكامل لإنشاء الحسابات بالجملة
عند جمع كل الأجزاء معًا: يقرأ برنامج نصي واحد ملف CSV، وينشئ المستخدمين والمجموعات، ويعيّن سياسة كلمات المرور، ويسجل كل إجراء، ويتعامل مع الأخطاء بسلاسة من دون إيقاف الدفعة بأكملها.
قرارات التصميم المهمة في البرنامج النصي أدناه:
- يلتقط
LOG_FILEجميع العمليات مع طوابع زمنية لأغراض التدقيق - تُسجّل أخطاء المستخدمين الأفراد، لكنها لا توقف الحلقة (
|| log_error) - البرنامج النصي قابل لإعادة التنفيذ — وآمن للتشغيل مجددًا بعد الإخفاقات الجزئية
- يُرسل كل الإخراج إلى كل من الطرفية وملف السجل باستخدام
tee
#!/usr/bin/env bash
# bulk_provision.sh — production user provisioning
set -uo pipefail
[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }
USER_FILE="${1:-users.csv}"
LOG_FILE="/var/log/user_provision_$(date +%F).log"
log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOG_FILE"; }
err() { log "ERROR: $*"; }
log "=== Provisioning started from $USER_FILE ==="
tail -n +2 "$USER_FILE" | while IFS=',' read -r username fullname group shell; do
username="${username// /}"
[[ -z "$username" || "$username" == \#* ]] && continue
group="${group:-staff}"
shell="${shell:-/bin/bash}"
# Ensure group exists
getent group "$group" &>/dev/null || groupadd "$group"
# Create user idempotently
if id "$username" &>/dev/null; then
log "[SKIP] $username exists"
else
useradd -m -s "$shell" -c "$fullname" -G "$group" "$username" || { err "useradd failed for $username"; continue; }
TMP="$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 14)"
echo "${username}:${TMP}" | chpasswd
chage -M 90 -m 1 -W 14 -I 30 -d 0 "$username"
log "[OK] $username created (group=$group) tmp_pass=$TMP"
fi
done
log "=== Provisioning complete ==="إدارة ملفات الإضافة إلى sudoers
يُعدّ تحرير /etc/sudoers مباشرةً أمرًا خطيرًا — إذ قد يؤدي خطأ نحوي إلى منع الجميع من استخدام sudo. والطريقة الآمنة هي استخدام ملفات الإضافة داخل /etc/sudoers.d/، مع التحقق من صحة كل ملف باستخدام visudo -c -f قبل وضعه في مكانه.
أفضل الممارسات لملفات sudoers الجزئية:
- سمّوا الملفات بأسماء الفريق أو الدور الذي تمنحه (مثل
10-developersو20-ops) - استخدموا قواعد قائمة على المجموعات (
%developers ALL=(ALL) NOPASSWD: /usr/bin/systemctl) بدلًا من القواعد الخاصة بكل مستخدم - اضبطوا الأذونات دائمًا على
0440والملكية علىroot:root - تحققوا باستخدام
visudo -c— إذ يُرجع رمز خروج غير صفري عند وجود أي خطأ نحوي
#!/usr/bin/env bash
# write_sudoers_fragment.sh
set -euo pipefail
[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }
FRAGMENT_NAME="${1:-10-developers}"
SUDOERS_DIR="/etc/sudoers.d"
TMP_FILE="$(mktemp)"
# Write the fragment to a temp file first
cat > "$TMP_FILE" << 'EOF'
# Developers: restart services and view journals without full root
%developers ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart *, /usr/bin/journalctl
%ops ALL=(ALL) NOPASSWD: ALL
EOF
# Validate BEFORE installing
if visudo -c -f "$TMP_FILE"; then
install -m 0440 -o root -g root "$TMP_FILE" "${SUDOERS_DIR}/${FRAGMENT_NAME}"
echo "[OK] Installed ${SUDOERS_DIR}/${FRAGMENT_NAME}"
else
echo "[ERROR] sudoers syntax check failed — fragment NOT installed"
rm -f "$TMP_FILE"
exit 1
fi
rm -f "$TMP_FILE"تدقيق الحسابات الموجودة
بعد إنشاء الحسابات (وبصفة دورية)، ينبغي لكم تدقيق قاعدة بيانات المستخدمين بحثًا عن الحالات غير الطبيعية:
- الحسابات ذات UID 0 — أي حساب ذي UID 0 بخلاف root يمثل اكتشافًا أمنيًا بالغ الخطورة
- الحسابات التي لا تملك كلمة مرور — الإدخالات التي يحتوي فيها حقل كلمة المرور في
/etc/shadowعلى قيمة فارغة أو على الرمز! - الحسابات المنتهية الصلاحية التي لا تزال نشطة — يمكن تحليل مخرجات
chage -lبالجملة - المستخدمون الذين لديهم صدفات من دون دليل منزلي — إعداد خاطئ يؤدي إلى تعطل تسجيل الدخول
من السهل إنشاء تقرير منظم وإرساله بالبريد الإلكتروني إلى فريق الأمان باستخدام mail أو بإلحاقه بمسار سجل تتم مراقبته.
#!/usr/bin/env bash
# audit_users.sh — produce a security-relevant user report
set -uo pipefail
REPORT="/var/log/user_audit_$(date +%F).txt"
echo "=== User Audit Report $(date) ===" > "$REPORT"
echo "" >> "$REPORT"
echo "--- Accounts with UID 0 (should be root only) ---" >> "$REPORT"
awk -F: '$3 == 0 { print $1 }' /etc/passwd >> "$REPORT"
echo "" >> "$REPORT"
echo "--- Accounts with empty password field ---" >> "$REPORT"
awk -F: '($2 == "" || $2 == "!") && $3 >= 1000 { print $1 }' /etc/shadow 2>/dev/null >> "$REPORT" || echo " (requires root)" >> "$REPORT"
echo "" >> "$REPORT"
echo "--- Normal users (UID 1000-60000) ---" >> "$REPORT"
awk -F: '$3 >= 1000 && $3 < 60000 { printf "%-20s uid=%-6s shell=%s\n", $1, $3, $7 }' /etc/passwd >> "$REPORT"
cat "$REPORT"
echo "Report saved to $REPORT"قفل الحسابات وفتحها وإزالتها
يُعدّ إنهاء حسابات الموظفين المغادرين مهمًا بقدر أهمية إنشاء حسابات الموظفين الجدد. عند مغادرة مستخدم، يكون التسلسل الصحيح كما يلي:
- قفل الحساب فورًا (
usermod -L) — إذ يضيف الرمز!إلى تجزئة كلمة المرور في shadow، ما يمنع تسجيل الدخول من دون حذف البيانات - إلغاء صلاحيات sudo — إزالة ملف sudoers الخاص به إن وُجد
- نقل ملكية ملفاته إلى مدير أو حساب أرشيف
- أرشفة الدليل المنزلي في ملف tar قبل حذفه
- حذف الحساب باستخدام
userdel -r— إذ يزيل الدليل المنزلي وبكرة البريد
يفتح usermod -U قفل الحساب (ويزيل البادئة !)، وهو مفيد للتعليق المؤقت.
#!/usr/bin/env bash
# offboard_user.sh — lock, archive, then optionally delete
set -euo pipefail
[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }
USERNAME="$1"
ARCHIVE_DIR="/srv/archived-homes"
mkdir -p "$ARCHIVE_DIR"
# 1. Lock account
usermod -L "$USERNAME"
echo "[OK] Account $USERNAME locked"
# 2. Remove sudoers fragment if present
SUDOERS_FILE="/etc/sudoers.d/${USERNAME}"
[[ -f "$SUDOERS_FILE" ]] && rm -f "$SUDOERS_FILE" && echo "[OK] Removed sudoers fragment"
# 3. Archive home directory
HOME_DIR="$(getent passwd "$USERNAME" | cut -d: -f6)"
if [[ -d "$HOME_DIR" ]]; then
tar -czf "${ARCHIVE_DIR}/${USERNAME}_$(date +%F).tar.gz" -C "$(dirname "$HOME_DIR")" "$(basename "$HOME_DIR")"
echo "[OK] Home archived to ${ARCHIVE_DIR}/${USERNAME}_$(date +%F).tar.gz"
fi
echo "[NOTICE] Review archive, then run: userdel -r $USERNAME"اختبار البرنامج النصي باستخدام وضع التشغيل التجريبي
يجب أن تكون البرامج النصية لإنشاء الحسابات في بيئة الإنتاج قابلة للاختبار من دون آثار جانبية. نفّذوا وضع التشغيل التجريبي باستخدام علامة DRY_RUN التي تستبدل جميع الأوامر التي تغيّر النظام ببدائل echo.
النمط بسيط: عرّفوا دالة مساعدة باسم run() تنفّذ الأمر أو تعرضه بحسب قيمة العلامة. ويعني هذا الأسلوب ما يلي:
- اختبار جميع مسارات التعليمات البرمجية
- إظهار ما كان سيحدث بالضبط عند التشغيل الفعلي
- تمكين مسارات CI من التحقق من المنطق من دون صلاحيات المستخدم الجذر
أضيفوا إلى التشغيل التجريبي بادئة مخصصة لمستخدم الاختبار (مثل test_) لتسهيل التنظيف بعد اختبارات التكامل.
#!/usr/bin/env bash
# provision_with_dryrun.sh
set -euo pipefail
DRY_RUN="${DRY_RUN:-false}"
# Wrapper: execute or echo
run() {
if [[ "$DRY_RUN" == "true" ]]; then
echo "[DRY-RUN] $*"
else
"$@"
fi
}
create_user() {
local user="$1" group="$2"
if id "$user" &>/dev/null; then
echo "[SKIP] $user exists"
return
fi
run useradd -m -s /bin/bash -G "$group" "$user"
run chage -M 90 -m 1 -W 14 -d 0 "$user"
echo "[OK] $user provisioned (dry=$DRY_RUN)"
}
# Test run
DRY_RUN=true create_user testuser developers
echo "---"
create_user realuser developers 2>/dev/null || trueما الأمر الذي ينبغي استخدامه لإضافة مستخدم إلى مجموعة إضافية من دون إزالة عضوياته الحالية في المجموعات؟
تحتاجون في برنامج نصي لإنشاء الحسابات بالجملة إلى إسناد المستخدم الحالي إلى مجموعة auditors. والمستخدم عضو بالفعل في مجموعتي developers وstaff. فما الأمر الذي يحافظ على جميع العضويات الحالية مع إضافة العضوية الجديدة؟
مراجعة الدرس: أتمتة إنشاء حسابات المستخدمين والمجموعات
بنيتم في هذا الدرس مجموعة أدوات متكاملة واحترافية لإنشاء حسابات المستخدمين. إليكم أهم النقاط:
- تحليل الإدخال بحذر — استخدموا حلقات
IFS/read، وتخطوا الأسطر الفارغة وأسطر التعليقات، وتحققوا من الحقول قبل إجراء أي استدعاء للنظام - أساسيات
useradd— استخدموا دائمًا-m(الدليل المنزلي) و-s(الصدفة) و-c(التعليق) و-G(المجموعات)، وتحققوا من الوجود باستخدامidأولًا لضمان قابلية إعادة التنفيذ - كلمات المرور — عيّنوها عبر الإدخال القياسي لـ
chpasswdلإبعاد النص الصريح عن وسائط العمليات، وفرضوا إعادة التعيين عند أول تسجيل دخول باستخدامchage -d 0 - استخدام
chageلتطبيق السياسة — وحّدوا الحد الأقصى للعمر (-M) وأيام التحذير (-W) وقفل عدم النشاط (-I) عبر جميع الحسابات غير التابعة للنظام - عضوية المجموعات — استخدموا
gpasswd -aأوusermod -aG(مع العلامة-a) للإضافة بدلًا من استبدال العضويات - ملفات الإضافة إلى sudoers — اكتبوا في
/etc/sudoers.d/، وتحققوا باستخدامvisudo -c -fقبل التثبيت، واضبطوا الأذونات على0440 root:root - إنهاء حسابات المغادرين — اقفلوا الحساب (
usermod -L) وأرشفوا الدليل المنزلي ثم احذفوه؛ ولا تتخطوا خطوة الأرشفة أبدًا - وضع التشغيل التجريبي — غلّفوا الأوامر التي تغيّر النظام داخل دالة مساعدة باسم
run()حتى تتمكن المسارات من التحقق من المنطق من دون آثار جانبية تتطلب صلاحيات المستخدم الجذر
يمنحكم الجمع بين هذه الأنماط طبقة أتمتة قابلة للتكرار والتدقيق وآمنة لإدارة الهويات في Linux على أي نطاق.
الأسئلة الشائعة
هل درس «أتمتة إنشاء المستخدمين والمجموعات» مجاني؟
نعم — نص درس «أتمتة إنشاء المستخدمين والمجموعات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة DevOps Bootcamp، انتقل إلى CoddyKit PRO. تتضمن دورة DevOps Bootcamp 4 دروس في المجموع.
ماذا ستتعلم في «أتمتة إنشاء المستخدمين والمجموعات»؟
أنشئ الحسابات وعدّلها ودقّقها بكميات كبيرة باستخدام useradd وchage وإدارة أجزاء sudoers تتمرن على DevOps Bootcamp مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ DevOps Bootcamp؟
لا تُشترط خبرة سابقة. DevOps Bootcamp على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «أتمتة إنشاء المستخدمين والمجموعات»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس DevOps Bootcamp هذا؟
نعم. كل درس في DevOps Bootcamp يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- أتمتة إنشاء المستخدمين والمجموعات
- التحكّم في خدمات systemd وكتابة ملفات الوحدات
- أتمتة الأقراص وأنظمة الملفات والضمّ
- إنشاء سكربتات فحص صحة النظام والتنبيه