Scripts de monitoramento
LidoNesta aula, você aprenderá a criar scripts de monitoramento em PowerShell, cobrindo verificação de serviços e recursos, implementação de alertas, logging e execução periódica. O conteúdo inclui exemplos práticos e exercícios para consolidar o conhecimento.
Bem-vindo à aula 77 do nosso curso de PowerShell! Hoje vamos explorar um dos usos mais poderosos do PowerShell: a criação de scripts de monitoramento. Monitorar sistemas é uma tarefa crucial para garantir disponibilidade, desempenho e segurança. Com PowerShell, você pode automatizar a verificação de serviços, recursos do sistema, gerar alertas e manter logs detalhados, tudo de forma eficiente e integrada ao ecossistema Windows.
Nesta aula, vamos construir desde a base: primeiro, aprenderemos a verificar o estado de serviços e recursos do sistema. Depois, veremos como transformar essas verificações em alertas úteis, seja por e-mail, log ou até mesmo pop-ups. Em seguida, abordaremos a importância do logging e como implementar um sistema de registro robusto. Por fim, discutiremos como agendar a execução periódica dos nossos scripts, seja com o Agendador de Tarefas ou usando loops internos. Ao final, você terá um conhecimento sólido para criar seus próprios scripts de monitoramento profissionais.
Verificando serviços e recursos
O primeiro passo em qualquer script de monitoramento é coletar informações sobre o estado atual do sistema. O PowerShell oferece cmdlets nativos para consultar serviços, processos, uso de CPU, memória, disco e muito mais. Vamos examinar os principais.
Para verificar serviços, usamos o cmdlet Get-Service. Ele retorna objetos que representam cada serviço, com propriedades como Status, Name e DisplayName. Podemos filtrar por status ou nome, e também verificar se um serviço específico está em execução. Por exemplo, para listar todos os serviços em execução:
Get-Service | Where-Object { $_.Status -eq 'Running' }Para recursos do sistema, temos Get-Process para processos, Get-Counter para contadores de desempenho (como CPU e memória), e Get-PSDrive ou Get-Volume para discos. Um exemplo de verificação de uso de disco:
Get-Volume | Select-Object DriveLetter, FileSystemLabel, @{Name='Size(GB)';Expression={[math]::Round($_.Size/1GB,2)}}, @{Name='Free(GB)';Expression={[math]::Round($_.SizeRemaining/1GB,2)}}Para monitorar CPU e memória, podemos usar Get-Counter:
$cpu = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue
$mem = (Get-Counter '\Memory\Available MBytes').CounterSamples.CookedValue
Write-Host "CPU: $cpu% - Memória Livre: $mem MB"Em scripts de monitoramento, é comum definir limites e verificar se os valores estão dentro do esperado. Por exemplo, se a CPU estiver acima de 90% por um período, pode ser um sinal de alerta. Vamos combinar essas verificações em um script simples que verifica serviços críticos e recursos:
$servicos = @('Spooler', 'W3SVC', 'MSSQLSERVER')
foreach ($svc in $servicos) {
$status = (Get-Service -Name $svc -ErrorAction SilentlyContinue).Status
if ($status -eq 'Running') {
Write-Host "$svc está em execução" -ForegroundColor Green
} else {
Write-Host "$svc NÃO está em execução!" -ForegroundColor Red
}
}
$cpuThreshold = 90
$cpu = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue
if ($cpu -gt $cpuThreshold) {
Write-Host "ALERTA: CPU acima de $cpuThreshold% ($cpu%)" -ForegroundColor Yellow
} else {
Write-Host "CPU ok: $cpu%" -ForegroundColor Green
}Alertas
De nada adianta monitorar se não formos notificados quando algo der errado. Alertas são essenciais para que possamos agir rapidamente. O PowerShell permite enviar alertas por e-mail, gravar em log, exibir pop-ups ou até mesmo enviar mensagens para serviços externos como Slack ou Teams (via webhooks).
O método mais comum é o envio de e-mail usando o cmdlet Send-MailMessage (embora em versões mais recentes seja recomendado usar Send-MailKitMessage ou a classe System.Net.Mail.SmtpClient). Um exemplo simples:
$parametrosEmail = @{
From = 'monitor@empresa.com'
To = 'admin@empresa.com'
Subject = 'Alerta: Serviço parado'
Body = 'O serviço Spooler está parado.'
SmtpServer = 'smtp.empresa.com'
}
Send-MailMessage @parametrosEmailPara alertas visuais, podemos usar o .NET Framework para exibir um balão de notificação ou um pop-up. Exemplo de pop-up com MsgBox:
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show('Alerta: CPU alta!', 'Monitoramento')Outra abordagem moderna é enviar um webhook para o Slack ou Teams. Aqui está um exemplo para Slack (usando um webhook URL):
$webhookUrl = 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX'
$mensagem = @{ text = '🚨 Alerta: Serviço Spooler parado!' } | ConvertTo-Json
Invoke-RestMethod -Uri $webhookUrl -Method Post -Body $mensagem -ContentType 'application/json'Em nossos scripts, devemos integrar os alertas às verificações. Por exemplo, se um serviço crítico estiver parado, envie um e-mail e registre no log. Vamos criar uma função de alerta reutilizável:
function Send-Alerta {
param(
[string]$Mensagem,
[string]$Severidade = 'Info'
)
# Enviar e-mail
$parametrosEmail = @{
From = 'monitor@empresa.com'
To = 'admin@empresa.com'
Subject = "[$Severidade] Alerta de Monitoramento"
Body = $Mensagem
SmtpServer = 'smtp.empresa.com'
}
Send-MailMessage @parametrosEmail
# Registrar no log (será abordado na próxima seção)
Write-Log -Mensagem $Mensagem -Severidade $Severidade
}Logging
Manter um registro (log) das atividades e alertas é fundamental para auditoria e diagnóstico. O PowerShell oferece várias formas de criar logs: podemos gravar em arquivos de texto, usar o Event Viewer do Windows, ou até mesmo em bancos de dados.
Uma abordagem simples é criar um arquivo de log com data/hora e mensagens. Podemos definir uma função Write-Log que adiciona linhas a um arquivo:
function Write-Log {
param(
[string]$Mensagem,
[string]$CaminhoLog = 'C:\Logs\monitoramento.log',
[string]$Severidade = 'Info'
)
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
$linha = "[$timestamp] [$Severidade] $Mensagem"
Add-Content -Path $CaminhoLog -Value $linha
}Para usar o Event Viewer, podemos usar o cmdlet Write-EventLog (ou New-EventLog se precisar criar uma fonte). Exemplo:
if (-not [System.Diagnostics.EventLog]::SourceExists('MeuScriptMonitoramento')) {
New-EventLog -LogName Application -Source 'MeuScriptMonitoramento'
}
Write-EventLog -LogName Application -Source 'MeuScriptMonitoramento' -EventId 1001 -EntryType Warning -Message 'Serviço Spooler parado.'É importante incluir detalhes como horário, hostname, e o que estava sendo verificado. Um log bem estruturado facilita a correção de problemas. Vamos melhorar nossa função para incluir o nome do computador e o script:
function Write-Log {
param(
[string]$Mensagem,
[string]$CaminhoLog = 'C:\Logs\monitoramento.log',
[string]$Severidade = 'Info'
)
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
$hostname = $env:COMPUTERNAME
$linha = "[$timestamp] [$hostname] [$Severidade] $Mensagem"
Add-Content -Path $CaminhoLog -Value $linha
}Podemos também configurar a rotação de logs para evitar que os arquivos cresçam indefinidamente, por exemplo, criando um novo arquivo por dia ou por tamanho máximo.
Execução periódica
Para que o monitoramento seja contínuo, precisamos executar nossos scripts em intervalos regulares. Existem duas abordagens principais: usar o Agendador de Tarefas do Windows ou criar um loop dentro do próprio script.
O Agendador de Tarefas é a forma mais profissional e confiável. Podemos criar uma tarefa que executa o script a cada X minutos, no logon ou em horários específicos. Para criar via PowerShell, usamos o módulo ScheduledTasks. Exemplo de criação de uma tarefa que executa o script a cada 5 minutos:
$acao = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-File "C:\Scripts\monitoramento.ps1"'
$gatilho = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 5) -RepetitionDuration (New-TimeSpan -Days 3650)
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable
Register-ScheduledTask -TaskName 'Monitoramento' -Action $acao -Trigger $gatilho -Settings $settings -Description 'Script de monitoramento periódico'Outra opção é usar o Register-ScheduledTask com um gatilho de logon ou em um horário específico. Para mais controle, podemos usar o utilitário schtasks.exe.
Se preferir que o script fique em execução contínua, podemos usar um loop com Start-Sleep. Por exemplo, para verificar a cada 5 minutos:
while ($true) {
# Verificações aqui
Write-Log 'Verificação executada'
Start-Sleep -Seconds 300
}No entanto, essa abordagem não é recomendada para scripts longos, pois consome memória e pode ser interrompida se o PowerShell fechar. O Agendador de Tarefas é mais robusto e permite reiniciar após falhas.
Boas práticas e observações finais
Ao criar scripts de monitoramento, siga estas boas práticas para garantir robustez e manutenibilidade:
- Use funções para encapsular lógica repetitiva, como verificação de serviços e envio de alertas.
- Parametrize caminhos, e-mails e limites em variáveis ou arquivos de configuração.
- Trate erros com
try/catchpara evitar que o script pare inesperadamente. - Inclua informações contextuais nos logs (hostname, timestamp, nome do script).
- Teste os scripts manualmente antes de agendar.
- Considere usar módulos como
PSFrameworkpara logging avançado, ou ferramentas comoPosh-Sysmon.
Lembre-se de que monitorar é um processo contínuo; revise e ajuste seus scripts conforme a infraestrutura evolui.
Exercícios
- Crie um script que verifique se o serviço 'Spooler' está em execução. Se não estiver, exiba um alerta no console e envie um e-mail fictício (use
Send-MailMessagecom parâmetros fictícios). - Escreva uma função
Get-DiskHealthque retorne o espaço livre em disco de todas as unidades em GB, e alerte se alguma tiver menos de 10% de espaço livre. - Implemente um sistema de logging que registre cada execução do script em um arquivo
monitoramento.log, incluindo data/hora e status das verificações. - Crie um script que monitore a CPU e a memória a cada 30 segundos, registrando um alerta se a CPU estiver acima de 80% ou a memória livre abaixo de 500 MB.
- Agende o script de monitoramento para rodar a cada 10 minutos usando o Agendador de Tarefas, e mostre o comando usado.
$servico = Get-Service -Name 'Spooler' -ErrorAction SilentlyContinue
if ($servico -and $servico.Status -eq 'Running') {
Write-Host 'Serviço Spooler em execução' -ForegroundColor Green
} else {
Write-Host 'ALERTA: Serviço Spooler parado!' -ForegroundColor Red
$parametrosEmail = @{
From = 'monitor@empresa.com'
To = 'admin@empresa.com'
Subject = 'Alerta: Serviço Spooler parado'
Body = 'O serviço Spooler está parado. Verifique imediatamente.'
SmtpServer = 'smtp.empresa.com'
}
Send-MailMessage @parametrosEmail
}function Get-DiskHealth {
$volumes = Get-Volume
foreach ($vol in $volumes) {
if ($vol.Size -gt 0) {
$percentFree = ($vol.SizeRemaining / $vol.Size) * 100
if ($percentFree -lt 10) {
Write-Host "ALERTA: Unidade $($vol.DriveLetter) com $([math]::Round($percentFree,2))% livre." -ForegroundColor Red
} else {
Write-Host "Unidade $($vol.DriveLetter): $([math]::Round($percentFree,2))% livre." -ForegroundColor Green
}
}
}
}
Get-DiskHealthfunction Write-Log {
param(
[string]$Mensagem,
[string]$CaminhoLog = 'C:\Logs\monitoramento.log',
[string]$Severidade = 'Info'
)
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
$hostname = $env:COMPUTERNAME
$linha = "[$timestamp] [$hostname] [$Severidade] $Mensagem"
Add-Content -Path $CaminhoLog -Value $linha
}
# Exemplo de uso
Write-Log 'Script iniciado'
# ... verificações ...
Write-Log 'Script finalizado'while ($true) {
$cpu = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue
$mem = (Get-Counter '\Memory\Available MBytes').CounterSamples.CookedValue
if ($cpu -gt 80 -or $mem -lt 500) {
Write-Host "ALERTA: CPU $cpu% - Memória $mem MB" -ForegroundColor Red
Write-Log "ALERTA: CPU $cpu% - Memória $mem MB" -Severidade 'Warning'
} else {
Write-Host "OK: CPU $cpu% - Memória $mem MB" -ForegroundColor Green
Write-Log "OK: CPU $cpu% - Memória $mem MB"
}
Start-Sleep -Seconds 30
}$acao = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-File "C:\Scripts\monitoramento.ps1"'
$gatilho = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 10) -RepetitionDuration (New-TimeSpan -Days 3650)
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable
Register-ScheduledTask -TaskName 'Monitoramento' -Action $acao -Trigger $gatilho -Settings $settings -Description 'Script de monitoramento periódico'