Instalador Automatico de Software para Cloud & DevOps Engineers en Windows

Ultimamente estoy poniendo mucho foco en automatizar todo lo que se pueda. Siguiendo esta linea se me ocurrió la idea de simplificar el proceso de onboarding y configuración inicial de un nuevo desktop o laptop, automatizando la instalación de todas las herramientas esenciales que utilizamos día a día los Cloud Engineers y DevOps Engineers.

En este caso, desarrolle el script en PowerShell utilizando algunos comandos nativos y, ademas, utilicé el poderosisimo Chocolatey. Primero vamos a presentar un poco el script, luego hablamos de esta tool.

Link al repositorio de GitHub:

https://github.com/mdiloreto/windows-desktop-devopstools-install-script

En resumen:

En resumen, este script:

  • Instalará el listado de software especificado en la variable $chocoSoftwareList utilizando Chocolatey.
  • Instalará WSL e instalará la distribución especificada en la variable $distribution sin inicializarla.
  • Instalará PowerShell7.
  • Instalará los modulos de PowerShell especificados en la variable $psModules.
  • Instalará Gcloud SDK inicializando el instalador (ya que el package de Chocolatey está desactualizado).

Componentes del script:

Debajo les dejo la descripción en alto nivel de los componentes del script.

¿Que software instala el script?

En principio el script está seteado para instalar los siguientes programas/tools:

  • Development Tools: gitdocker-desktopvisualstudiocodeterraformkubernetes-cli, python
  • Cloud CLI Tools: azure-cliawscli, gcloud SDK, azurestorageexplorer
  • Database Tools: mysql.workbench
  • Remote Access Tools: anydeskmremoteng
  • API Testing Tools: postman
  • Otros: bitwardenfirefoxsnagit

Los packetes instalados podemos modificarlos utilizando la lista $chocoSoftwareList

Esto nos da un pequeño indicio sobre que Packet Manager estaremos utiilzando… Si estaremos utilizando Chocolatey.

¿Qué es Chocolatey?

Es un Packet Manager Open Source para Windows. Esta basado en PowerShell y las instalaciones desatendidas. Es similar a apt-get o yum en Linux. Nos permite administrar los paquetes de instalación de software de manera rápida y automatica en Windows.

Utiliza paquetes de software empaquetados en formatos .nupkg, que son compilaciones de software que incluyen todo lo necesario para instalar una aplicación. Actualmente tiene 10035 Packages mantenidos por la comunidad.

En este script podremos modificar / agregar / quitar el software que es instalado modificando la variable nombrada anteriormente $chocoSoftwareList:

# List of software to install with Chocolatey
$chocoSoftwareList = @(
    "git",
    "gh",    
    "docker-desktop",
    "microsoftazurestorageexplorer"
    "azure-cli",
    #"gcloudsdk", ### Package out of date 20-2-2024
    "awscli",
    "visualstudiocode",
    "terraform",
    "python",
    "kubernetes-cli",
    "mysql.workbench",
    "mremoteng",
    "postman",
    "anydesk",
    "snagit",
    "bitwarden",
    #"googlechrome", ### Package out of date 20-2-2024
    "firefox"
)

Instalación de WSL

El script tambien instalará e inicializará el Windows Subsystem for Linux en esta sección del codigo:

function install-wsl {
    param (
        [string[]]$distribution
    )
    try {
        # Enable WSL and Install distribution
        $wslInstalled = Get-WindowsOptionalFeature -FeatureName Microsoft-Windows-Subsystem-Linux -Online

        if ($wslInstalled.State -ne "Enabled") {
            Write-Host "Enabling WSL..."
            Enable-WindowsOptionalFeature -FeatureName Microsoft-Windows-Subsystem-Linux -Online -NoRestart
            Write-Host "Enabling $distribution distribution in WSL with no-launch..." -ForegroundColor DarkRed
            wsl --install -d $distribution --no-launch
        } else {
            Write-Host "WSL is already enabled."
        }
    } catch {
        Write-Error "Failed to enable or check WSL: $($_.Exception.Message)"
    }
}

¿Que es WSL?

WSL, o Windows Subsystem for Linux (Subsistema de Windows para Linux), es una característica de Windows 10 y Windows 11 que permite a los usuarios ejecutar un entorno de Linux directamente en Windows, sin la necesidad de una máquina virtual o un doble booteo.

WSL tiene dos versiones principales: WSL 1 y WSL 2. WSL 1 implementa un traductor de llamadas al sistema Linux en el kernel de Windows, permitiendo la ejecución de binarios de Linux. WSL 2, por otro lado, utiliza la virtualización ligera para ejecutar un verdadero kernel de Linux, proporcionando una mayor compatibilidad y rendimiento para aplicaciones Linux en Windows.

En este caso implementamos el wsl2.

Instalación de PowerShell 7 y modulos

El script instalará PowerShell 7. Adicionalmente instalará los modulos especificados en la variable $psModules.

# List of the Pwsh Modules to install
$psModules = @(
    "Az",
    "AzureAD", # For Azure Active Directory
    "MSOnline", # For Microsoft 365
    "ExchangeOnlineManagement"

)

El script

El script se encuentra en el siguiente repo:

https://github.com/mdiloreto/windows-desktop-devopstools-install-script

function RunAsAdmin {
    try {
        # Ensure the script is run as an Administrator
        If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
            Write-Warning "Please run this script as an Administrator!"
            Exit
        }
    } catch {
        Write-Error "Failed to validate administrative privileges: $($_.Exception.Message)"
    }
}

function install-choco {
    try {
        If (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
            Write-Host "Installing Chocolatey..."
            Set-ExecutionPolicy Bypass -Scope Process -Force
            Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
        }
    } catch {
        Write-Error "Chocolatey installation failed: $($_.Exception.Message)"
    }
}

