Como usar o PowerShell para gerenciar pacotes com winget e Chocolatey

1. Introdução ao gerenciamento de pacotes no Windows com PowerShell

O ecossistema de gerenciamento de pacotes no Windows evoluiu significativamente nos últimos anos. Atualmente, duas ferramentas dominam o cenário: o winget (nativo da Microsoft, integrado ao Windows 10/11) e o Chocolatey (solução de terceiros consolidada há mais de uma década). O PowerShell atua como interface unificada para ambos, permitindo automação, scripts e integração com pipelines de CI/CD.

Benefícios do uso com PowerShell:
- Automação de instalações em lote
- Tratamento de erros com try/catch
- Integração com perfis de usuário ($PROFILE)
- Combinação de múltiplos provedores de pacotes

Pré-requisitos:
- PowerShell 5.1 ou superior (Windows PowerShell ou PowerShell 7+)
- Permissões de administrador para instalação de pacotes
- Conexão com internet para download dos repositórios

2. Instalação e configuração inicial dos gerenciadores

Instalação do winget

O winget é instalado automaticamente com o App Installer da Microsoft Store. Para verificar se está disponível:

winget --version

Se não estiver presente, instale o App Installer via:

winget install "Microsoft.AppInstaller" --source msstore --accept-package-agreements

Instalação do Chocolatey

O Chocolatey requer um script de instalação via PowerShell com permissão de execução:

Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

Verificação de versões

winget --version
choco --version

Para atualizar ambos:

winget upgrade --all
choco upgrade chocolatey

3. Comandos básicos do winget no PowerShell

Pesquisar pacotes

winget search firefox
winget search python --source winget

Instalar pacotes

winget install Google.Chrome --accept-package-agreements --accept-source-agreements
winget install "Microsoft.VisualStudioCode" --exact

Listar e remover pacotes

winget list
winget uninstall Google.Chrome

Para usar com PowerShellGet:

Find-Package -Name "firefox" -ProviderName winget
Install-Package -Name "firefox" -ProviderName winget

4. Comandos essenciais do Chocolatey via PowerShell

Pesquisar pacotes

choco find git
choco find 7zip --exact

Usando o provedor nativo do PowerShell:

Find-Package -Name "git" -ProviderName Chocolatey

Instalar pacotes com confirmação silenciosa

choco install git -y --no-progress
choco install vscode -y --params="/NoDesktopIcon /NoQuicklaunchIcon"

Atualizar e desinstalar

choco upgrade all -y
choco uninstall git -y

5. Automação de instalação em lote com scripts PowerShell

Script básico para instalação múltipla

$wingetPackages = @(
    "Microsoft.VisualStudioCode",
    "Google.Chrome",
    "7zip.7zip"
)

$chocoPackages = @(
    "git",
    "nodejs",
    "docker-desktop"
)

Write-Host "Instalando pacotes via winget..." -ForegroundColor Green
foreach ($pkg in $wingetPackages) {
    winget install $pkg --accept-package-agreements --silent
}

Write-Host "Instalando pacotes via Chocolatey..." -ForegroundColor Green
foreach ($pkg in $chocoPackages) {
    choco install $pkg -y
}

Uso de arquivo JSON para lista de pacotes

Crie um arquivo packages.json:

{
    "winget": ["Microsoft.PowerShell", "Microsoft.WindowsTerminal"],
    "chocolatey": ["googlechrome", "notepadplusplus"]
}

Script para ler o JSON:

$config = Get-Content "packages.json" | ConvertFrom-Json

foreach ($pkg in $config.winget) {
    winget install $pkg --silent --accept-package-agreements
}

foreach ($pkg in $config.chocolatey) {
    choco install $pkg -y
}

6. Gerenciamento avançado e integração entre ferramentas

Script com detecção automática de disponibilidade

