Top Comandos PowerShell Windows Server: Guia Prático para Sysadmin
Comandos PowerShell essenciais para administrar Windows Server sem GUI: serviços, eventos, rede, AD, processos e automação real em produção.
Administrar Windows Server pela interface gráfica funciona, mas escala mal. Você não consegue reproduzir 30 cliques entre Server Manager, Services.msc e Event Viewer em uma janela de manutenção noturna. PowerShell muda essa equação: qualquer ação de GUI tem um cmdlet equivalente, scriptável, auditável e reproduzível em centenas de servidores.
Este guia cobre os comandos PowerShell que um sysadmin Windows usa de verdade todo dia — gestão de serviços e processos, leitura de eventos, configuração de rede, manipulação de usuários e Active Directory, e o caminho completo para automatizar tudo isso via Scheduled Tasks. Os exemplos foram testados em Windows Server 2022 com Windows PowerShell 5.1 (default do sistema) e funcionam sem ajuste em Windows Server 2019 e 2025.
Tempo de execução para passar por todas as seções com prática real: cerca de 40 minutos. Ao final você terá uma sessão PowerShell elevada, vários comandos úteis no histórico, e um script agendado rodando como demonstração.
Pré-requisitos
Windows Server 2019/2022/2025 com acesso RDP ou console e conta com
privilégios administrativos. Windows PowerShell 5.1 já está instalado. Se for
administrar Active Directory, o módulo RSAT-AD-PowerShell precisa estar
presente — instale com Install-WindowsFeature RSAT-AD-PowerShell em um
Domain Controller ou servidor membro do domínio.
Windows Server 2022 5.1 (default) Sessão elevada Antes de qualquer coisa, abra o PowerShell como administrador (Win+X, depois “Windows PowerShell (Admin)” ou “Terminal (Admin)” no Server 2022+). Confirme a versão e a Execution Policy atual:
$PSVersionTable.PSVersion
Get-ExecutionPolicy -List
Se a Execution Policy está em Restricted em todos os escopos, ajuste antes
de rodar qualquer script:
Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy RemoteSigned -Force
Gestão de serviços do Windows
Serviços são o pão com manteiga da administração Windows. Esses comandos substituem por completo o snap-in services.msc.
Listar serviços e filtrar por status:
Get-Service | Where-Object { $_.Status -eq 'Stopped' -and $_.StartType -eq 'Automatic' }Esse pipeline mostra serviços configurados como automáticos mas que estão
parados — um dos primeiros sinais de problema em um servidor recém-iniciado.
A propriedade StartType só vem no PowerShell 5.1+ direto no Get-Service.
Iniciar, parar e reiniciar um serviço:
Start-Service -Name 'W3SVC'
Stop-Service -Name 'W3SVC' -Force
Restart-Service -Name 'W3SVC'Use -Force em Stop-Service quando o serviço tem dependentes — sem isso,
PowerShell pede confirmação para parar a cadeia inteira.
Auditar binário e conta de logon de um serviço (útil em revisão de segurança):
Get-CimInstance Win32_Service -Filter "Name='Spooler'" |
Select-Object Name, PathName, StartName, State, ProcessIdPathName revela se o serviço aponta para binário suspeito (C:\Users\* ou
diretório temporário são red flags). StartName mostra a conta que executa —
contas com privilégio excessivo em serviços de terceiros são vetores
comuns de escalação.
Processos e consumo de recursos
Para diagnosticar pico de CPU ou memória sem abrir o Gerenciador de Tarefas:
Top 10 processos por uso de memória:
Get-Process |
Sort-Object -Property WorkingSet64 -Descending |
Select-Object -First 10 Name, Id,
@{n='RAM_MB';e={[math]::Round($_.WorkingSet64/1MB,1)}},
@{n='CPU_s';e={[math]::Round($_.CPU,1)}}WorkingSet64 é a memória física residente — o número que importa quando o
servidor está sob pressão de RAM. A propriedade CPU acumula segundos de
processador desde o início do processo, então um número alto pode ser
processo legítimo de longa duração, não necessariamente problema.
Matar processo travado por nome ou PID:
Stop-Process -Name 'notepad' -Force
Stop-Process -Id 4242 -ForceNunca use Stop-Process em lsass, csrss, wininit ou services — o
sistema reinicia em 60 segundos com bug check. Confirme o caminho com
Get-Process antes de qualquer Stop-Process em processo desconhecido.
Eventos e logs do Windows
Get-WinEvent é dramaticamente mais rápido que Get-EventLog porque empurra filtros para a API ETW em vez de carregar tudo na memória.
Últimos 20 erros do log System nas últimas 24h:
$ontem = (Get-Date).AddDays(-1)
Get-WinEvent -FilterHashtable @{
LogName = 'System'
Level = 2
StartTime = $ontem
} -MaxEvents 20 | Format-Table TimeCreated, Id, ProviderName, Message -WrapLevel 2 é Error. Use 3 para Warning e 4 para Information. O hashtable é processado server-side, então funciona bem mesmo em logs com milhões de eventos.
Buscar tentativas de logon falhadas (Event ID 4625 do Security log):
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4625
StartTime = (Get-Date).AddHours(-6)
} | Select-Object TimeCreated, @{n='User';e={$_.Properties[5].Value}},
@{n='IP';e={$_.Properties[19].Value}}Event ID 4625 é o evento canônico de logon falho. Em servidor exposto à internet (RDP, SSH, OWA), essa query revela bruteforce em andamento. Se o volume está alto, configure bloqueio por conta com Account Lockout Policy ou um sistema de IP banning.
Rede: configuração e diagnóstico
Esses comandos substituem ncpa.cpl, ipconfig, ping, tracert e netstat em ambiente moderno (Windows Server 2012 R2 ou superior).
Inventário rápido de IPs e gateways:
Get-NetIPConfiguration |
Where-Object { $_.NetAdapter.Status -eq 'Up' } |
Format-Table InterfaceAlias, IPv4Address, IPv4DefaultGateway, DNSServerMostra só interfaces ativas. Para mexer em uma específica:
Get-NetAdapter -Name 'Ethernet0' | Format-List Name, MacAddress, LinkSpeed, StatusConfigurar IP estático e DNS:
New-NetIPAddress -InterfaceAlias 'Ethernet0' `
-IPAddress '10.0.0.50' -PrefixLength 24 -DefaultGateway '10.0.0.1'
Set-DnsClientServerAddress -InterfaceAlias 'Ethernet0' `
-ServerAddresses '1.1.1.1','8.8.8.8'Mudar IP da interface que carrega sua sessão RDP derruba a conexão. Faça via
console (KVM, console serial do provedor) ou agende reversão automática com
Register-ScheduledTask para rodar em 5 minutos caso você não confirme a
mudança.
Listar conexões TCP ativas com PID e processo:
Get-NetTCPConnection -State Listen |
Select-Object LocalAddress, LocalPort,
@{n='Process';e={(Get-Process -Id $_.OwningProcess).Name}} |
Sort-Object LocalPortSubstitui netstat -ano com a vantagem de já trazer o nome do processo. Use
para auditar quais portas estão abertas e quem está escutando.
Usuários e Active Directory
O módulo ActiveDirectory adiciona 150+ cmdlets *-AD*. Os mais usados no
dia a dia:
Criar usuário, definir senha e habilitar:
$senha = Read-Host -AsSecureString 'Senha inicial'
New-ADUser -Name 'João Silva' -SamAccountName 'jsilva' `
-UserPrincipalName '[email protected]' `
-AccountPassword $senha -Enabled $true `
-ChangePasswordAtLogon $true -Path 'OU=Usuarios,DC=empresa,DC=local'Read-Host -AsSecureString evita a senha vazar no histórico do PowerShell.
ChangePasswordAtLogon $true força troca no primeiro acesso, prática
recomendada para qualquer conta provisionada.
Encontrar contas inativas há mais de 90 dias (candidatos a desativação):
Search-ADAccount -AccountInactive -TimeSpan 90.00:00:00 -UsersOnly |
Select-Object Name, SamAccountName, LastLogonDate, Enabled |
Sort-Object LastLogonDateEsse comando é gold para higiene de AD. Contas inativas são vetor de comprometimento porque ninguém percebe se forem reativadas maliciosamente.
Automação: agendar scripts sem GUI
Toda a Task Scheduler tem equivalente em cmdlets. Esse padrão substitui clicar em taskschd.msc.
Agendar um script de manutenção para rodar todo dia às 3h:
$action = New-ScheduledTaskAction -Execute 'powershell.exe' `
-Argument '-NoProfile -ExecutionPolicy Bypass -File C:\scripts\manutencao.ps1'
$trigger = New-ScheduledTaskTrigger -Daily -At 3am
$principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' `
-LogonType ServiceAccount -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable `
-DontStopOnIdleEnd -ExecutionTimeLimit (New-TimeSpan -Hours 2)
Register-ScheduledTask -TaskName 'Manutencao_Diaria' `
-Action $action -Trigger $trigger -Principal $principal -Settings $settings-NoProfile evita carregar perfis de usuário (que podem demorar
segundos). -StartWhenAvailable garante que a task roda quando o servidor
volta de downtime, mesmo que tenha perdido o horário programado.
Coloque Start-Transcript -Path "C:\logs\manutencao_$(Get-Date -f yyyyMMdd).log" -Append
no topo do manutencao.ps1 e Stop-Transcript no fim. Sem isso, debug de
falha em task agendada é cego — o output do script some quando a sessão
termina.
Verificação
Para confirmar que tudo está no lugar, rode esse health check rápido:
Write-Host "PowerShell $($PSVersionTable.PSVersion)"
Write-Host "Execution Policy: $(Get-ExecutionPolicy)"
Write-Host "Tasks ativas: $((Get-ScheduledTask | Where-Object State -eq 'Ready').Count)"
Write-Host "Serviços Stopped (auto): $((Get-Service | Where-Object { $_.Status -eq 'Stopped' -and $_.StartType -eq 'Automatic' }).Count)"
Output esperado em servidor saudável: versão 5.1 ou superior, ExecutionPolicy RemoteSigned, nenhum serviço automático parado sem motivo, e ao menos a task recém-criada visível.
Próximos passos
- Estude
about_Splatting(Get-Help about_Splatting) — passar parâmetros via hashtable deixa scripts longos legíveis. - Aprenda
about_Try_Catch_Finallypara tratamento de erros adequado em scripts agendados, evitando falhas silenciosas. - Configure DSC (Desired State Configuration) ou Ansible para gerenciamento declarativo de configuração em frota de servidores.
- Considere migrar para PowerShell 7 nos servidores onde precisa de pipeline
paralelo (
ForEach-Object -Parallel) ou módulos cross-plataforma.
Se você está rodando esses comandos contra Windows Server em produção, uma VPS Windows da Hostini já vem com licença ativada, console KVM disponível para recuperação quando você se tranca fora pela rede, e snapshots sob demanda para testar mudanças de configuração com segurança.
Perguntas frequentes
Preciso instalar algo para usar esses comandos no Windows Server?
Não. Windows PowerShell 5.1 vem instalado em Windows Server 2016, 2019, 2022 e 2025. O módulo ActiveDirectory exige Remote Server Administration Tools (RSAT), que em Windows Server você adiciona via `Install-WindowsFeature RSAT-AD-PowerShell`. Para PowerShell 7 multiplataforma, baixe o MSI do GitHub oficial — ele instala lado a lado, sem substituir o 5.1.
Como resolver erro 'execution of scripts is disabled on this system'?
Esse erro vem da Execution Policy. Rode `Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy RemoteSigned` em sessão elevada. Isso permite scripts locais e exige assinatura digital em scripts baixados da internet. Para uma execução pontual, use `powershell.exe -ExecutionPolicy Bypass -File caminho.ps1`. Nunca configure como `Unrestricted` em servidor de produção.
Get-Service e Get-CimInstance Win32_Service mostram a mesma coisa?
Não exatamente. Get-Service traz uma visão simplificada (nome, status, start type) e é rápido. Get-CimInstance Win32_Service traz dados completos do WMI: caminho do executável, conta de logon, dependências, PID quando rodando. Use Get-Service no dia a dia e Get-CimInstance quando precisa auditar binário ou conta de serviço.
Como executo PowerShell em outro servidor remotamente?
Habilite WinRM no destino com `Enable-PSRemoting -Force`. Depois use `Invoke-Command -ComputerName srv02 -ScriptBlock { Get-Service }` para comandos pontuais ou `Enter-PSSession srv02` para sessão interativa. Dentro de domínio, a autenticação Kerberos é automática. Fora de domínio, configure TrustedHosts com `Set-Item WSMan:\localhost\Client\TrustedHosts -Value 'srv02'`.
Qual a diferença entre Get-EventLog e Get-WinEvent?
Get-EventLog é o cmdlet legado, lê só os 3 logs clássicos (System, Application, Security) e é lento em logs grandes. Get-WinEvent usa a API ETW moderna, lê qualquer canal do Windows Event Log (incluindo Microsoft-Windows-*), suporta filtros XPath e XML, e é ordens de magnitude mais rápido com filtros server-side. Use Get-WinEvent em qualquer código novo.
Posso agendar scripts PowerShell sem usar a interface gráfica do Task Scheduler?
Sim. Use `New-ScheduledTaskAction` + `New-ScheduledTaskTrigger` + `Register-ScheduledTask`. Sempre passe `-NoProfile` no argumento do powershell.exe para não carregar perfis lentos, registre logs com `Start-Transcript` no topo do script, e rode como `SYSTEM` ou conta de serviço dedicada com `-RunLevel Highest`. Veja exemplo na seção de automação.