Optimiza la gestión del sistema: script de implementación de BGInfo en PowerShell

Principales conclusiones

  • Despliegue automatizado de BGInfo: el script proporciona un método automatizado y fluido para desplegar BGInfo en varios sistemas Windows.
  • Eficacia para los profesionales de TI: ahorra tiempo y reduce el esfuerzo manual de los profesionales de TI y MSP que gestionan las pantallas de información del sistema.
  • Configuración personalizable: permite la personalización mediante un parámetro configurable para adaptarse a distintos entornos y requisitos.
  • Se requieren privilegios administrativos: el script debe ejecutarse con derechos de administrador para acceder a los directorios del sistema y modificar la configuración.
  • Tratamiento de errores y solidez: incluye un tratamiento exhaustivo de los errores, lo que garantiza la fiabilidad y una comunicación clara durante la ejecución.
  • Concienciación en materia de seguridad: es importante ser consciente de la información que muestra BGInfo para evitar exponer datos sensibles.
  • Escalabilidad y coherencia: garantiza la uniformidad en la visualización de la información del sistema en todas las máquinas de una organización.
  • Compatibilidad con sistemas Windows modernos: compatible principalmente con Windows 10 y Windows Server 2016 en adelante.
  • Complemento de herramientas de TI completas: funciona bien junto con plataformas de gestión de TI más amplias como NinjaOne para mejorar la visibilidad y el control.

En el panorama en constante evolución de las tecnologías de la información, la gestión y configuración eficientes de los sistemas informáticos son cruciales. BGInfo, una herramienta de renombre en el entorno Windows, desempeña un papel vital en este sentido. Esta herramienta muestra información esencial del sistema en el fondo del escritorio, lo que resulta muy valioso para los profesionales de TI y los proveedores de servicios gestionados (MSP). Hoy veremos un script de PowerShell pensado para implementar y configurar BGInfo sin complicaciones en sistemas Windows.

Contexto

BGInfo, que forma parte de la suite Sysinternals, ha sido un elemento clave en el conjunto de herramientas de los profesionales de TI durante años. Muestra información del sistema como la dirección IP, el nombre del ordenador y la versión del sistema operativo en el escritorio, proporcionando una visión rápida de las configuraciones del sistema. En un mundo en el que el acceso rápido a la información y la supervisión del sistema son fundamentales, la automatización de la implementación de BGInfo mediante un script de PowerShell ahorra tiempo y aumenta la eficacia, especialmente para los profesionales de TI y los MSP que gestionan varios equipos.

El script:

#Requires -Version 2.0

<#
.SYNOPSIS
    Downloads, installs and sets up BGInfo to run for all users.
.DESCRIPTION
    Downloads, installs and sets up BGInfo to run for all users.
    Uses the default configuration if no .bgi file path or URL is specified.

    Note: Users that are already logged in will need to logout and login to have BGInfo update their desktop background.

.EXAMPLE
    (No Parameters)
    ## EXAMPLE OUTPUT WITHOUT PARAMS ##
    Create Directory: C:\WINDOWS\System32\SysInternals
    Downloading https://live.sysinternals.com/Bginfo.exe
    Created Shortcut: C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\BGInfo.lnk

.EXAMPLE
    -Config C:\BGInfo\config.bgi
    Specifies the BGInfo configuration file to use.

PARAMETER: -Config C:\BGInfo\config.bgi
    ## EXAMPLE OUTPUT WITHOUT PARAMS ##
    Create Directory: C:\WINDOWS\System32\SysInternals
    Downloading https://live.sysinternals.com/Bginfo.exe
    Created Shortcut: C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\BGInfo.lnk
.OUTPUTS
    None
.NOTES
    Minimum OS Architecture Supported: Windows 10, Windows Server 2016
    Release Notes: Renamed script and added Script Variable support
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
    Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
#>

[CmdletBinding()]
param (
    [Parameter()]
    [string]$Config
)

