Agilizando la instalación de aplicaciones un 1000% tras instalar Windows limpio o tener tu ordenador de fábrica
24-04-2024
Vamos a comenzar explicando una historia, la historia de María.
María es una persona risueña, y amante del sistema MacOS, que es el que utiliza para programar en su día a día, pero ha tenido que cambiar de colaborador y le han dado un nuevo ordenador que usa Windows.
Esto es un “problema” en cierto sentido porque trabajar con Power Shell, en la terminal de Windows, es como empezar de
cero para María, ya que a ella le gusta instalar las cosas por gestores de paquetes como brew
, que era lo que usaba en
MacOS.
Entonces, se pone a buscar información sobre cómo hacer un script en Windows(Power Shell), que le permita preparar su
setup inicial de aplicaciones que utiliza para trabajar. Y se pone a ello y acaba creando el
siguiente script, que ha decidido dejarlo en un
gist
de GitHub para que en el ordenador Windows
restablecido de fábrica, sólo tenga que abrir una terminal en modo administrador y ejecutar la siguiente línea de
comando:
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://gist.githubusercontent.com/RubenZagon/1d4931f2547757c3d5ddce75f6b65378/raw/powershell-setup.ps1'))"
Y WUALÁ !! Se comienzan a ejecutar las aplicaciones auto-mágicamente y ésto, le ha reducido a María 2 días de instalación y configuración “de cosas” a 15 minutos.
Antes
Después
Video demostración de lo que pasa
Requisitos previos
Este script ha sido probado en Windows 11, pero debería poder correr con Windows 10 versión 2004 (build 19041 or higher).
Herramientas que se instalan
Instaladas por scoop
Nombre | Descripción |
---|---|
scoop-tray | Herramienta que permite acceder a la aplicaciones instaladas mediante scoop desde la bandeja del sistema en Windows |
curl | Herramienta de línea de comandos para transferir datos |
busybox | Pequeña utilidad que incluye muchos comandos de Unix en un solo ejecutable |
fzf | Un buscador de archivos y texto para la línea de comandos |
vim | Editor de texto avanzado |
cacert | Base de datos de certificados raíz |
colortool | Herramienta para aplicar colores a la consola Windows |
sudo | Permite a los usuarios ejecutar comandos con privilegios de administrador |
gpg | Sistema de cifrado de correo electrónico y archivos |
spacesniffer | Analiza el uso del espacio de disco en una partición |
sysinternals | Conjunto de utilidades para la gestión del sistema |
pshazz | Permite automatizar tareas con PowerShell y personalizar la experiencia de línea de comandos |
mpv | Reproductor de video de código abierto con una interface de línea de comandos que permite reproducir videos y audio de diversos formatos |
Instaladas por WinGet (Mínima instalación)
Nombre | Descripción |
---|---|
Microsoft.PowerToys | Conjunto de herramientas de productividad para Windows |
PuTTY | Cliente SSH, Telnet y Rlogin para Windows |
WinRAR | Compresor y descompresor de archivos |
Slack | Aplicación de mensajería para equipos |
Zoom | Aplicación de videoconferencia y reuniones en línea |
JetBrains.Toolbox | Herramienta de productividad para programadores |
Bitwarden | Gestor de contraseñas y autenticación segura |
Malwarebytes | Software antivirus y anti-malware |
Greenshot | Herramienta para capturar pantallas y editar imágenes |
chrisant996.Clink | Complemento para el símbolo del sistema de Windows que mejora la línea de comandos. |
Aplicaciones opcionales
Nombre | Descripción |
---|---|
Google Chrome | |
Sidekick | |
Mozilla Firefox | |
Opera | |
Obsidian | Aplicación de notas con enfoque en la estructura y organización |
HWMonitor | Monitoreo del hardware |
BleachBit | Limpiador de sistema para Windows |
SumatraPDF | Visor de PDF de código abierto |
Spark | Cliente de correo electrónico para Mac y iOS |
OBS Studio | Software de transmisión y grabación de video |
DBeaver | Herramienta de gestión de bases de datos |
DiskGenius | Herramienta de gestión de disco |
AutoHotkey | Lenguaje de scripts para automatización de tareas |
RevoUninstaller | Desinstalador de software con opciones avanzadas |
Starship | Un intérprete de comandos avanzado para el terminal |
Instaladas por Chocolately
Nombre | Descripción |
---|---|
syspin | Para fijar las aplicaciones en la barra de tareas del escritorio |
Aprendiendo a utilizar la Power Shell
Aquí voy a hacer un análisis un poco por encima de este script - powershell-setup.ps1
Explicación de bloques del script
Aquí pondré una serie de bloques del script que me parecen interesantes analizar, para aprender un par de cosas si se quieren montar sus propios script en power-shell
function Install-ScoopApp { param ( [string]$Package ) Write-Verbose -Message "Preparing to install $Package" if (!(scoop info $Package).Installed) { Write-Verbose -Message "Installing $Package" scoop install $Package } else { Write-Verbose -Message "Package $Package already installed! Skipping..." } }
Esta función verifica si un paquete está instalado, y si no lo está, lo instala. También imprime mensajes detallados
usando la opción Write-Verbose
, para dar más información sobre el proceso de instalación.
try { Write-Output "Comprobando que winget está bien instalado..." winget --list Write-Output "Okay !" } catch { Start-Sleep -Seconds 5 Write-Error "`nReiniciar el ordenador para que se cojan bien los cambios y comenzar hacer la instalación sin probla" Write-Output "`n`nPor favor, tras reiniciar vuelve a lanzar el script para continuar :)`n`n" Write-Output "Reiniciando en 10 segundos..." Start-Sleep -Seconds 10 Restart-Computer -Force }
Este bloque comprobaría si winget
está instalado y funcionando correctamente. Si winget está funcionando, el código
escribirá "Okay !" en la consola. Si hay un error al ejecutar el comando winget
, porque sigue sin coger las
configuraciones tras haberse instalado, el código mostrará un mensaje de error. Luego, esperará 5 segundos antes de
reiniciar el ordenador. Después de reiniciar, se espera 10 segundos antes de continuar con la ejecución del script, para
que dé tiempo al usuario de informarse de lo que va a pasar.
if ((Get-Command -Name "choco" -CommandType Application -ErrorAction SilentlyContinue)) { # {...bloques de código...} while ($confirmation -eq $null) { $confirmation = Read-Host -Prompt "Lo has entendido bien? ([Y]es/[N]o)?" if ($confirmation -eq "n" -or $confirmation -eq "N") { Write-Host "`nvamos a salir de este modo :)" exit } } }
Este bloque se utiliza para interactuar con el usuario, y que nos dé feedback de si quiere continuar o no con la
instalación. Se utiliza el bucle while
para evitar que se presione (ENTER) o entradas inválidas a 'n', aunque para
este caso he preferido que considere todo un sí
a menos que se confirme lo contrario.
Install WinGet Packages
$WinGet = @( "Microsoft.PowerToys", "PuTTY.PuTTY", "RARLab.WinRAR", "SlackTechnologies.Slack", "Zoom.Zoom", "JetBrains.Toolbox", # {...muchos más paquetes...} ) foreach ($item in $WinGet) { Install-WinGetApp -PackageID "$item" }
Este patrón de bloque, se repite varias veces en el código para hacer la instalación de las diferentes aplicaciones, tanto en WinGet, como en Chocolately o Scoop.
Seleccionar qué navegadores web quieres instalar
$applicationsOpt = [PsCustomObject]@{ Name = "Google Chrome"; Id = "Google.Chrome" }, [PsCustomObject]@{ Name = "Sidekick"; Id = "PushPlayLabs.Sidekick" }, [PsCustomObject]@{ Name = "Mozilla.Firefox"; Id = "Mozilla.Firefox" }, [PsCustomObject]@{ Name = "Opera"; Id = "Opera.Opera" } $selectedApplicationsOpt = $applicationsOpt | Select-Object -Property Name, Id | Out-GridView -Title "Selecciona con (Shift + clic) o (Ctrl + clic) una o más navegares web a instalar y pulsa (ENTER) para ejecutar:" -PassThru | Select-Object -ExpandProperty Id Write-Host "Navegadores web seleccionados para instalar: $selectedApplicationsOpt" $WinGet = @( $selectedApplicationsOpt ) foreach ($item in $WinGet) { Install-WinGetApp -PackageID "$item" }
Siguiendo el bloque anterior, así es como haríamos para crear un menú interactivo en el que el usuario puede elegir qué aplicaciones opcionales quiere instalar, en este caso, el navegador web que quiere.
Entonces, con estos bloques de código tenemos la siguiente información:
Funciones
Las funciones se construyen de la siguiente manera:
function Greetings { param ( [string]$name ) # Cuerpo de la función }
y se llaman así:
Greetings -name "Noelia"
Condicional If
Las condiciones if se construyen de esta manera:
if (condición) { # Acción a realizar si la condición es verdadera } elseif (condición) { # Acción a realizar si la primera condición es falsa y esta es verdadera } else { # Acción a realizar si ninguna de las condiciones anteriores es verdadera }
Ejemplos:
Ejemplo 1: uso de 'and'
$num = 10 if ($num -gt 5 -and $num -lt 20) { Write-Host "El número está entre 5 y 20." }
Ejemplo 2: uso de 'or'
$name = "Juan" if ($name -eq "Juan" -or $name -eq "Pedro") { Write-Host "El nombre es Juan o Pedro." }
Ejemplo 3: anidación de condiciones
$age = 30 if ($age -gt 18) { if ($age -gt 25) { Write-Host "La edad es mayor que 25 años." } else { Write-Host "La edad es mayor que 18 años pero menor o igual que 25 años." } } else { Write-Host "La edad es menor o igual que 18 años." }
Impresión de mensajes por pantalla
Comando en power shell | Descripción |
---|---|
Write-Host | Imprime un mensaje en la consola de PowerShell y es el comando más común para imprimir texto en PowerShell. |
Write-Output | Imprime un objeto o valor en la consola de PowerShell. |
Write-Verbose | Imprime un mensaje sólo si el modo verboso está activado. |
Write-Debug | Imprime un mensaje sólo si el modo de depuración está activado. |
Write-Warning | Imprime un mensaje de advertencia en la consola de PowerShell. |
Write-Error | Imprime un mensaje de error en la consola de PowerShell. |
Ejemplo:
Write-Output "Hola mundo" Write-Host "Bienvenido al script" Write-Error "Bienvenido al script" Write-Verbose -Message "Package $Package already installed! Skipping..."
Bucles while
y for
Un bucle while
se crea en PowerShell con la siguiente sintaxis:
while (condition) { # bloque de código a ejecutar mientras se cumpla la condición } # Ejemplo - Imprimir los números del 1 al 10 $counter = 1 while ($counter -le 10) { Write-Output $counter $counter++ }
Un bucle for
se crea en PowerShell con la siguiente sintaxis:
for ($variable in $colleccion) { # bloque de código a ejecutar en cada iteración } # Ejemplo - Imprimir los elementos de una lista de nombres $names = "John", "Jane", "Jim" for ($name in $names) { Write-Output $name }
Capturar errores con Try/Catch
El bloque try
es donde se ejecutan los comandos que pueden fallar, y el bloque catch
es donde se especifican las
acciones a realizar en caso de un error.
Ejemplo:
try { # Código que puede fallar Write-Output "Realizando una operación peligrosa..." Get-ChildItem C:\NoExiste } catch { # Acción a realizar en caso de un error Write-Output "Ha ocurrido un error: $($_.Exception.Message)" }
Comandos útiles
Start-Sleep
: detiene la ejecución del script por un número de segundos especificado.
Start-Sleep -Seconds 5
Restart-Computer
: reinicia el equipo.
Restart-Computer -Force
Get-Command
: devuelve un objeto que representa un comando específico, en este caso se busca una aplicación con el nombre especificado.
Get-Command -Name "nombre_aplicacion" -CommandType Application -ErrorAction SilentlyContinue
- '`n': representa un salto de línea, equivalente a '\n' en otros lenguajes de programación.
Write-Output "`nInstalación completada!"
Out-GridView
: El usuario puede seleccionar uno o más objetos personalizados a través de esta ventana y pulsar ( ENTER) para ejecutar el script.
Out-GridView -Title "Selecciona con (Shift + clic) o (Ctrl + clic) una o más navegares web a instalar y pulsa (ENTER)
para ejecutar:" -PassThru
Select-Object
: Se utiliza para seleccionar un subconjunto de propiedades de un objeto o una serie de objetos. Puede usarse para elegir las propiedades que deseas incluir en la salida, renombrar las propiedades existentes, calcular valores de nuevas propiedades basadas en propiedades existentes y reordenar las propiedades en la salida. Es una herramienta muy útil para manipular y personalizar la salida en PowerShell.
$applicationsOpt =
[PsCustomObject]@{ Name = "Google Chrome"; Id = "Google.Chrome" }
$selectedApplicationsOpt = $applicationsOpt | Select-Object -Property Name, Id
set-alias
: Creación de alias en la consola
set-alias -name gco -value 'git checkout' -Scope Global