TL;DR — Resumo Rápido

Guia de PowerShell Remoting com WinRM cobrindo Enable-PSRemoting, hosts confiáveis, Invoke-Command, credenciais e remoting baseado em SSH

PowerShell Remoting é uma das funcionalidades mais poderosas do conjunto de ferramentas de administração do Windows. Ele permite executar comandos, rodar scripts e gerenciar configurações em máquinas remotas — uma de cada vez ou centenas simultaneamente. Em seu núcleo, o PowerShell Remoting se baseia no Windows Remote Management (WinRM), a implementação da Microsoft do protocolo WS-Management. Neste guia, você aprenderá como habilitar e configurar o WinRM, usar os principais cmdlets de remoting, gerenciar credenciais de forma segura, lidar com cenários entre domínios e aproveitar o remoting baseado em SSH para gerenciamento multiplataforma.

Pré-requisitos

Antes de começar a configurar o PowerShell Remoting, certifique-se de ter o seguinte:

  • Windows Server 2016 ou posterior (ou Windows 10/11 Pro/Enterprise para máquinas cliente)
  • PowerShell 5.1 ou posterior instalado (PowerShell 7+ recomendado para remoting baseado em SSH)
  • Privilégios administrativos tanto na máquina cliente quanto nas remotas
  • Conectividade de rede na porta 5985 (HTTP) ou 5986 (HTTPS) entre cliente e servidor
  • Domínio Active Directory (recomendado mas não obrigatório — configurações de grupo de trabalho são cobertas abaixo)
  • Familiaridade básica com cmdlets do PowerShell e configuração do firewall do Windows

Habilitação e Configuração do WinRM

O WinRM é instalado por padrão nos sistemas Windows modernos, mas o serviço tipicamente não está em execução e as regras de firewall não estão habilitadas nos sistemas operacionais cliente. Nas edições do Windows Server a partir de 2012, o WinRM é habilitado por padrão, mas você ainda deve verificar a configuração.

Habilitar PSRemoting

A forma mais rápida de habilitar tudo de uma vez é o cmdlet Enable-PSRemoting:

# Executar em uma sessão elevada do PowerShell na máquina remota
Enable-PSRemoting -Force

Este comando único realiza várias ações: inicia o serviço WinRM, configura-o para início automático, cria um listener HTTP na porta 5985, adiciona exceções ao Firewall do Windows e registra as configurações de sessão padrão do PowerShell.

Verificar que o WinRM Está Escutando

Após habilitar, confirme que o serviço está rodando e os listeners estão ativos:

# Verificar status do serviço
Get-Service WinRM

# Listar listeners ativos
Get-WSManInstance -ResourceURI winrm/config/listener -Enumerate

# Teste rápido de conectividade a partir do cliente
Test-WSMan -ComputerName SERVIDOR01

Configurar TrustedHosts

Em um ambiente de domínio, o Kerberos gerencia a autenticação de forma transparente. Em cenários de grupo de trabalho ou entre domínios, você precisa configurar TrustedHosts na máquina cliente:

# Adicionar um único host
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "SERVIDOR01"

# Adicionar múltiplos hosts (separados por vírgula)
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "SERVIDOR01,SERVIDOR02,192.168.1.50"

# Confiar em todos os hosts (NÃO recomendado para produção)
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*"

# Ver os TrustedHosts atuais
Get-Item WSMan:\localhost\Client\TrustedHosts

Configurar Transporte HTTPS

Para ambientes de produção, especialmente através de redes não confiáveis, o transporte HTTPS criptografa toda a sessão WinRM:

# No servidor remoto: criar um certificado autoassinado
$cert = New-SelfSignedCertificate -DnsName "SERVIDOR01.contoso.com" `
    -CertStoreLocation Cert:\LocalMachine\My -NotAfter (Get-Date).AddYears(5)

# Criar um listener HTTPS usando a impressão digital do certificado
New-WSManInstance -ResourceURI winrm/config/listener `
    -SelectorSet @{Address="*"; Transport="HTTPS"} `
    -ValueSet @{CertificateThumbprint=$cert.Thumbprint}

# Adicionar regra de firewall para HTTPS
New-NetFirewallRule -DisplayName "WinRM HTTPS" -Direction Inbound `
    -LocalPort 5986 -Protocol TCP -Action Allow

Configurar via Política de Grupo

Para implantação em todo o domínio, use a Política de Grupo para habilitar o WinRM em escala:

  1. Navegue até Configuração do Computador → Modelos Administrativos → Componentes do Windows → Gerenciamento Remoto do Windows → Serviço WinRM
  2. Habilite Permitir gerenciamento remoto do servidor através do WinRM
  3. Defina o filtro IPv4/IPv6 para * ou sub-redes específicas
  4. Configure Shell Remoto do Windows → Permitir Acesso ao Shell Remoto como Habilitado

