Winget: qué es, comandos y cómo usarlo con PowerShell

Winget, el administrador de paquetes de Windows: cinco cajas de cartón iguales, cerradas con cinta, ordenadas sobre una repisa de madera frente a una pared de ladrillo blanco

Winget es el administrador de paquetes de Windows: una orden en la consola que busca, instala, actualiza y desinstala programas sin abrir un navegador ni pulsar «Siguiente». Esta guía explica qué es, cómo instalar winget si no aparece, qué comandos se usan a diario, cómo sacarle partido desde PowerShell con el módulo oficial y qué hacer cuando winget no se reconoce. Además, lo que no sale de la documentación lo medimos el 30 de octubre de 2026 en un Windows 11 Pro 26H2, sin permisos de administrador, con Windows PowerShell 5.1 y con PowerShell 7.6.9.

La guía tiene dos niveles. Si solo quiere instalar y actualizar programas, lea los apartados de instalación y comandos. En cambio, si administra equipos o quiere automatizar, siga hasta el módulo de PowerShell, los fijados, los escenarios y los errores. Para un primer contacto con la consola, antes conviene leer nuestra guía de PowerShell.

Qué es winget

Winget es el cliente de línea de comandos del Administrador de paquetes de Windows (Windows Package Manager). Según la documentación de Microsoft, llega con el Instalador de aplicaciones (App Installer), un componente del sistema que se actualiza desde Microsoft Store. Por eso no suele hacer falta instalarlo: ya viene con Windows 11 y con las versiones modernas de Windows 10.

Por otra parte, winget no guarda los programas. Consulta un catálogo con la descripción de cada paquete, descarga el instalador del fabricante, comprueba su huella y lo ejecuta. De hecho, durante la prueba lo vimos en cada instalación: «Successfully verified installer hash». También avisa de algo que conviene recordar: «This application is licensed to you by its owner. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.»

Esto es lo que encontramos en el equipo de prueba:

DatoValor medido
Versión de wingetv1.29.380, del 21 de septiembre de 2026
Versiones estables en los últimos 12 meses8, según las publicaciones del proyecto en GitHub
Orígenesmsstore, winget y winget-font (este último, solo si se pide)
Programas instalados que ve146 identificadores distintos
Idioma de los mensajesInglés, con Windows en español (es-MX)

Winget y PowerShell: dos formas de usarlo

Hay dos maneras de manejarlo desde PowerShell, y la diferencia importa en cuanto se escribe un script:

winget.exeMódulo Microsoft.WinGet.Client
Qué esPrograma de consolaMódulo oficial de PowerShell
Viene con WindowsSíNo, se instala aparte
Qué devuelveTextoObjetos con propiedades
Cómo se sabe si funcionó$LASTEXITCODEPropiedad Status del resultado
Dónde sirve mejorTrabajo a manoScripts e informes

Para qué sirve winget: usos y beneficios

Instalar un programa a mano en un equipo es fácil. Sin embargo, hacerlo en veinte, mantenerlos al día y saber qué tiene cada uno ya no lo es. Ahí es donde winget ahorra tiempo:

  • Preparar equipos nuevos: la misma lista de programas, instalada sin asistentes.
  • Actualizar: ver de una vez qué programas tienen versión nueva y actualizarlos.
  • Inventario: qué hay instalado, en qué versión y cuál se quedó atrás.
  • Controlar versiones: fijar un programa para que una actualización general no lo toque.
  • Trabajar sin conexión: descargar el instalador en un equipo y llevarlo a otro.

Frente a la instalación manual, además, tiene beneficios claros:

  1. Sale del catálogo: se evita buscar el instalador en páginas que imitan a la del fabricante.
  2. Comprueba la huella: si el archivo no coincide con el catálogo, winget se detiene.
  3. Se repite igual: el mismo script da el mismo resultado en todos los equipos.
  4. Queda escrito: el script documenta qué se instaló.

Instalar winget y comprobar que funciona