begin {
    if ($env:bginfoConfigFilePath -and $env:bginfoConfigFilePath -notlike "null") { $Config = $env:bginfoConfigFilePath }
    function Test-IsElevated {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $p = New-Object System.Security.Principal.WindowsPrincipal($id)
        $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
    }

    function New-Shortcut {
        [CmdletBinding()]
        param(
            [Parameter()]
            [String]$Arguments,
            [Parameter()]
            [String]$IconPath,
            [Parameter(ValueFromPipeline = $True)]
            [String]$Path,
            [Parameter()]
            [String]$Target,
            [Parameter()]
            [String]$WorkingDir
        )
        process {
            Write-Host "Creating Shortcut at $Path"
            $ShellObject = New-Object -ComObject ("WScript.Shell")
            $Shortcut = $ShellObject.CreateShortcut($Path)
            $Shortcut.TargetPath = $Target
            if ($WorkingDir) { $Shortcut.WorkingDirectory = $WorkingDir }
            if ($Arguments) { $ShortCut.Arguments = $Arguments }
            if ($IconPath) { $Shortcut.IconLocation = $IconPath }
            $Shortcut.Save()

            if (!(Test-Path $Path -ErrorAction SilentlyContinue)) {
                Write-Error "Unable to create Shortcut at $Path"
                exit 1
            }
        }
    }
    # Utility function for downloading files.
    function Invoke-Download {
        param(
            [Parameter()]
            [String]$URL,
            [Parameter()]
            [String]$Path,
            [Parameter()]
            [int]$Attempts = 3,
            [Parameter()]
            [Switch]$SkipSleep
        )
        Write-Host "URL given, Downloading the file..."

        $SupportedTLSversions = [enum]::GetValues('Net.SecurityProtocolType')
        if ( ($SupportedTLSversions -contains 'Tls13') -and ($SupportedTLSversions -contains 'Tls12') ) {
            [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol::Tls13 -bor [System.Net.SecurityProtocolType]::Tls12
        }
        elseif ( $SupportedTLSversions -contains 'Tls12' ) {
            [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
        }
        else {
            # Not everything requires TLS 1.2, but we'll try anyway.
            Write-Warning "TLS 1.2 and or TLS 1.3 are not supported on this system. This download may fail!"
            if ($PSVersionTable.PSVersion.Major -lt 3) {
                Write-Warning "PowerShell 2 / .NET 2.0 doesn't support TLS 1.2."
            }
        }

        $i = 1
        While ($i -le $Attempts) {
            # Some cloud services have rate-limiting
            if (-not ($SkipSleep)) {
                $SleepTime = Get-Random -Minimum 3 -Maximum 15
                Write-Host "Waiting for $SleepTime seconds."
                Start-Sleep -Seconds $SleepTime
            }
        
            if ($i -ne 1) { Write-Host "" }
            Write-Host "Download Attempt $i"

            try {
                # Invoke-WebRequest is preferred because it supports links that redirect, e.g., https://t.ly
                if ($PSVersionTable.PSVersion.Major -lt 4) {
                    # Downloads the file
                    $WebClient = New-Object System.Net.WebClient
                    $WebClient.DownloadFile($URL, $Path)
                }
                else {
                    # Standard options
                    $WebRequestArgs = @{
                        Uri                = $URL
                        OutFile            = $Path
                        MaximumRedirection = 10
                        UseBasicParsing    = $true
                    }

                    # Downloads the file
                    Invoke-WebRequest @WebRequestArgs
                }

                $File = Test-Path -Path $Path -ErrorAction SilentlyContinue
            }
            catch {
                Write-Warning "An error has occurred while downloading!"
                Write-Warning $_.Exception.Message

                if (Test-Path -Path $Path -ErrorAction SilentlyContinue) {
                    Remove-Item $Path -Force -Confirm:$false -ErrorAction SilentlyContinue
                }

                $File = $False
            }

            if ($File) {
                $i = $Attempts
            }
            else {
                Write-Warning "File failed to download."
                Write-Host ""
            }

            $i++
        }

        if (-not (Test-Path $Path)) {
            throw "Failed to download file!"
        }
        else {
            Write-Host "Download Successful!"
        }
    }

    function Install-SysInternalsTool {
        [CmdletBinding()]
        param()
        # Target directory is %WinDir%C:\Windows\System32\SysInternals
        $TargetDir = Join-Path -Path $env:WinDir -ChildPath "System32\SysInternals"

        # Tools to be downloaded
        $Tools = @(
            [PSCustomObject]@{
                Name     = "Bginfo"
                FileName = "Bginfo.exe"
                URL      = "https://live.sysinternals.com/Bginfo.exe"
            }
        )

        # Create Directory
        if (-not $(Test-Path $TargetDir -ErrorAction SilentlyContinue)) {
            Write-Host "Create Directory: $TargetDir"
            New-Item -ItemType Directory -Path $TargetDir -Force -ErrorAction SilentlyContinue
        }

        # Download tools to target directory
        try {
            foreach ($Tool in $Tools) {
                $FilePath = Join-Path $TargetDir $Tool.FileName
                Write-Host "Downloading $($Tool.Name) to $FilePath"
                Invoke-Download -URL $Tool.URL -Path $FilePath
            }
        }
        catch {
            throw $_
        }
    }
    function Register-BGInfoStartup {
        [CmdletBinding()]
        param(
            [Parameter()][string]$Config
        )
        $ExePath = Join-Path -Path $env:WinDir -ChildPath "System32\SysInternals\BGInfo.exe"
        if (-not $(Test-Path -Path $ExePath -ErrorAction SilentlyContinue)) {
            throw "BGInfo.exe is not found at $ExePath"
        }

        # Register Startup command for All User
        try {
            $StartupPath = Join-Path -Path $env:ProgramData -ChildPath "Microsoft\Windows\Start Menu\Programs\StartUp\StartupBGInfo.lnk"
            
            if ($(Test-Path -Path $StartupPath -ErrorAction SilentlyContinue)) {
                Remove-Item -Path $StartupPath -ErrorAction SilentlyContinue
            }
            if ($Config -and $(Test-Path -Path $Config -ErrorAction SilentlyContinue)) {
                New-Shortcut -Path $StartupPath -Arguments "/iq `"$Config`" /accepteula /timer:0 /silent" -Target $ExePath
            }
            else {
                New-Shortcut -Path $StartupPath -Arguments "/accepteula /timer:0 /silent" -Target $ExePath
            }

            Write-Host "Created Startup: $StartupPath"
        }
        catch {
            throw "Unable to create shortcut for BGInfo.exe"
        }
    }
}
process {
    if (-not (Test-IsElevated)) {
        Write-Error -Message "Access Denied. Please run with Administrator privileges."
        exit 1
    }

    try {
        Install-SysInternalsTool

        if ($Config) {
            if (-not $(Test-Path -Path $Config -ErrorAction SilentlyContinue)) {
                try {
                    if (-not (Test-Path -Path "$Env:PROGRAMDATA\SysInternals" -ErrorAction SilentlyContinue)) {
                        New-Item -ItemType Directory -Path "$Env:PROGRAMDATA\SysInternals" -Force
                    }
                    Invoke-Download -URL $Config -Path $(Join-Path -Path $env:PROGRAMDATA -ChildPath "SysInternals\bginfoConfig.bgi")
                    $Config = $(Join-Path -Path $env:PROGRAMDATA -ChildPath "SysInternals\bginfoConfig.bgi")
                }
                catch {
                    Write-Error "Failed to download from provided Url or that the Path to the specified file does not exist."
                    Write-Error $_
                    exit 1
                }
            }
            Register-BGInfoStartup -Config $Config
        }
        else {
            Register-BGInfoStartup
        }
    }
    catch {
        Write-Error $_
        exit 1
    }

    Write-Host "Successfully installed and set up bginfo. Bginfo will start the next time the end user logs in or restarts."
    exit 0
}
end {
    
    
    
}

 

Accede a más de 300 scripts en el Dojo de NinjaOne

Obtén acceso

Análisis detallado

El script funciona en varias etapas:

  • Configuración de parámetros: comienza permitiendo al usuario especificar un archivo de configuración a través del parámetro $Config. Si no se indica una ruta específica para el archivo de configuración, se utilizará por defecto una configuración estándar.
  • Comprobación de elevación: el script comprueba si se está ejecutando con privilegios de administrador, lo que es esencial para acceder a los directorios del sistema y modificar la configuración de inicio.
  • Descarga e instalación de BGInfo: el script crea un directorio en C:\WINDOWS\System32\SysInternals y descarga BGInfo desde el sitio oficial de Sysinternals. Gestiona los posibles problemas de descarga, como la incompatibilidad TLS y la lógica de reintento.
  • Configurar el acceso directo de inicio: el script crea un acceso directo en la carpeta de inicio común. Esto garantiza que BGInfo se ejecute para todos los usuarios al iniciar sesión. Puede utilizar un archivo de configuración especificado o la configuración por defecto.
  • Tratamiento de errores: el script incluye un sólido sistema de gestión de errores que garantiza que cualquier problema se comunique claramente al usuario.

Posibles casos de uso

Consideremos un escenario en el que un MSP necesita desplegar BGInfo en una flota de equipos Windows en un entorno corporativo. Este script automatiza el proceso, reduciendo la intervención manual y garantizando la uniformidad en la configuración de BGInfo en todos los sistemas.

Comparaciones

Tradicionalmente, el despliegue de BGInfo implicaba la instalación y configuración manual en cada máquina. Este script no solo ahorra tiempo, sino que también reduce la probabilidad de que se produzcan errores humanos. Es un enfoque más escalable y fiable que la implementación manual.

FAQ

  • ¿Se puede personalizar este script para distintas configuraciones?
    Sí, cambiando el parámetro $Config.
  • ¿Funciona este script en todas las versiones de Windows?
    Es compatible con Windows 10 y Windows Server 2016 en adelante.

Implicaciones

Aunque el script agiliza la implantación, es importante ser conscientes de las implicaciones de seguridad. Asegurarse de que la configuración de BGInfo no expone inadvertidamente información sensible en el fondo del escritorio es vital.

Recomendaciones

  • Prueba siempre el script en un entorno controlado antes de desplegarlo a gran escala.
  • Actualiza regularmente el script para adaptarlo a las nuevas actualizaciones de Windows y a las versiones de Sysinternals.
  • Ten cuidado con la información que muestra BGInfo, teniendo en cuenta el contexto de seguridad de tu entorno.

Reflexiones finales

En el contexto de la gestión y supervisión de sistemas, herramientas como NinjaOne pueden complementar guiones como éste proporcionando una plataforma integral para la gestión de TI. NinjaOne ofrece una serie de funciones que se complementan con la información proporcionada por BGInfo, mejorando la visibilidad y el control generales de la infraestructura de TI.

Próximos pasos

La creación de un equipo de TI próspero y eficaz requiere contar con una solución centralizada que se convierta en tu principal herramienta de prestación de servicios. NinjaOne permite a los equipos de TI supervisar, gestionar, proteger y dar soporte a todos sus dispositivos, estén donde estén, sin necesidad de complejas infraestructuras locales.

Obtén más información sobre NinjaOne Remote Script Deployment, echa un vistazo a un tour en vivo, o comienza tu prueba gratuita de la plataforma NinjaOne.

Categorías:

Quizá también te interese…