Como fazer deploy e configuração remota com PowerShell Remoting
1. Fundamentos do PowerShell Remoting
O PowerShell Remoting é a tecnologia nativa da Microsoft para administração remota de sistemas Windows baseada no protocolo WinRM (Windows Remote Management), implementação Microsoft do WS-Management. Diferente de soluções como SSH nativo, o PowerShell Remoting oferece integração profunda com o ecossistema Windows, permitindo execução de comandos, scripts e acesso completo a objetos .NET em máquinas remotas.
Requisitos de infraestrutura:
- Windows PowerShell 5.1 ou PowerShell 7+ (cross-platform)
- WinRM 2.0+ habilitado nas máquinas alvo
- Firewall permitindo porta 5985 (HTTP) ou 5986 (HTTPS)
- Política de execução adequada (RemoteSigned ou superior)
- Privilégios administrativos nas máquinas remotas
Habilitando e testando conectividade:
# Habilitar PowerShell Remoting no servidor alvo (executar como Admin)
Enable-PSRemoting -Force
# Verificar se o serviço WinRM está ativo
Get-Service WinRM
# Testar conectividade remota
Test-WSMan -ComputerName "SERVIDOR01"
# Verificar configuração do listener
Get-WSManInstance -ResourceURI winrm/config/listener
2. Configuração de Sessões Remotas (PSSessions)
Sessões persistentes (PSSessions) são o coração do PowerShell Remoting para operações complexas. Elas mantêm estado, variáveis e módulos carregados entre comandos.
Criação e gerenciamento:
# Criar sessão persistente com credenciais
$creds = Get-Credential
$session = New-PSSession -ComputerName "SERVIDOR01" -Credential $creds -Authentication Default
# Criar sessão com configuração específica (endpoint personalizado)
$sessionCustom = New-PSSession -ComputerName "SERVIDOR02" -ConfigurationName "Microsoft.PowerShell32"
# Entrar em sessão interativa
Enter-PSSession -Session $session
# Sair da sessão interativa
Exit-PSSession
# Listar todas as sessões ativas
Get-PSSession
# Desconectar sessão sem encerrá-la (útil para tarefas longas)
Disconnect-PSSession -Session $session
# Reconectar a sessão desconectada
Connect-PSSession -Session $session
# Remover sessão após uso
Remove-PSSession -Session $session
Boas práticas: Sempre utilize Remove-PSSession para liberar recursos. Em scripts automatizados, considere usar blocos try/catch/finally para garantir o encerramento adequado.
3. Execução de Comandos e Scripts Remotos
Invoke-Command é o cmdlet principal para execução remota, suportando lote, paralelismo e coleta de resultados.
Execução básica e em lote:
# Execução única
Invoke-Command -ComputerName "SRV01" -ScriptBlock { Get-Process | Where-Object CPU -gt 10 }
# Execução em múltiplos computadores
$computadores = @("SRV01", "SRV02", "SRV03")
Invoke-Command -ComputerName $computadores -ScriptBlock {
Get-Service -Name "Spooler" | Select-Object Name, Status, MachineName
}
# Passagem de variáveis com ArgumentList
$nomeServico = "W3SVC"
Invoke-Command -ComputerName "SRV01" -ScriptBlock {
param($servico)
Restart-Service -Name $servico -Force
} -ArgumentList $nomeServico
# Uso do escopo Using: (PowerShell 7+)
$limiteCPU = 80
Invoke-Command -ComputerName "SRV01" -ScriptBlock {
Get-Process | Where-Object { $_.CPU -gt $using:limiteCPU }
}
Execução assíncrona com jobs:
# Iniciar job remoto
$job = Invoke-Command -ComputerName @("SRV01","SRV02") -ScriptBlock {
Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3"
} -AsJob
# Aguardar e receber resultados
$job | Wait-Job
$resultados = $job | Receive-Job
# Verificar status
$job | Get-Job
4. Transferência de Arquivos e Deploy de Pacotes
O PowerShell Remoting permite cópia de arquivos bidirecional através de sessões, essencial para deploys.
Copiando arquivos via sessão:
# Criar sessão para transferência
$session = New-PSSession -ComputerName "SRV01" -Credential $creds
# Copiar pasta local para servidor remoto
Copy-Item -Path "C:\Deploy\App_v2.0" -Destination "C:\Program Files\MyApp" -ToSession $session -Recurse -Force
# Copiar arquivo do servidor remoto para local
Copy-Item -Path "C:\Logs\app.log" -Destination "D:\BackupLogs\" -FromSession $session
# Deploy via caminho UNC (alternativa)
Copy-Item -Path "\\fileserver\deploy\installer.msi" -Destination "C:\Temp\installer.msi" -ToSession $session
Deploy silencioso de software:
# Instalar MSI remotamente
Invoke-Command -Session $session -ScriptBlock {
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i C:\Temp\app.msi /quiet /norestart" -Wait -NoNewWindow
}
# Executar instalador EXE com parâmetros
Invoke-Command -Session $session -ScriptBlock {
Start-Process -FilePath "C:\Temp\setup.exe" -ArgumentList "/S /v/qn" -Wait -PassThru
}
5. Configuração Remota de Serviços e Registro
Gerenciamento de serviços:
# Parar e desabilitar serviço
Invoke-Command -ComputerName "SRV01" -ScriptBlock {
Stop-Service -Name "wuauserv" -Force
Set-Service -Name "wuauserv" -StartupType Disabled
}
# Criar serviço personalizado
Invoke-Command -ComputerName "SRV01" -ScriptBlock {
New-Service -Name "MeuServico" -BinaryPathName "C:\App\meuapp.exe" -DisplayName "Meu Serviço" -StartupType Automatic
}
Alterações no registro e sistema:
# Configurar chave de registro
Invoke-Command -ComputerName "SRV01" -ScriptBlock {
New-Item -Path "HKLM:\SOFTWARE\MinhaEmpresa\AppConfig" -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\MinhaEmpresa\AppConfig" -Name "Timeout" -Value 300
}
# Configurar regra de firewall
Invoke-Command -ComputerName "SRV01" -ScriptBlock {
New-NetFirewallRule -DisplayName "App Port 8080" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow
}
# Criar tarefa agendada
Invoke-Command -ComputerName "SRV01" -ScriptBlock {
$action = New-ScheduledTaskAction -Execute "C:\Scripts\backup.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "02:00AM"
Register-ScheduledTask -TaskName "BackupDiario" -Action $action -Trigger $trigger -User "SYSTEM"
}
6. Automação de Tarefas em Múltiplas Máquinas
Deploy em lote com arquivo de inventário:
# Inventário em CSV
$inventario = Import-Csv -Path "C:\inventario.csv"
# CSV esperado: ComputerName,Role,Environment
foreach ($maquina in $inventario) {
Write-Host "Processando $($maquina.ComputerName)..." -ForegroundColor Cyan
try {
$session = New-PSSession -ComputerName $maquina.ComputerName -ErrorAction Stop
Invoke-Command -Session $session -ScriptBlock {
# Lógica de deploy específica para o role
param($role)
if ($role -eq "Web") {
# Configurar IIS
} elseif ($role -eq "DB") {
# Configurar SQL
}
} -ArgumentList $maquina.Role
Remove-PSSession $session
Write-Host "$($maquina.ComputerName): Sucesso" -ForegroundColor Green
}
catch {
Write-Host "$($maquina.ComputerName): Erro - $_" -ForegroundColor Red
}
}
Paralelismo com ThrottleLimit:
# Executar deploy em paralelo (máx. 5 simultâneos)
$resultados = Invoke-Command -ComputerName $computadores -ScriptBlock {
# Script de deploy
$status = "OK"
# ... lógica ...
return $status
} -ThrottleLimit 5
# Logging centralizado
$resultados | Export-Csv -Path "C:\Logs\deploy_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation
7. Segurança e Boas Práticas em Ambientes Remotos
Configuração segura do WinRM:
# Configurar listener HTTPS com certificado
$cert = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object Subject -like "*servidor*"
New-WSManInstance -ResourceURI winrm/config/Listener -SelectorSet @{
Address = "*"
Transport = "HTTPS"
} -ValueSet @{
CertificateThumbprint = $cert.Thumbprint
Port = 5986
}
# Configurar trusted hosts (para grupos de trabalho)
Set-Item -Path WSMan:\localhost\Client\TrustedHosts -Value "*.dominio.local" -Force
# Restringir endpoints remotos
Set-PSSessionConfiguration -Name "Microsoft.PowerShell" -ShowSecurityDescriptorUI
Gerenciamento de credenciais:
# Salvar credencial de forma segura
$creds = Get-Credential
$creds | Export-Clixml -Path "C:\secure\creds.xml"
# Carregar em script automatizado
$creds = Import-Clixml -Path "C:\secure\creds.xml"
# (Alternativa moderna) Usar Azure Key Vault
# $secret = Get-AzKeyVaultSecret -VaultName "MeuVault" -Name "AdminCred"
Resolução de problemas comuns:
# Verificar logs de erro do WinRM
Get-WinEvent -LogName "Microsoft-Windows-WinRM/Operational" | Where-Object LevelDisplayName -eq "Error"
# Testar conectividade detalhada
Test-WSMan -ComputerName "SRV01" -Authentication Negotiate
# Verificar permissões do usuário remoto
Invoke-Command -ComputerName "SRV01" -ScriptBlock { whoami }
# Aumentar timeout para operações longas
$options = New-PSSessionOption -IdleTimeout 3600000 -OpenTimeout 30000
$session = New-PSSession -ComputerName "SRV01" -SessionOption $options
Referências
-
Documentação Oficial do PowerShell Remoting (Microsoft) — Guia completo sobre execução remota de comandos, configuração de sessões e solução de problemas.
-
PowerShell Remoting Security Best Practices (Microsoft Learn) — Artigo técnico sobre configuração segura de listeners WinRM, autenticação e gerenciamento de endpoints.
-
Deploying Applications with PowerShell Remoting (PowerShell.org) — Tutorial prático sobre deploy de software usando sessões remotas e transferência de arquivos.
-
WinRM Configuration and Troubleshooting Guide (Microsoft Docs) — Guia detalhado de instalação, configuração e diagnóstico do WinRM para ambientes corporativos.
-
Advanced PowerShell Remoting: Jobs, Sessions, and Parallel Execution (4sysops) — Artigo técnico abordando execução assíncrona, jobs paralelos e otimização de desempenho em deploys remotos.
-
Securing PowerShell Remoting in Enterprise Environments (SANS Institute) — Whitepaper sobre práticas de segurança, auditoria e hardening para PowerShell Remoting em grandes infraestruturas.