# Forzar reinicio

> Script macOS que monitoriza el tiempo de actividad y escala alertas con swiftDialog para forzar reinicios, con una cuenta regresiva de 10 minutos forzada tras 13 o más días sin reiniciar.

Source: https://docs.applivery.com/es/device-management/apple/macos/scripts/force-reboot/  •  Last updated: 2026-04-18

**Answers:** ¿Por qué es importante reiniciar periódicamente los dispositivos macOS? · ¿Cómo funciona el script de política de reinicio forzado? · ¿Qué ocurre si un dispositivo macOS lleva 9-12 días sin reiniciar? · ¿Qué ocurre cuando un dispositivo macOS lleva 13 o más días en funcionamiento? · ¿Se requiere un logotipo corporativo para el script de política de reinicio forzado? · ¿Qué versión de macOS se requiere para ejecutar el script de política de reinicio forzado? · ¿Con qué frecuencia debe ejecutarse el script de política de reinicio forzado? · ¿Qué es swiftDialog y es obligatorio?

**Key topics:** gestión de dispositivos, automatización, scripting, Applivery, MDM, Administradores TI

---

**TL;DR:** Automatiza tareas repetitivas en dispositivos gestionados usando scripts en Applivery para una gestión de dispositivos eficiente.

Los parches de seguridad solo surten efecto después de un reinicio. En la práctica, los usuarios posponen los reinicios indefinidamente — y cuanto más tiempo lleva un dispositivo sin reiniciar, más actualizaciones de seguridad se acumulan en estado pendiente. Los equipos que llevan semanas encendidos también tienden a mostrar un rendimiento degradado y presión de memoria que un simple reinicio resolvería.

El problema de forzar un reinicio con un apagado abrupto es que causa interrupciones y frustración. Este script adopta un enfoque más gradual: monitoriza el tiempo de actividad y escala progresivamente, comenzando con una notificación discreta y solo forzando una cuenta regresiva cuando el dispositivo lleva 13 o más días en funcionamiento. Los usuarios tienen tiempo suficiente para guardar su trabajo; TI tiene la garantía de que los reinicios realmente ocurren.

Las alertas se muestran usando swiftDialog (instalado automáticamente si no está presente) con la marca de tu empresa, para que los usuarios las reconozcan como comunicaciones TI legítimas.