Uso de Invoke-Command e Enter-PSSession

O PowerShell fornece dois cmdlets principais para execução remota, cada um adaptado a fluxos de trabalho diferentes.

Invoke-Command — Execução em Lote Paralelo

Invoke-Command envia um bloco de script para um ou mais computadores e os executa em paralelo por padrão (até 32 conexões simultâneas):

# Executar um comando em um único host remoto
Invoke-Command -ComputerName SERVIDOR01 -ScriptBlock {
    Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
}

# Executar contra múltiplos servidores simultaneamente
$servidores = @("SERVIDOR01", "SERVIDOR02", "SERVIDOR03", "SERVIDOR04")
Invoke-Command -ComputerName $servidores -ScriptBlock {
    Get-Service -Name "W3SVC" | Select-Object Status, MachineName
}

# Limitar a concorrência para ambientes grandes
Invoke-Command -ComputerName $servidores -ScriptBlock {
    Restart-Service -Name "Spooler" -Force
} -ThrottleLimit 10

# Executar um arquivo de script local em máquinas remotas
Invoke-Command -ComputerName $servidores -FilePath "C:\Scripts\Audit-Security.ps1"

Enter-PSSession — Remoting Interativo

Enter-PSSession é ideal para resolução de problemas ad-hoc onde você precisa de um shell interativo:

# Iniciar uma sessão interativa
Enter-PSSession -ComputerName SERVIDOR01 -Credential (Get-Credential)

# Agora você está no SERVIDOR01 — execute comandos como se fosse local
[SERVIDOR01]: PS C:\> Get-EventLog -LogName System -Newest 20
[SERVIDOR01]: PS C:\> Get-Disk | Format-Table
[SERVIDOR01]: PS C:\> Exit-PSSession

Sessões Persistentes (PSSessions)

Para conexões repetidas, crie uma sessão persistente para evitar a sobrecarga de estabelecer uma nova conexão a cada vez:

# Criar sessões persistentes
$sessoes = New-PSSession -ComputerName SERVIDOR01, SERVIDOR02, SERVIDOR03

# Reutilizar a sessão em múltiplos comandos
Invoke-Command -Session $sessoes -ScriptBlock { Get-HotFix | Select-Object -Last 5 }
Invoke-Command -Session $sessoes -ScriptBlock { Get-WindowsFeature | Where-Object Installed }

# Copiar arquivos através de uma sessão
Copy-Item -Path "C:\Deploy\app.zip" -Destination "C:\Install\" -ToSession $sessoes[0]

# Limpar quando terminar
Remove-PSSession $sessoes

Gerenciamento de Credenciais e Segurança

O manuseio adequado de credenciais é crucial para remoting seguro em escala.

Uso de Get-Credential e PSCredential

# Solicitação interativa
$cred = Get-Credential -UserName "CONTOSO\admin" -Message "Digite a senha do administrador remoto"

# Credencial programática (para automação — proteja a fonte da senha)
$securePass = ConvertTo-SecureString "P@ssw0rd!" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential("CONTOSO\admin", $securePass)

Armazenamento Seguro de Credenciais

Nunca codifique senhas diretamente nos scripts. Use uma destas abordagens:

# Exportar credencial criptografada para arquivo (específica de usuário+máquina)
Get-Credential | Export-Clixml -Path "$HOME\cred.xml"

# Importar em outra sessão (mesmo usuário, mesma máquina apenas)
$cred = Import-Clixml -Path "$HOME\cred.xml"

# Usar o Gerenciador de Credenciais do Windows via módulo CredentialManager
Install-Module -Name CredentialManager -Force
New-StoredCredential -Target "WinRM-Admin" -UserName "CONTOSO\admin" `
    -Password "P@ssw0rd!" -Persist LocalMachine
$cred = Get-StoredCredential -Target "WinRM-Admin"

CredSSP para Cenários de Duplo Salto

Quando um comando remoto precisa acessar um segundo recurso (o problema do “duplo salto”), configure a delegação CredSSP:

# No cliente: habilitar o papel de cliente CredSSP
Enable-WSManCredSSP -Role Client -DelegateComputer "SERVIDOR01.contoso.com"

# No servidor: habilitar o papel de servidor CredSSP
Enable-WSManCredSSP -Role Server

# Conectar usando autenticação CredSSP
Invoke-Command -ComputerName SERVIDOR01 -Credential $cred `
    -Authentication CredSSP -ScriptBlock {
    # Agora pode acessar recursos de rede como compartilhamentos
    Get-ChildItem "\\FILESERVER\Share$"
}