En primer lugar, abra una consola y escriba lo siguiente. Si responde con un número de versión, no tiene que instalar nada:

winget --version
winget --info

Por su parte, winget --info muestra dónde guarda sus registros y su configuración. Microsoft pide estos requisitos: Windows 10 1809 (compilación 17763) o posterior, Windows 11 o Windows Server 2025. Según el proyecto en GitHub, en Windows Server 2019 y 2022 solo funciona de forma experimental y sin soporte. Y un detalle que explica muchas consultas: winget no está disponible hasta que el usuario inicia sesión por primera vez, porque es entonces cuando Microsoft Store registra el componente.

Instalar o reparar winget con PowerShell

Si falta o está dañado, Microsoft propone reparar con su módulo, en una consola elevada:

Install-PackageProvider -Name NuGet -Force | Out-Null
Install-Module -Name Microsoft.WinGet.Client -Force -Repository PSGallery | Out-Null
Repair-WinGetPackageManager -Force -Latest

Además, para dejarlo disponible a todos los usuarios del equipo, añada -AllUsers a Repair-WinGetPackageManager. Si quiere ver antes si hace falta, Assert-WinGetPackageManager no devuelve nada cuando todo está bien, como ocurrió en la prueba.

Winget no se reconoce como un comando

El mensaje «winget no se reconoce como nombre de un cmdlet» o «como un comando interno o externo» tiene pocas causas, y conviene revisarlas en este orden:

CausaCómo se compruebaQué hacer
El usuario acaba de iniciar sesión por primera vezEquipo o perfil recién creadoEsperar a que Microsoft Store registre el componente
Falta el Instalador de aplicacionesGet-AppxPackage Microsoft.DesktopAppInstaller no devuelve nadaRepararlo con el módulo, como arriba
La carpeta de alias no está en el PATHGet-Command winget no encuentra nadaComprobar que %LOCALAPPDATA%\Microsoft\WindowsApps esté en el PATH de usuario
Se ejecuta como SYSTEMTarea programada o herramienta de despliegueUsar el módulo, como explicamos más abajo
Un administrador lo desactivóHKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller tiene valoresRevisar la directiva
Windows Server anterior a 2025Get-ComputerInfo -Property OsNameNo tiene soporte

En el equipo de prueba, winget.exe era un alias de 0 bytes en %LOCALAPPDATA%\Microsoft\WindowsApps, y esa carpeta estaba en el PATH de usuario, no en el del sistema. Por eso una cuenta distinta o una tarea de otro usuario pueden no encontrarlo aunque usted sí lo vea.

Comandos de winget más comunes

Estos son los comandos de winget que se usan a diario. La lista completa sale con winget --help, y la de cada uno, con winget install --help:

ComandoPara qué sirve
winget searchBusca en el catálogo
winget showMuestra la ficha de un paquete y sus versiones
winget installInstala un paquete
winget listLista lo instalado
winget upgradeLista las actualizaciones, o actualiza
winget uninstallDesinstala
winget pinFija un paquete para que no se actualice
winget export y winget importGuardan e instalan una lista de paquetes
winget downloadDescarga el instalador sin instalarlo
winget sourceAdministra los orígenes
winget settingsAbre la configuración
winget errorExplica un código de error

Buscar un programa

winget search powershell --source winget
winget show --id Microsoft.PowerShell --exact --source winget
winget show --id jqlang.jq --exact --source winget --versions

Sin embargo, winget search mira también las etiquetas, así que devuelve mucho: con «powershell» salieron 65 paquetes, y casi todos solo llevan esa palabra como etiqueta. Por eso conviene copiar el identificador de la columna Id y usarlo siempre.

Instalar un programa

La forma segura de instalar usa el identificador exacto y el origen:

winget install --id Microsoft.PowerShell --exact --source winget

Así no hay dudas sobre qué paquete se instala. En cambio, para un script, añada las opciones que evitan preguntas:

winget install --id jqlang.jq --exact --source winget --silent --accept-package-agreements --accept-source-agreements --disable-interactivity