:::warning
El agente de Applivery para macOS debe estar instalado y activo en el dispositivo. Obtén más información sobre el [agente macOS](https://docs.applivery.com/es/device-management/apple/apple-policies/agent/#agent-app-for-macos-devices).
:::

## Requisitos

| Requisito | Detalle |
|---|---|
| Plataforma | macOS 11.0 (Big Sur) o posterior |
| Privilegios de ejecución | Root (predeterminado en Applivery) |
| Marca corporativa | `/var/root/CompanyAssets/logo.png` (opcional, para diálogos con marca) |
| swiftDialog | Se instala automáticamente si no está presente |

---

## Niveles de escalada

El script calcula el tiempo de actividad actual del sistema en días y aplica una política de escalada de cuatro niveles:

| Tiempo de actividad | Acción |
|---|---|
| 0–4 días | Sin acción |
| 5–8 días | Notificación de macOS con alerta sonora |
| 9–12 días | Ventana de diálogo con opciones **Reiniciar ahora** y **Posponer** (24h). Se cierra automáticamente después de 14 minutos |
| 13+ días | Advertencia a pantalla completa seguida de una cuenta regresiva de 10 minutos. El Mac se reinicia cuando llega a cero, o el usuario hace clic en **Reiniciar ahora** |

---

## Configuración

**Desplegar el logotipo corporativo (opcional)**

Antes de desplegar este script, asegúrate de que tu logotipo corporativo esté disponible en `/var/root/CompanyAssets/logo.png` en cada dispositivo gestionado. El script redimensiona y copia el logotipo a la carpeta de recursos de swiftDialog automáticamente. Usar el logotipo corporativo garantiza que los usuarios reconozcan las alertas como comunicaciones TI y no las descarten como ruido. Puedes distribuir el archivo usando la [gestión de archivos de Applivery](https://docs.applivery.com/es/device-management/apple/macos/policies/file-management/).

**Crear el script**

Una vez en el [**panel de Applivery**](https://dashboard.applivery.io/), sigue los pasos descritos [aquí](https://docs.applivery.com/es/device-management/apple/macos/scripts/index) para crear un script. Pega el siguiente script en el editor, selecciona **Bash** como lenguaje, dale un nombre descriptivo (por ejemplo, `Política de reinicio forzado`) y haz clic en **Crear**.

```bash
#!/bin/bash

# ---
# Title: Force Reboot Policy (Uptime Enforcement)
# Description: Monitors macOS uptime and triggers escalating alerts via swiftDialog to force a restart.
# Author: Applivery
# Version: 1.2.0
# ---

# ==========================================
# 1. CLEANUP OLD INSTALLATIONS
# ==========================================
DIALOG_OLD="/Applications/Dialog.app"

if [ -d "$DIALOG_OLD" ]; then
  echo "→ Old Dialog.app found"
  pgrep -if "Dialog.app" && {
    echo "  → Quitting Dialog..."
    pkill -if "Dialog.app" 2>/dev/null
    sleep 1
  }
  if sudo rm -rf "$DIALOG_OLD" 2>/dev/null; then
    echo "  → Removed successfully"
  else
    echo "  → Failed to remove legacy app."
  fi
else
  echo "→ No old Dialog.app present"
fi

# ==========================================
# 2. PRE-FLIGHT & BRANDING SETUP
# ==========================================
PATH=/usr/bin:/bin:/usr/sbin:/sbin

DIALOG_CLI="/usr/local/bin/dialog"
DIALOG_APP="/Library/Application Support/Dialog/Dialog.app"
DIALOG_ICON_DIR="/Library/Application Support/Dialog"
DIALOG_ICON="$DIALOG_ICON_DIR/Dialog.png"
BRAND_ICON="/var/root/CompanyAssets/logo.png"

needs_install=0
needs_reinstall=0

CURRENT_USER=$(stat -f %Su /dev/console)
USER_ID=$(id -u "$CURRENT_USER" 2>/dev/null || true)

# [... resto del script de instalación de swiftDialog y cálculo de tiempo de actividad ...]

# ==========================================
# 4. UPTIME CALCULATION
# ==========================================
current_unix_time="$(date '+%s')"
boot_time_unix="$(sysctl -n kern.boottime | awk -F 'sec = |, usec' '{ print $2; exit }')"
uptime_seconds="$(( current_unix_time - boot_time_unix ))"
uptime_days="$(( uptime_seconds / 86400 ))"

# TEST_UPTIME_DAYS="7" # Uncomment for testing

# ==========================================
# 5. ESCALATION LOGIC
# ==========================================

if [ "$uptime_days" -le 4 ]; then
  echo "Uptime: $uptime_days days. No action needed."
  exit 0

elif [ "$uptime_days" -ge 5 ] && [ "$uptime_days" -le 8 ]; then
  echo "Uptime: $uptime_days days. Showing Notification."
  run_as_user "$DIALOG_CLI" --notification \
    --title "$uptime_days days without a reboot!" \
    --message "Your Mac needs to restart to regain performance and apply security updates."
  afplay "/System/Library/Sounds/Sosumi.aiff"
  exit 0

elif [ "$uptime_days" -ge 9 ] && [ "$uptime_days" -le 12 ]; then
  echo "Uptime: $uptime_days days. Showing Dialog with Postpone."
  run_as_user "$DIALOG_CLI" \
    --title "Restart Required" \
    --message "*${uptime_days} days without a reboot!* \n\nPlease save your work and restart." \
    --button1text "Restart now" \
    --button2text "Postpone" \
    --timer 840 --width 650 --height 280 --position bottomright --ontop
  dialog_results=$?

elif [ "$uptime_days" -ge 13 ]; then
  echo "Uptime: $uptime_days days. Final warning."
  run_as_user "$DIALOG_CLI" \
    --title "Restart Required" \
    --message "*${uptime_days} days without a reboot!* \n\n*After pressing I Understand, you will have 10 minutes to save your work.*" \
    --button1text "I Understand" --width 650 --height 230 --blurscreen --ontop

  run_as_user "$DIALOG_CLI" \
    --title none --message "Computer will restart when the timer reaches zero." \
    --button1text "Restart now" --timer 600 --width 320 --height 110 --position bottomright --icon none --ontop
  dialog_results=$?
fi

# ==========================================
# 6. REBOOT EXECUTION
# ==========================================
if [ "$dialog_results" = "0" ] || [ "$dialog_results" = "4" ]; then
  echo "Rebooting now..."
  shutdown -r now
  sleep 2
  reboot
elif [ "$dialog_results" = "2" ]; then
  echo "User postponed the restart."
fi

exit 0
```

**Asignar el script a un dispositivo**

Ahora, navega a cualquiera de tus **Dispositivos**, selecciona la pestaña **Scripts**, haz clic en el botón **\+ Asignar Script** y selecciona el que acabas de crear.

:::info
También puedes asignar scripts a Políticas. Para ello, navega a la sección **Políticas**, selecciona la política deseada y haz clic en la pestaña **Scripts**. El proceso será el mismo que al asignarlo directamente a un dispositivo individual.
:::

**Elegir el método de ejecución**

| Método | Comportamiento | ¿Recomendado? |
|---|---|---|
| **Once** | Se ejecuta una vez por dispositivo. | ❌ No adecuado — este script necesita ejecutarse continuamente para monitorizar el tiempo de actividad. |
| **Loop** | Se ejecuta repetidamente en el intervalo configurado (15m, 1h, 6h, 1d, 7d). | ✅ Recomendado — selecciona el intervalo diario (`1d`) para comprobar el tiempo de actividad cada 24 horas y escalar las alertas progresivamente. |
| **On demand** | Solo se ejecuta cuando se activa manualmente. | ❌ No adecuado para la aplicación automática del tiempo de actividad. |

Este script no requiere ningún argumento. El tiempo de actividad del sistema se calcula automáticamente en tiempo de ejecución. Haz clic en **Añadir** para guardar la asignación.

---

## Qué verán los usuarios

**Nivel 2 — Notificación (días 5–8):** Aparece una notificación de macOS no intrusiva en la esquina superior derecha con una alerta sonora. El usuario puede descartarla y continuar trabajando.

**Nivel 3 — Diálogo con opción de posponer (días 9–12):** Aparece una ventana de diálogo en la esquina inferior derecha. El usuario puede hacer clic en **Reiniciar ahora** o **Posponer**. El diálogo se cierra automáticamente después de 14 minutos.

**Nivel 4 — Cuenta regresiva forzada (día 13+):** Primero aparece una advertencia a pantalla completa desenfocada. Después de que el usuario la confirme, comienza una cuenta regresiva de 10 minutos en la esquina inferior derecha. Cuando llega a cero — o el usuario hace clic en **Reiniciar ahora** — el Mac se reinicia.

---

## Probar el script

Para probar un nivel de escalada específico sin esperar el tiempo de actividad real, descomenta la línea `TEST_UPTIME_DAYS` en el script y establécela en el número de días deseado:

```bash
TEST_UPTIME_DAYS="7"  # Uncomment for testing
```

Recuerda comentarlo de nuevo antes de desplegarlo en producción.

---

## Disponible en GitHub

Este script es parte del [Repositorio público de scripts de Applivery](https://github.com/applivery/applivery-mdm-scripts/tree/main/Apple/Force%20Reboot%20Policy). Un dispositivo sin reiniciar es un parche sin efecto — esta política de escalada progresiva mantiene tu flota actualizada sin interrumpir a nadie.