function Install-Package {
    param([string]$PackageName)

    try {
        winget install $PackageName --silent --accept-package-agreements
    }
    catch {
        Write-Warning "winget falhou para $PackageName. Tentando Chocolatey..."
        choco install $PackageName -y
    }
}

Install-Package "firefox"

Exportação e importação de listas

# Exportar pacotes winget
winget export -o winget-packages.json

# Exportar pacotes Chocolatey
choco list -r > choco-packages.txt

# Importar pacotes winget
winget import -i winget-packages.json

# Importar Chocolatey
Get-Content choco-packages.txt | ForEach-Object { choco install $_ -y }

Configuração no perfil PowerShell

Adicione ao $PROFILE:

function Update-All {
    Write-Host "Atualizando winget..." -ForegroundColor Green
    winget upgrade --all --silent

    Write-Host "Atualizando Chocolatey..." -ForegroundColor Green
    choco upgrade all -y
}

function Install-DevTools {
    winget install Microsoft.VisualStudioCode --silent
    choco install git nodejs.install -y
}

7. Solução de problemas e boas práticas

Tratamento de erros com try/catch

try {
    winget install "Google.Chrome" --silent
    if ($LASTEXITCODE -ne 0) {
        throw "winget retornou código $LASTEXITCODE"
    }
}
catch {
    Write-Error "Falha na instalação: $_"
    choco install googlechrome -y
}

Logging de instalações

$logFile = "install-log_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"

function Log-Install {
    param([string]$Message)
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    "$timestamp - $Message" | Out-File -FilePath $logFile -Append
}

# Exemplo de uso
Log-Install "Iniciando instalação do Visual Studio Code"
winget install Microsoft.VisualStudioCode --silent
Log-Install "Instalação concluída"

Boas práticas de segurança

  • Sempre verificar a fonte dos scripts Chocolatey antes de executar
  • Usar --accept-package-agreements apenas em ambientes controlados
  • Preferir pacotes oficiais e verificados (winget: verified publisher, Chocolatey: trusted)
  • Executar scripts em modo restrito (Set-ExecutionPolicy RemoteSigned)

8. Exemplo prático: Script completo para setup de desenvolvimento

# setup-dev.ps1 - Script completo para ambiente de desenvolvimento
param(
    [switch]$Force
)

$ErrorActionPreference = "Stop"
$logFile = "setup-dev.log"

function Write-Log {
    param([string]$Message)
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    "$timestamp - $Message" | Out-File -FilePath $logFile -Append
    Write-Host $Message
}

# Verificar permissões
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Error "Execute como Administrador"
    exit 1
}

Write-Log "Iniciando setup do ambiente de desenvolvimento"

# Instalar via winget (apps da loja/universais)
$wingetApps = @(
    "Microsoft.VisualStudioCode",
    "Microsoft.WindowsTerminal",
    "Microsoft.PowerShell",
    "Git.Git",
    "9NBLGGH4NNS1"  # Windows Subsystem for Linux
)

foreach ($app in $wingetApps) {
    try {
        Write-Log "Instalando $app via winget..."
        winget install $app --silent --accept-package-agreements
    }
    catch {
        Write-Log "Erro ao instalar $app via winget: $_"
    }
}

# Instalar via Chocolatey (ferramentas CLI)
$chocoApps = @(
    "nodejs.install",
    "python",
    "dotnet-sdk",
    "docker-desktop",
    "kubernetes-cli",
    "terraform",
    "azure-cli"
)

foreach ($app in $chocoApps) {
    try {
        Write-Log "Instalando $app via Chocolatey..."
        choco install $app -y --no-progress
    }
    catch {
        Write-Log "Erro ao instalar $app via Chocolatey: $_"
    }
}

# Relatório final
Write-Log "Setup concluído. Pacotes instalados:"
winget list | Out-File -FilePath $logFile -Append
choco list -r | Out-File -FilePath $logFile -Append

Write-Host "Relatório salvo em: $logFile" -ForegroundColor Green

Para executar:

.\setup-dev.ps1 -Force

Referências