Estas son las opciones que más se usan:

OpciónPara qué sirve
--id y --exactBusca ese identificador, tal cual
--source wingetEvita buscar también en Microsoft Store
--silentInstala sin ventanas, si el instalador lo permite
--scope user o --scope machineSolo para este usuario, o para todo el equipo
--versionInstala una versión concreta
--accept-package-agreementsAcepta la licencia del paquete
--accept-source-agreementsAcepta las condiciones del origen
--disable-interactivityNunca se queda esperando una respuesta
--no-upgradeSi ya está instalado, no intenta actualizar

Probamos cada caso con jq, un programa pequeño que luego quitamos. Dos resultados sorprenden:

  • Instalar lo que ya está actualiza. winget responde Found an existing package already installed. Trying to upgrade the installed package... y sigue. Con --no-upgrade se detiene con «A package version is already installed. Installation cancelled.»
  • --version no baja de versión. Con jq 1.8.2 instalado, pedir la 1.7.1 terminó en «No available upgrade found.» y la versión siguió igual. Para bajar, primero hay que desinstalar.

Por qué un programa recién instalado no aparece

Este comportamiento cambia según la consola, y lo medimos con jq:

Dónde se instaló¿Lo ve la misma consola?
winget install en PowerShell 7.6.9Sí
winget install en Windows PowerShell 5.1No
Install-WinGetPackage en cualquiera de las dosNo

Aunque winget avisa «Path environment variable modified; restart your shell to use the new value», PowerShell 7 ya lo veía. En los otros casos, abra una consola nueva o recargue el PATH en la actual:

$env:Path = [Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' + [Environment]::GetEnvironmentVariable('Path', 'User')

Además, jq es un paquete portátil, y winget lo copió a %LOCALAPPDATA%\Microsoft\WinGet\Packages y añadió esa carpeta al PATH de usuario, en lugar de crear un enlace en la carpeta Links. Por eso, cada programa portátil que se instala así alarga el PATH.

Actualizar programas con winget

winget upgrade
winget upgrade --id jqlang.jq --exact --source winget --silent --accept-package-agreements --disable-interactivity
winget upgrade --all --silent --accept-package-agreements --accept-source-agreements --disable-interactivity

En primer lugar, la primera orden solo lista, y no cambia nada. En el equipo de prueba dijo «22 upgrades available.», más un aviso: 1 package(s) have version numbers that cannot be determined. Use --include-unknown to see all results. Con --include-unknown subió a 23.

La tercera orden, winget upgrade --all, es cómoda y arriesgada, porque salta a la última versión sin distinguir. Entre esas 22 pendientes había cuatro cambios de versión mayor: Node.js LTS de la 24.19 a la 26.13, OpenSSL de la 3.6 a la 4.1, PDFgear de la 2.1 a la 3.0 y Adobe Creative Cloud de la 5.2 a la 6.11. Por lo tanto, un cambio así puede romper lo que depende de ese programa. Por eso no la ejecutamos, y por eso existen los fijados, que veremos a continuación.

Desinstalar y descargar

winget uninstall --id jqlang.jq --exact --silent --disable-interactivity
winget download --id jqlang.jq --exact --source winget -d C:\Temp\Instaladores --accept-package-agreements --disable-interactivity

winget download dejó dos archivos: el instalador y un archivo .yaml con la descripción del paquete. Es la forma de llevar un programa a un equipo sin salida a internet.

Fijar versiones con winget pin

Fijar impide que una actualización general toque un programa. Hay tres tipos de fijado, y el de fábrica protege menos de lo que parece:

TipoOrdenQué haceLo que medimos con jq
Normalwinget pin add --id jqlang.jq --exactLo saca de winget upgrade --allwinget upgrade --id lo actualizó igual, con código 0
Bloqueowinget pin add --id jqlang.jq --exact --blockingImpide cualquier actualización«A newer version was found, but the package has a pin that prevents from upgrading it.»; con --force, se actualizó
Por versiónwinget pin add --id jqlang.jq --exact --version 1.8.*Solo admite esa ramaNo lo probamos

Es decir, si quiere que un programa no se mueva, use --blocking. Con un fijado normal, además, el paquete desaparece de winget list --upgrade-available, que avisa con «1 package(s) have pins that prevent upgrade.»

winget pin list
winget pin remove --id jqlang.jq --exact

Winget con PowerShell: el módulo Microsoft.WinGet.Client

Se puede escribir winget dentro de un script de PowerShell, pero lo que devuelve es texto pensado para leerse en pantalla. El módulo oficial de la Galería, Microsoft.WinGet.Client, devuelve objetos, y eso lo cambia todo a la hora de filtrar o exportar. Se instala como cualquier otro módulo:

Install-Module -Name Microsoft.WinGet.Client -Scope CurrentUser -Repository PSGallery
Import-Module -Name Microsoft.WinGet.Client
Get-WinGetVersion

Por otro lado, si la instalación falla, la guía de módulos de PowerShell repasa los errores habituales. Medimos la versión 1.29.380, del 21 de septiembre de 2026, con 41 archivos y 53,4 MB. Trae 20 cmdlets y su firma es válida, a nombre de Microsoft Corporation. Cargó en 1,3 s en PowerShell 7 y en 0,1 s en la 5.1.

Ojo con una contradicción: el README del módulo pide «la última versión de PowerShell (no Windows PowerShell)», pero la Galería declara como mínimo la 5.1, y en nuestra prueba funcionó igual en las dos versiones.

CmdletEquivale aPara qué sirve
Find-WinGetPackagewinget searchBusca en el catálogo
Get-WinGetPackagewinget listLista lo instalado
Install-WinGetPackagewinget installInstala
Update-WinGetPackagewinget upgradeActualiza
Uninstall-WinGetPackagewinget uninstallDesinstala
Export-WinGetPackagewinget downloadDescarga el instalador
Get-WinGetSourcewinget source listLista los orígenes
Get-WinGetUserSettingwinget settingsLee la configuración del usuario
Assert-WinGetPackageManagerSin equivalenteComprueba que winget funciona
Repair-WinGetPackageManagerSin equivalenteInstala o repara winget

Buscar, listar y filtrar con objetos

Find-WinGetPackage -Id 'Microsoft.PowerShell' -MatchOption Equals -Source winget
Get-WinGetPackage | Where-Object IsUpdateAvailable | Select-Object Name, Id, InstalledVersion
Get-WinGetPackage | Where-Object Source -eq 'winget' | Measure-Object

Cada paquete instalado trae las propiedades Name, Id, InstalledVersion, IsUpdateAvailable, AvailableVersions y Source. Sin embargo, hay dos detalles que conviene conocer:

  • -Source winget no filtra lo instalado. Get-WinGetPackage -Source winget devolvió los 146 paquetes, igual que sin el parámetro. Para quedarse con los de un origen, use Where-Object, como arriba.
  • Si no encuentra nada, no avisa. Find-WinGetPackage y Get-WinGetPackage con un identificador que no existe devolvieron cero objetos y ningún error. Un script tiene que comprobarlo.

-WhatIf no simula: instala de verdad

Este es el hallazgo más importante de la guía. Los tres cmdlets que cambian algo aceptan -WhatIf, que en PowerShell significa «dime qué harías sin hacerlo». Pero, con la versión 1.29.380, no lo respetan. Lo descubrimos por accidente, y lo repetimos con jq en las dos versiones de PowerShell:

OrdenAntesDespuésStatus
Install-WinGetPackage -WhatIfNo instalado1.8.2 instaladoOk
Update-WinGetPackage -WhatIf1.8.11.8.2Ok
Uninstall-WinGetPackage -WhatIf1.8.2DesinstaladoOk

Tampoco sirve $WhatIfPreference = $true: jq se instaló igual. No hay aviso ni error, y Status dice Ok. Así que nunca use -WhatIf para probar estos cmdlets, y menos en un equipo en producción. Para ver qué pasaría, use las órdenes de lectura: Find-WinGetPackage, Get-WinGetPackage o winget upgrade. Solo lo probamos con un paquete portátil, así que no sabemos si ocurre igual con otros tipos de instalador; aun así, conviene asumir que sí.

Comprobar el resultado en un script

Con el módulo, el resultado está en Status, una cadena que conviene revisar siempre. Esto respondió en cada caso:

CasoQué devolvió
Instalar un paquete nuevoStatus = Ok
Instalar uno que ya estáStatus = Ok, sin avisar de que ya estaba
Actualizar sin versión nuevaStatus = NoApplicableUpgrade
Instalar un identificador que no existeError «No packages matched the given input criteria.»; devuelve nulo y el script sigue

Por eso, en un script conviene añadir -ErrorAction Stop dentro de un try/catch. Otros valores posibles de Status, leídos del propio módulo, son BlockedByPolicy, CatalogError, DownloadError, InstallError, ManifestError, NoApplicableInstallers y PackageAgreementsNotAccepted. El resultado trae además RebootRequired, InstallerErrorCode y ExtendedErrorCode.

Por qué no conviene leer el texto de winget

Muchos scripts capturan la salida de winget list y la cortan por columnas. Sin embargo, medimos tres problemas:

  • Las tildes llegan rotas. winget escribe en UTF-8, y PowerShell lo lee con la codificación de la consola (ibm850 en el equipo de prueba, en las dos versiones). «Asistencia rápida» llegó como Asistencia r├ípida, y una comparación con el nombre correcto dio False.
  • Las filas no son paquetes. winget list dio 166 filas para 146 identificadores, porque repite algunos: Microsoft.WindowsAppRuntime.1.8 salió seis veces.
  • Las columnas dependen del contenido. En winget list, Version empezaba en la posición 147, y en winget upgrade, mucho antes. Además, los mensajes están en inglés, así que cualquier cambio de versión puede romper el corte.

Si aun así necesita el texto, cambie antes la codificación. Así, la comparación dio True en las dos versiones:

$anterior = [Console]::OutputEncoding
[Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
$texto = winget list --disable-interactivity
[Console]::OutputEncoding = $anterior

Exportar e importar la lista de programas

winget export guarda en un JSON los paquetes instalados, y winget import los instala en otro equipo:

winget export -o "$env:USERPROFILE\Desktop\programas.json" --include-versions
winget import -i "$env:USERPROFILE\Desktop\programas.json" --accept-package-agreements --accept-source-agreements --ignore-unavailable --disable-interactivity

Pero un archivo exportado no es un inventario. En el equipo de prueba guardó 55 de los 146 paquetes (53 de winget y 2 de Microsoft Store), y avisó 91 veces con «Installed package is not available from any source». Entre los que se quedaron fuera estaban Aplicaciones de Microsoft 365 y RustDesk. Lo que winget no encuentra en un catálogo no se exporta. Para saber qué hay instalado, use Get-WinGetPackage. Además, --include-versions guarda la versión de cada paquete; sin esa opción, winget import instala la más reciente.

Configurar winget

La configuración de cada usuario vive en un archivo settings.json. winget settings lo abre con su editor, y winget settings export muestra la configuración vigente. En el equipo de prueba el archivo no existía: mientras no se cree, se aplican los valores de fábrica. Esta configuración hace que winget prefiera instalar para el usuario actual:

{
    "$schema": "https://aka.ms/winget-settings.schema.json",
    "installBehavior": {
        "preferences": {
            "scope": "user"
        }
    }
}

La referencia de Microsoft distingue dos niveles: preferences ordena las opciones disponibles, y requirements las filtra, así que puede terminar en un error si ninguna cumple. Lo que se pase en la línea de comandos manda sobre ambas.

Orígenes y registros

winget source list
winget source update

El origen winget es el catálogo de la comunidad, y msstore, Microsoft Store. Por su parte, los registros están en %LOCALAPPDATA%\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\DiagOutputDir. Según Microsoft, se borran los que tienen más de 7 días o superan 128 MB en total; en el equipo de prueba había 155 archivos y 0,9 MB. Con --verbose-logs, el registro es más completo.

Directivas para empresas

Las directivas de Microsoft están en Configuración del equipo, ruta Windows Components > Desktop App Installer, y escriben en HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppInstaller:

DirectivaPara qué sirve
EnableAppInstallerActiva o desactiva el Instalador de aplicaciones
EnableWindowsPackageManagerCommandLineInterfacesSi se desactiva, nadie puede usar winget ni sus cmdlets
EnableMicrosoftStoreSourcePermite o impide el origen de Microsoft Store
EnableDefaultSourcePermite o impide el catálogo winget
EnableAllowedSourcesLimita qué orígenes se pueden agregar
EnableAdditionalSourcesAgrega orígenes propios de la empresa
EnableHashOverrideControla si se puede saltar la comprobación de la huella

Winget como SYSTEM y en tareas programadas

Aquí está la limitación que más sorprende a quien automatiza. Según la guía de problemas de Microsoft, la línea de comandos de winget no se admite como SYSTEM, porque es una aplicación empaquetada y su registro es por usuario. En cambio, el módulo Microsoft.WinGet.Client sí se puede usar como SYSTEM, con aplicaciones instaladas para todo el equipo.

Por eso, en la práctica, esto lleva a tres reglas:

  • Herramientas de despliegue y tareas como SYSTEM: use el módulo, instalado con -Scope AllUsers, y paquetes con -Scope System.
  • Tareas con la cuenta de un usuario: winget funciona, pero solo si esa cuenta ya inició sesión alguna vez.
  • Cualquier tarea: añada --accept-package-agreements, --accept-source-agreements y --disable-interactivity, porque nadie va a responder a las preguntas.

La forma de crearlas está en nuestra guía de tareas programadas con PowerShell. No lo probamos como SYSTEM, porque exige elevar.

Escenarios de winget con PowerShell

Los escenarios se pueden copiar tal cual. Salvo el tercero, los ejecutamos en PowerShell 5.1 y 7, con jq como paquete de prueba.

Escenario 1: preparar un equipo nuevo

Este bloque instala una lista de programas y deja un resultado por cada uno. Si un identificador está mal, sigue con el siguiente:

$programas = '7zip.7zip', 'Mozilla.Firefox', 'Notepad++.Notepad++'
$resultado = foreach ($id in $programas) {
    try {
        $r = Install-WinGetPackage -Id $id -MatchOption Equals -Source winget -Mode Silent -ErrorAction Stop
        [pscustomobject]@{ Id = $id; Estado = $r.Status; Reinicio = $r.RebootRequired; Codigo = $r.InstallerErrorCode }
    } catch {
        [pscustomobject]@{ Id = $id; Estado = $_.Exception.Message; Reinicio = $false; Codigo = $null }
    }
}
$resultado | Format-Table -AutoSize

Busque antes cada identificador con winget search, porque tiene que coincidir letra por letra.

Escenario 2: informe de programas desactualizados

Guarda un CSV que Excel abre con las tildes bien, en las dos versiones de PowerShell:

$lineas = Get-WinGetPackage | Where-Object IsUpdateAvailable |
    Select-Object Name, Id, InstalledVersion, @{ n = 'Disponible'; e = { @($_.AvailableVersions)[0] } }, Source |
    ConvertTo-Csv -NoTypeInformation -Delimiter ';'
[IO.File]::WriteAllLines("$env:USERPROFILE\Desktop\desactualizados.csv", [string[]]$lineas, [Text.UTF8Encoding]::new($true))

En el equipo de prueba listó 21 programas, y AvailableVersions traía primero la versión más reciente.

Escenario 3: actualizar todo, salvo lo delicado

Primero se bloquea lo que no debe moverse y, luego, se actualiza lo demás. No lo ejecutamos, porque habría actualizado todo el equipo de prueba:

winget pin add --id OpenJS.NodeJS.LTS --exact --blocking
winget pin add --id PostgreSQL.PostgreSQL.18 --exact --blocking
winget upgrade --all --silent --accept-package-agreements --accept-source-agreements --disable-interactivity
'Código de salida: 0x{0:X8}' -f $LASTEXITCODE

Escenario 4: actualizar solo una lista, comprobando cada paso

Cuando no quiere tocar nada más, recorra una lista corta y actualice solo lo que tenga versión nueva:

$lista = 'jqlang.jq', '7zip.7zip'
foreach ($id in $lista) {
    $p = Get-WinGetPackage -Id $id -MatchOption Equals
    if (-not $p) { "$id no está instalado"; continue }
    if (-not $p.IsUpdateAvailable) { "$id ya está en $($p.InstalledVersion)"; continue }
    $r = Update-WinGetPackage -Id $id -MatchOption Equals -Mode Silent
    "$id -> $($r.Status) · reinicio: $($r.RebootRequired)"
}

Escenario 5: reaccionar al código de salida de winget.exe

$LASTEXITCODE llega en decimal y negativo, así que conviene pasarlo a hexadecimal:

winget install --id jqlang.jq --exact --source winget --silent --accept-package-agreements --accept-source-agreements --disable-interactivity
switch ('0x{0:X8}' -f $LASTEXITCODE) {
    '0x00000000' { 'Instalado o ya estaba al día' }
    '0x8A15002B' { 'Ya estaba instalado y no hay versión nueva' }
    '0x8A150014' { 'No existe ese identificador' }
    default { winget error ('0x{0:X8}' -f $LASTEXITCODE) }
}

Escenario 6: llevar un instalador a un equipo sin internet

En el equipo con salida a internet:

New-Item -ItemType Directory -Path 'C:\Temp\Instaladores' -Force | Out-Null
winget download --id jqlang.jq --exact --source winget -d C:\Temp\Instaladores --accept-package-agreements --disable-interactivity
Get-ChildItem -Path 'C:\Temp\Instaladores'

Después, copie la carpeta y ejecute el instalador en el otro equipo. El archivo .yaml dice qué opciones acepta el instalador para instalarse sin ventanas.

Errores frecuentes de winget

winget error explica un código. Acepta el valor en hexadecimal, pero el decimal solo con --input: winget error -1978335212 falla, y winget error --input -1978335212 funciona.

CódigoMensajeQué significaQué hacer
0x8A150014No package found matching input criteria.No encontró ese paqueteRevisar el Id con winget search
0x8A15002BNo available upgrade found.Ya está en la última versiónNada; en un script, no es un fallo
0x8A150061A package version is already installed. Installation cancelled.Ya estaba, y se pidió --no-upgradeNada
0x8A150068A newer version was found, but the package has a pin that prevents from upgrading it.Tiene un fijado de bloqueowinget pin remove
0x8A150002Argument name was not recognized for the current commandOpción mal escritaRevisar con --help
0x8A150011The installer file's hash does not match the manifestLa huella no coincideNo saltarla; reintentar más tarde
0x8A150056The installer cannot be run from an administrator context.El instalador no admite elevaciónUsar una consola sin elevar
0x8A150109Restart your PC to finish installation.Falta reiniciarReiniciar

Los cinco primeros los provocamos en la prueba. En cambio, el texto de los otros tres sale de winget error. Además, Microsoft documenta un error 403 Forbidden: ocurre si el fabricante no permite la descarga desde un gestor de paquetes, y entonces hay que bajar el instalador con el navegador.

Recomendaciones para usar winget

Estas son, en resumen, las prácticas que recomendamos tras la prueba:

  1. Use siempre --id, --exact y --source: así instala lo que quiere y no lo que más se le parece.
  2. Nunca confíe en -WhatIf con el módulo: no simula.
  3. Revise la lista antes de winget upgrade --all y bloquee lo que dependa de una versión mayor.
  4. Use --blocking si un programa no debe moverse: el fijado normal deja actualizarlo con --id.
  5. Para scripts, prefiera el módulo: da objetos, sin problemas de tildes ni de columnas.
  6. No tome el archivo de winget export como inventario: deja fuera lo que no está en un catálogo.
  7. Recuerde que el catálogo es de terceros: la huella protege de un archivo alterado, pero no dice que el programa sea adecuado para su empresa. Limite los orígenes por directiva si hace falta.
  8. No use --ignore-security-hash: Microsoft tampoco lo recomienda.
  9. Vigile el PATH en equipos con muchos programas portátiles.

Lo que medimos y lo que no

Medimos en un Windows 11 Pro 26H2 en español, sin permisos de administrador, con Windows PowerShell 5.1.26100 y PowerShell 7.6.9:

  • winget 1.29.380 y su módulo 1.29.380, descargado a una carpeta temporal;
  • las órdenes de lectura, con sus tiempos y códigos de salida;
  • un ciclo real con jq, un paquete portátil de 1 MB: instalar, fijar, actualizar, exportar, importar, descargar y desinstalar;
  • el comportamiento de -WhatIf y de $WhatIfPreference;
  • la codificación y las filas repetidas de la salida de texto.

Además, comprobamos los comandos y los parámetros del artículo contra el módulo en las dos versiones, y ejecutamos los escenarios 1, 2, 4, 5 y 6 con jq. Al terminar, jq se desinstaló y el equipo quedó como estaba.

En cambio, no ejecutamos winget upgrade --all ni probamos paquetes MSI o EXE, la instalación para todo el equipo, la ejecución como SYSTEM, Windows Server, winget configure, el fijado por versión ni una consola estrecha, donde winget podría recortar las columnas. Lo que no medimos sale de la documentación de Microsoft.

Preguntas frecuentes

¿Winget es gratis?

Sí. Winget y su módulo son gratuitos y vienen de Microsoft. Eso sí, cada programa tiene su propia licencia, y --accept-package-agreements acepta esa licencia en su nombre.

¿Winget necesita permisos de administrador?

No para funcionar. Instalamos, actualizamos y quitamos jq sin elevar. Sin embargo, según Microsoft, algunas aplicaciones piden elevación al instalarse, y Windows muestra entonces su aviso; si no se acepta, la instalación falla. En una consola elevada no aparece ese aviso, así que conviene ser prudente con lo que se instala.

¿Winget actualiza Windows?

No. Actualiza programas, no el sistema operativo. Para eso, tenemos una guía de Windows Update con PowerShell.

¿Funciona winget en Windows Server?

Microsoft da soporte en Windows Server 2025. En Windows Server 2019 y 2022, el proyecto dice que puede funcionar de forma experimental, sin soporte.

¿Por qué winget sale en inglés?

En el equipo de prueba, con Windows en español, todos sus mensajes salieron en inglés. Por eso, al buscar un error conviene hacerlo con el mensaje en inglés o con su código.

¿Es lo mismo winget que Microsoft Store?

No. Microsoft Store es uno de sus orígenes. El otro, winget, es un catálogo con programas de muchos fabricantes.

Winget en la empresa

Instalar un programa con winget es fácil. Lo difícil, en cambio, es que todos los equipos tengan los mismos programas, que nadie instale de más y que una actualización no rompa lo que depende de ella. En KHARONTE hacemos ese trabajo dentro de la instalación y estandarización de aplicaciones de nuestro soporte técnico para empresas, atendido desde nuestra mesa de ayuda TI y como parte de los servicios administrados de TI que prestamos. Si quiere conocer el resto de nuestros servicios de TI para empresas, escríbanos.

Hablemos de la TI de su empresa

Cuéntenos qué necesita su operación y le enviamos una propuesta por escrito. Cada línea del portafolio se contrata por separado.

Compartir este artículo

Últimas entradas

Escríbanos ahora