Aviso: CredSSP envia as credenciais para o servidor remoto. Use apenas com máquinas de confiança e preferencialmente via HTTPS.

Just Enough Administration (JEA)

Para remoting com privilégios mínimos, configure endpoints JEA que restrinjam o que os usuários podem fazer:

# Criar um arquivo de capacidade de função
New-PSRoleCapabilityFile -Path "C:\JEA\HelpDeskRole.psrc" `
    -VisibleCmdlets @("Restart-Service", "Get-Service", "Get-Process") `
    -VisibleFunctions @("Get-HotFix")

# Criar configuração de sessão
New-PSSessionConfigurationFile -Path "C:\JEA\HelpDesk.pssc" `
    -SessionType RestrictedRemoteServer `
    -RunAsVirtualAccount `
    -RoleDefinitions @{ "CONTOSO\HelpDesk" = @{ RoleCapabilities = "HelpDeskRole" } }

# Registrar o endpoint
Register-PSSessionConfiguration -Name "HelpDesk" -Path "C:\JEA\HelpDesk.pssc"

Remoting Baseado em SSH para Multiplataforma

A partir do PowerShell 7, você pode usar SSH como camada de transporte em vez do WinRM. Isso é especialmente útil para gerenciar máquinas Linux e macOS junto com servidores Windows.

Instalar e Configurar OpenSSH

# No Windows: instalar o servidor OpenSSH
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service sshd -StartupType Automatic

# Configurar o subsistema SSH para PowerShell em sshd_config
# Adicione esta linha a C:\ProgramData\ssh\sshd_config:
# Subsystem powershell c:/progra~1/powershell/7/pwsh.exe -sshs -NoLogo -NoProfile
Restart-Service sshd

No Linux, adicione o subsistema do PowerShell ao /etc/ssh/sshd_config:

# Instalar o PowerShell no Ubuntu
sudo apt-get update && sudo apt-get install -y powershell

# Adicionar subsistema ao sshd_config
echo "Subsystem powershell /usr/bin/pwsh -sshs -NoLogo -NoProfile" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshd

Uso do Remoting Baseado em SSH

# Sessão interativa sobre SSH
Enter-PSSession -HostName servidor-linux01 -UserName admin -SSHTransport

# Executar comandos no Linux a partir do Windows
Invoke-Command -HostName servidor-linux01 -UserName admin -ScriptBlock {
    uname -a
    df -h
    systemctl status nginx
}

# Apontar para sistemas operacionais mistos
$sessaoWindows = New-PSSession -ComputerName WIN-SRV01 -Credential $cred
$sessaoLinux = New-PSSession -HostName LINUX-SRV01 -UserName admin -SSHTransport

Invoke-Command -Session $sessaoWindows, $sessaoLinux -ScriptBlock {
    if ($IsLinux) { cat /etc/os-release } else { Get-ComputerInfo | Select-Object OsName }
}

Comparação: WinRM vs Remoting Baseado em SSH vs OpenSSH no Windows

Funcionalidade WinRM (HTTP/HTTPS) Remoting Baseado em SSH (PS7) OpenSSH no Windows
Protocolo WS-Management SSH SSH
Portas padrão 5985 / 5986 22 22
Autenticação Kerberos, NTLM, CredSSP Chaves SSH, senha Chaves SSH, senha
Multiplataforma Apenas Windows Windows, Linux, macOS Apenas Windows (servidor)
Versão do PowerShell 5.1+ 7.0+ necessário Qualquer (apenas shell SSH)
Criptografia HTTPS ou nível de mensagem Sempre criptografado Sempre criptografado
Duplo salto CredSSP ou delegação Kerberos Encaminhamento de agente SSH Encaminhamento de agente SSH
Integração com domínio AD/Kerberos nativo Gerenciamento manual de chaves Gerenciamento manual de chaves
Gerenciamento por GPO Suporte completo Limitado Limitado
Ideal para Ambientes apenas Windows Ambientes com SO misto Admins Linux gerenciando Windows

Cenário Real

Imagine que você é um administrador de sistemas gerenciando mais de 50 servidores Windows em três ambientes — Desenvolvimento, Staging e Produção — além de algumas máquinas Linux executando proxies reversos Nginx. Veja como você estruturaria seu fluxo de trabalho com PowerShell Remoting:

# Definir grupos de servidores
$servidoresDev = Get-Content "C:\ListasServidores\dev.txt"
$servidoresStaging = Get-Content "C:\ListasServidores\staging.txt"
$servidoresProd = Get-Content "C:\ListasServidores\prod.txt"

# Criar sessões persistentes com credenciais armazenadas
$cred = Import-Clixml "$HOME\admin-cred.xml"
$sessoesDev = New-PSSession -ComputerName $servidoresDev -Credential $cred
$sessoesStaging = New-PSSession -ComputerName $servidoresStaging -Credential $cred

# Verificação de saúde matinal em todos os servidores de desenvolvimento
$relatorioSaude = Invoke-Command -Session $sessoesDev -ScriptBlock {
    [PSCustomObject]@{
        Servidor    = $env:COMPUTERNAME
        Uptime      = (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
        CPUPorcento = (Get-CimInstance Win32_Processor).LoadPercentage
        LivreGB     = [math]::Round((Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='C:'").FreeSpace / 1GB, 2)
        Servicos    = (Get-Service | Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" }).Count
    }
}

$relatorioSaude | Format-Table Servidor, Uptime, CPUPorcento, LivreGB, Servicos -AutoSize

# Implantar um hotfix no staging com concorrência limitada
Invoke-Command -Session $sessoesStaging -ThrottleLimit 5 -ScriptBlock {
    Start-Process msiexec.exe -ArgumentList "/i C:\Deploy\hotfix-kb123.msi /quiet" -Wait
    Write-Output "$env:COMPUTERNAME — Hotfix instalado"
}

# Verificar proxies Linux via SSH
$sessoesLinux = New-PSSession -HostName "proxy01","proxy02" -UserName admin -SSHTransport
Invoke-Command -Session $sessoesLinux -ScriptBlock {
    systemctl is-active nginx
    curl -s -o /dev/null -w "%{http_code}" http://localhost
}

Este padrão mantém as sessões abertas durante a duração do seu trabalho, minimiza a sobrecarga de autenticação e permite que você aponte para grupos de ambientes específicos com execução limitada.

Armadilhas e Casos Especiais

  • Bloqueio de firewall: O WinRM usa a porta 5985 (HTTP) e 5986 (HTTPS). Se o remoting falhar silenciosamente, verifique tanto o Firewall do Windows quanto qualquer firewall de rede entre cliente e servidor.
  • Reset de TrustedHosts: Definir TrustedHosts com Set-Item substitui toda a lista. Use -Concatenate para adicionar: Set-Item WSMan:\localhost\Client\TrustedHosts -Value "NOVOSERVIDOR" -Concatenate.
  • MaxMemoryPerShellMB: O limite padrão (1024 MB) pode causar a queda de sessões durante operações intensivas em memória. Aumente com Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 2048.
  • Falha de duplo salto: Acessar recursos de rede de uma sessão remota falha por padrão. Use CredSSP, delegação restrita de Kerberos ou delegação restrita baseada em recursos para resolver isso.
  • Limites de sessão: O WinRM tem um limite padrão de 25 shells concorrentes por usuário. Em ambientes grandes, aumente MaxShellsPerUser na configuração do WinRM.
  • Diferença de fuso horário: Os timestamps retornados de sessões remotas usam o fuso horário do servidor remoto. Use [DateTime]::UtcNow para consistência em ambientes multi-região.
  • Caminho do subsistema SSH: No Windows, o caminho do subsistema em sshd_config deve usar o formato de nome curto 8.3 (progra~1) ou o caminho completo sem espaços.
  • Limites de serialização: Objetos retornados de sessões remotas são desserializados — perdem seus métodos. O que retorna é um instantâneo, não um objeto vivo. Planeje seus blocos de script para extrair os dados necessários no lado remoto.
  • Incompatibilidade de versão do PowerShell: Se a máquina remota executa PowerShell 5.1 e o cliente executa PowerShell 7, nem todos os cmdlets estarão disponíveis. Teste com -ConfigurationName PowerShell.7 para endpoints PS7.

Resumo

  • Enable-PSRemoting é o comando completo para configurar o WinRM em qualquer máquina Windows.
  • TrustedHosts deve ser configurado no cliente para conexões de grupo de trabalho ou entre domínios.
  • O transporte HTTPS deve ser usado em produção para criptografar o tráfego de remoting de ponta a ponta.
  • Invoke-Command é a ferramenta principal para execução paralela em múltiplos servidores; Enter-PSSession é ideal para resolução de problemas interativa.
  • O gerenciamento de credenciais deve usar Export-Clixml, o Gerenciador de Credenciais ou um cofre de segredos — nunca senhas codificadas diretamente.
  • CredSSP ou delegação restrita de Kerberos resolve o problema do duplo salto.
  • O remoting baseado em SSH no PowerShell 7+ habilita o gerenciamento multiplataforma de Linux e macOS a partir dos mesmos scripts.
  • Os endpoints JEA fornecem remoting com privilégios mínimos para administração delegada.
  • Fique atento aos limites de sessão, comportamento de serialização e regras de firewall à medida que seu ambiente cresce.

Artigos Relacionados