function install-choco-soft {
    param (
        [string[]]$chocoSoftwareList,
        [bool]$update 
    )
    
    foreach ($software in $chocoSoftwareList) {
        try {
            Write-Host "Checking and installing $software with Chocolatey..."
            choco install $software -y

            if ($update) {
                choco upgrade $software -y
            }
        } catch {
            Write-Error "Failed to install/upgrade $software : $($_.Exception.Message)"
        }
    }

    if ($update) {
        try {
            Write-Host "Upgrading Chocolatey and all its packages..."
            choco upgrade chocolatey -y
            choco upgrade all -y
        } catch {
            Write-Error "Failed to upgrade Chocolatey and all packages: $($_.Exception.Message)"
        }
    }
}

function install-pwsh7 {
    try {
        Write-Host "Searching for the latest version of PowerShell using Winget..."
        winget search Microsoft.PowerShell
        Write-Host "Installing the latest stable version of PowerShell..."
        winget install --id Microsoft.Powershell --source winget --accept-package-agreements --accept-source-agreements
        winget install --id Microsoft.Powershell.Preview --source winget --accept-package-agreements --accept-source-agreements
    } catch {
        Write-Error "Failed to install PowerShell 7: $($_.Exception.Message)"
    }
}

function install-wsl {
    param (
        [string[]]$distribution
    )
    try {
        # Enable WSL and Install distribution
        $wslInstalled = Get-WindowsOptionalFeature -FeatureName Microsoft-Windows-Subsystem-Linux -Online

        if ($wslInstalled.State -ne "Enabled") {
            Write-Host "Enabling WSL..."
            Enable-WindowsOptionalFeature -FeatureName Microsoft-Windows-Subsystem-Linux -Online -NoRestart
            Write-Host "Enabling $distribution distribution in WSL with no-launch..." -ForegroundColor DarkRed
            wsl --install -d $distribution --no-launch
        } else {
            Write-Host "WSL is already enabled."
        }
    } catch {
        Write-Error "Failed to enable or check WSL: $($_.Exception.Message)"
    }
}

function install-gcloudsdk-manual {
    try {

        Get-Command gcloud 

    } catch {
        Write-Host "Downloading Google Cloud SDK..." -ForegroundColor Yellow
        (New-Object Net.WebClient).DownloadFile("https://dl.google.com/dl/cloudsdk/channels/rapid/GoogleCloudSDKInstaller.exe", "$env:Temp\GoogleCloudSDKInstaller.exe")
        Write-Host "Installing Google Cloud SDK..." -ForegroundColor Blue
        Write-Host "The installer will pop out in a second..." -ForegroundColor DarkRed
        & $env:Temp\GoogleCloudSDKInstaller.exe

    }
}

function install-pwsh-modules {
    param (
        [string[]]$psModules
    )

    Write-Host "Managing PowerShell Modules..." -ForegroundColor Yellow

    foreach ($module in $psModules) {
        $installedModule = Get-Module -ListAvailable -Name $module

        if ($installedModule) {
            try {
                Write-Host "Updating PowerShell module: $module"
                Update-Module -Name $module -Force -ErrorAction Stop
            } catch {
                Write-Host "Encountered an issue updating $module. Attempting to install..." -ForegroundColor Yellow
                try {
                    Install-Module -Name $module -AllowClobber -Repository PSGallery -Force -SkipPublisherCheck -ErrorAction Stop
                    Write-Host "$module installed successfully." -ForegroundColor Green
                } catch {
                    Write-Error "Failed to install $module. Error: $_"
                }
            }
        }

    }

    Write-Host "PowerShell Modules management successful." -ForegroundColor Green
}

###### SET VARIABLES ########################################

# List of the Pwsh Modules to install
$psModules = @(
    "Az",
    "AzureAD", # For Azure Active Directory
    "MSOnline", # For Microsoft 365
    "ExchangeOnlineManagement"

)

# List of software to install with Chocolatey
$chocoSoftwareList = @(
    "git",
    "gh",    
    "docker-desktop",
    "microsoftazurestorageexplorer"
    "azure-cli",
    #"gcloudsdk", ### Package out of date 20-2-2024
    "awscli",
    "visualstudiocode",
    "terraform",
    "python",
    "kubernetes-cli",
    "mysql.workbench",
    "mremoteng",
    "postman",
    "anydesk",
    "snagit",
    "bitwarden",
    #"googlechrome", ### Package out of date 20-2-2024
    "firefox"
)

$distribution = "Ubuntu"  

################### Main Script Execution Block ####################

try {
    # 1. Step: Force script to run with elevated Administrator rights
    RunAsAdmin

    # 2. Step: Chocolatey Installation
    install-choco

    # 3. Set: Chocolatey-Powered Software Installation and Possible Upgrading
    install-choco-soft -chocoSoftwareList $chocoSoftwareList -update $true
    # 3.b Installing Gcloud SDK "manually" cause the chocolatly module is out of date. 
    install-gcloudsdk-manual

    # 4. Installing or Checking for PowerShell 7 via Winget
    install-pwsh7

    # 5. Bootstrap: This will be determined if WSL installation is based on a name of the specific choice of OS
    install-wsl -distribution $distribution

    # 6. Operate: Manage Windows and PowerShell's Requisite Leading-Edge Commands (Modules)
    install-pwsh-modules -psModules $psModules

} catch {
    Write-Error "An unexpected event fatally halted the code with error: $($_.Exception.Message)"
    exit 1
} finally {
    Write-Host "******* All applicable latest packages, and patterns including Bootstrapping, set up has been completed. Inspect carefully for errors. *******" -ForegroundColor Cyan
}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.