PowerShell | Expert Solutions Microsoft https://paulocostati.com.br Wed, 18 Mar 2026 14:14:42 +0000 pt-BR hourly 1 https://wordpress.org/?v=6.9.4 https://i0.wp.com/paulocostati.com.br/wp-content/uploads/2024/09/Logotipo-empresa-de-programacao-sistemas-e-tecnologia.png?fit=32%2C32&ssl=1 PowerShell | Expert Solutions Microsoft https://paulocostati.com.br 32 32 209994073 Como Criar Relatórios Preditivos no Exchange Online Usando IA e MCP https://paulocostati.com.br/powershell/como-criar-relatorios-preditivos-no-exchange-online-usando-ia-e-mcp/?utm_source=rss&utm_medium=rss&utm_campaign=como-criar-relatorios-preditivos-no-exchange-online-usando-ia-e-mcp https://paulocostati.com.br/powershell/como-criar-relatorios-preditivos-no-exchange-online-usando-ia-e-mcp/#respond Wed, 18 Mar 2026 14:07:54 +0000 https://paulocostati.com.br/?p=305 Fala Pessoal, tudo bem com vocês? Hoje vou falar um pouco sobre como criar relatórios preditivos no Exchange Online combinando PowerShell, MCP e GitHub Copilot para você sair do modo reativo e começar a antecipar problemas de mailbox antes que o usuário perceba.

Você já chegou numa segunda-feira de manhã e descobriu que a cota de mailbox de um usuário estourou no final de semana? Ou recebeu uma ligação furiosa porque o fluxo de e-mails de um departamento inteiro ficou represado por um problema de throttling que ninguém viu vir?

Quem administra Exchange Online no dia a dia sabe como isso acontece. A plataforma é robusta, mas os problemas aparecem depois que o estrago está feito. Os relatórios nativos do Microsoft 365 Admin Center mostram o passado e o passado não te ajuda a agir antes.

Então fui atrás de uma forma de mudar isso. Combinando PowerShell, Microsoft Graph API, MCP e o GitHub Copilot em Agent Mode no VS Code, montei um fluxo que coleta os dados do ambiente, identifica padrões e gera um relatório de risco antes do incidente acontecer sem precisar de nenhuma chave de API externa. Vou mostrar tudo aqui, do zero.

O Problema com os Relatórios Tradicionais

O Exchange Online tem bastante coisa disponível para quem quer monitorar o ambiente: relatórios no Admin Center, dados via PowerShell com o módulo ExchangeOnlineManagement, endpoints na Microsoft Graph. Para auditoria e compliance, funcionam bem.

O problema é que todos eles são descritivos. Te dizem o que aconteceu. Não te dizem o que vai acontecer.

Pensa num cenário real: você tem 800 usuários, e 40 deles estão com a cota de mailbox entre 85% e 95%. Você extrai esse dado hoje com PowerShell. E aí? Manda e-mail manual para cada um? Abre chamado para o suporte tratar caso a caso? Fica verificando todo dia?

O que eu queria era diferente: coletar esses dados automaticamente, estimar em quantos dias cada mailbox vai estourar, gerar um relatório priorizado com os casos mais urgentes e sugestões de ação sem precisar escrever uma linha de análise na mão. É exatamente isso que o MCP combinado com o Copilot permite construir.

O Que é o MCP e Por Que Usei Ele Aqui

O MCP (Model Context Protocol) é um protocolo aberto da Anthropic que padroniza como modelos de IA se conectam a fontes de dados e ferramentas externas. Em vez de montar integrações separadas para cada coisa, você expõe funções via MCP e o modelo sabe quando e como chamá-las.

No nosso caso, o MCP age como uma ponte entre o PowerShell que conhece o Exchange Online de perto e o GitHub Copilot, que vai fazer a análise. Você define as ferramentas disponíveis, como “buscar mailboxes próximas do limite” ou “verificar o fluxo de e-mail dos últimos dias”, e o Copilot decide o que consultar para responder o que você pediu.

O ponto que me convenceu a usar essa abordagem é que você não precisa preparar os dados na mão antes de jogar para IA. O modelo faz as chamadas, interpreta e devolve o relatório formatado. Isso muda bastante a dinâmica do trabalho.

Arquitetura da Solução

Antes de entrar no código, vale ver a estrutura que montei. O diagrama abaixo mostra as quatro camadas e como elas se conectam:

Cada camada tem um papel bem definido. O PowerShell vai na fonte conecta no Exchange Online, puxa os dados e gera o JSON. O MCP Server transforma essas funções em ferramentas que o Copilot pode chamar. O Copilot em Agent Mode usa essas ferramentas para montar o relatório, sem precisar de nenhuma API key extra.

Pré-requisitos

Antes de começar, garanta que você tem:

  • Módulo ExchangeOnlineManagement instalado (Install-Module ExchangeOnlineManagement)
  • App Registration no Entra ID configurado com as permissões mínimas (detalhes na próxima seção)
  • Certificado X.509 gerado e associado ao App Registration sem client secret
  • Node.js 18+ para rodar o MCP Server
  • VS Code com a extensão GitHub Copilot (plano Free já funciona)
  • PowerShell 7.x recomendado para compatibilidade com o MCP SDK

Autenticação App Registration com Certificado

Esse é o ponto que separa uma automação feita para durar de uma gambiarra que quebra na primeira rotação de senha. Usar App Registration com certificado resolve três problemas de uma vez: não tem credencial de usuário no script, o MFA não bloqueia a execução agendada e não tem client secret para rotacionar de tempos em tempos.

Permissões mínimas necessárias

Configure o App Registration com as seguintes permissões de Aplicativo não delegadas, porque o script roda sem usuário logado:

APIPermissão
Microsoft GraphMail.Read
Microsoft GraphMailboxSettings.Read
Microsoft GraphReports.Read.All
Office 365 Exchange OnlineExchange.ManageAsApp

Role obrigatória: depois de conceder Exchange.ManageAsApp, atribua a role Global Reader ao Service Principal do app no portal do Entra ID → Roles and Administrators. Sem essa role, o Connect-ExchangeOnline retorna acesso negado mesmo com a permissão consentida já caí nessa antes.

Admin consent: permissões de Aplicativo precisam de consentimento de um Global Administrator no Entra ID. Sem isso, nada funciona.

Gerando o certificado autoassinado

Em produção, prefira um certificado emitido pela CA interna. Para lab ou ambientes sem CA disponível, o PowerShell resolve em segundos:

$certParams = @{
Subject = "CN=ExchangeMCPApp"
CertStoreLocation = "Cert:CurrentUserMy"
KeyExportPolicy = "Exportable"
KeySpec = "Signature"
KeyLength = 2048
HashAlgorithm = "SHA256"
NotAfter = (Get-Date).AddYears(2)
}
$cert = New-SelfSignedCertificate @certParams
Export-Certificate -Cert $cert -FilePath "C:tempExchangeMCPApp.cer" | Out-Null
$pfxPassword = Read-Host "Senha do PFX" -AsSecureString
Export-PfxCertificate -Cert $cert -FilePath "C:tempExchangeMCPApp.pfx" -Password $pfxPassword | Out-Null
Write-Host "Thumbprint: $($cert.Thumbprint)"
Write-Host "Arquivos gerados em C:temp"

Depois de gerar, faça o upload do .cer no App Registration → Certificates & secrets → Certificates. Anote o Thumbprint ele vai substituir qualquer client secret no script.

Etapa 1 — Coletando os Dados do Exchange Online

Com o App Registration e o certificado no lugar, a conexão usa o CertificateThumbprint direto sem usuário, sem MFA, sem janela de login aparecendo pra quebrar o agendamento às 3 da manhã.


$AppId          = ""  # Application (client) ID
$TenantId       = ""  # Directory (tenantName)
$CertThumbprint = ""                      # Thumbprint do certificado
Connect-ExchangeOnline `
    -AppId                 $AppId `
    -CertificateThumbprint $CertThumbprint `
    -Organization          "$TenantId.onmicrosoft.com" `
    -ShowBanner:$false 
function Get-MailboxUsageReport {
    param(
        [int]$QuotaWarningPercent = 80
    )
    $mailboxes = Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox |
        Select-Object DisplayName, UserPrincipalName, ProhibitSendQuota, ProhibitSendReceiveQuota
    $report = foreach ($mbx in $mailboxes) {
        $stats = Get-MailboxStatistics -Identity $mbx.UserPrincipalName -ErrorAction SilentlyContinue
        if ($null -eq $stats) { continue }
        $sizeStr = $stats.TotalItemSize.Value.ToString()
        $totalSizeBytes = [regex]::Match($sizeStr, '((d+) bytes)').Groups[1].Value
        if ([string]::IsNullOrEmpty($totalSizeBytes)) {
            $totalSizeBytes = 0
        }
        $limitStr = $mbx.ProhibitSendReceiveQuota.ToString()
        if ($limitStr -eq "Unlimited") {
            $limitBytes = 107374182400  # 100 GB como fallback
        } else {
            $limitMatch = [regex]::Match($limitStr, '((d+) bytes)')
            if ($limitMatch.Success) {
                $limitBytes = [int64]$limitMatch.Groups[1].Value
            } else {
                $limitBytes = 107374182400  # 100 GB como fallback
            }
        }
        $percentUsed = if ($limitBytes -gt 0) {
            [math]::Round(([int64]$totalSizeBytes / $limitBytes) * 100, 2)
        } else {
            0
        }
        [PSCustomObject]@{
            DisplayName   = $mbx.DisplayName
            UPN           = $mbx.UserPrincipalName
            TotalSizeGB   = [math]::Round($totalSizeBytes / 1GB, 3)
            LimitGB       = [math]::Round($limitBytes / 1GB, 3)
            PercentUsed   = $percentUsed
            ItemCount     = $stats.ItemCount
            LastLogonTime = $stats.LastLogonTime
            AlertLevel    = if ($percentUsed -ge 95) { "CRÍTICO" }
                            elseif ($percentUsed -ge $QuotaWarningPercent) { "ATENÇÃO" }
                            else { "OK" }
        }
    }
    return $report | Sort-Object PercentUsed -Descending
}
$usageData = Get-MailboxUsageReport -QuotaWarningPercent 80
$usageData | ConvertTo-Json -Depth 3 | Out-File "$env:TEMPexchange_usage.json" -Encoding UTF8
Write-Host "Coleta concluída. Total de mailboxes: $($usageData.Count)"
Write-Host "Críticos: $(($usageData | Where-Object AlertLevel -eq 'CRÍTICO').Count)"
Write-Host "Em atenção: $(($usageData | Where-Object AlertLevel -eq 'ATENÇÃO').Count)"

Esse script classifica cada mailbox por nível de alerta e salva tudo em JSON. É esse arquivo que o MCP Server vai ler na próxima etapa.

Etapa 2 — Construindo o MCP Server

O MCP Server é a peça central da integração. É ele que transforma as funções de coleta em ferramentas que o Copilot pode chamar durante a análise sem você precisar preparar nada na mão.

Irei deixar o link do projeto no github para download.

https://github.com/paulocostatipe/MCP-Exchange

No arquivo README você vai encontrar como configurar o MCP

Depois de realizar o readme para um teste você pode pedir direto no agente do copilot no github para iniciar o MCP e começar as fazer algumas consultas

Exemplos:

Solicitei agora uma previsão baseado nesses 10 dias de quando essa caixa pode ficar lotada

Conclusão

A diferença entre um ambiente que funciona bem e um que vive apagando incêndio geralmente não é a tecnologia é a visibilidade. Com esse fluxo, você tem clareza sobre o que vai acontecer antes de acontecer, e tempo suficiente pra agir. Com isso você pode adaptar para realizar diversas consultas, aqui é só um exemplo bem basico em um laboratorio.

PowerShell cuida da coleta, MCP conecta tudo, Copilot faz a análise.

Esse é um ponto de partida. Dá pra expandir com análise de regras de transporte, detecção de padrões de spoofing, crescimento de grupos do Teams. A estrutura já está montada é só ir adicionando as ferramentas que fazem sentido pro seu ambiente.

Gostou do conteúdo?

Se esse artigo te ajudou, compartilha com alguém da área. Deixa nos comentários quais outros relatórios você quer ver com essa abordagem DLP, auditoria de acessos, crescimento de grupos?

]]>
https://paulocostati.com.br/powershell/como-criar-relatorios-preditivos-no-exchange-online-usando-ia-e-mcp/feed/ 0 305
Painel Visual no IIS para Monitorar Serviços de Vários Servidores Usando PowerShell https://paulocostati.com.br/powershell/painel-visual-no-iis-para-monitorar-servicos-de-varios-servidores-usando-powershell/?utm_source=rss&utm_medium=rss&utm_campaign=painel-visual-no-iis-para-monitorar-servicos-de-varios-servidores-usando-powershell Fri, 17 Oct 2025 00:09:49 +0000 https://paulocostati.com.br/?p=269

Painel Visual no IIS para Monitorar Serviços de Vários Servidores Usando PowerShell

Fala pessoal, tudo bem com vocês?

Imagine o cenário mais comum para qualquer administrador de TI: uma infraestrutura em crescimento, dezenas de servidores e a necessidade incessante de garantir o funcionamento de serviços críticos como o IIS (w3svc), Gerenciamento Remoto (WinRM) e Fila de Impressão (Spooler).

O método tradicional—abrir dezenas de sessões RDP, rodar Get-Service manualmente e verificar logs—é ineficiente, insustentável e impossível de escalar. A informação está dispersa e o tempo é perdido em cliques repetitivos.

A solução? Criar uma Central de Comando leve, visual e proativa, utilizando apenas duas ferramentas nativas e poderosas: PowerShell (para automação e coleta de dados) e IIS (para hospedagem e visualização).

Este projeto é dividido em três etapas claras: configurar o servidor central (IIS), enviar dados dos servidores remotos e gerar o painel visual.

1. Configurando o Servidor Central (O Painel IIS)

 

O script inicial prepara o ambiente. Ele instala o IIS, adiciona os recursos necessários e cria a estrutura de pastas que funcionará como a base de dados centralizada, definindo permissões de escrita para garantir que os servidores remotos possam enviar seus logs.

				
					<#
    .DESCRIPTION
    Script para configurar o IIS e preparar o ambiente para o Painel de Serviços.
    .AUTHOR
    Paulo Costa
#>

# Instalar IIS e recursos essenciais
Write-Host "Iniciando a instalação do IIS e componentes básicos..."
Install-WindowsFeature -Name Web-Server,Web-WebServer,Web-Common-Http,Web-Static-Content,Web-Default-Doc,Web-ASP -IncludeManagementTools -Confirm:$false

# Definir Caminhos
$PainelPath = "C:\inetpub\wwwroot\painel"
$LogsPath = "$PainelPath\logs"

# Criar a estrutura de pastas do Painel
if (-not (Test-Path $PainelPath)) { 
    New-Item -Path $PainelPath -ItemType Directory -Force
    Write-Host "Pasta principal do Painel criada: $PainelPath"
}
if (-not (Test-Path $LogsPath)) { 
    New-Item -Path $LogsPath -ItemType Directory -Force
    Write-Host "Pasta de Logs criada: $LogsPath"
}

# Configurar Permissões de Escrita (MUITO IMPORTANTE: Ajuste 'Everyone' conforme sua política de segurança)
Write-Host "Configurando permissões na pasta de Logs para permitir escrita remota..."
$acl = Get-Acl $LogsPath
# Concede permissão de Modificação (Modify) para o usuário 'Everyone'
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("Everyone","Modify","ContainerInherit,ObjectInherit","None","Allow")
$acl.SetAccessRule($rule)
Set-Acl $LogsPath $acl

# Criar o arquivo HTML inicial (Placeholder)
$HtmlPath = "$PainelPath\index.html"
@"
<html>
<head><title>Painel de Serviços</title></head>
<body>
    <div style="font-family: monospace; padding: 20px; background-color: #1e1e1e; color: #dcdcdc;">
        <h2>Painel de Serviços - Inicializando...</h2>
        <p>Aguardando a primeira execução do script central para gerar o relatório.</p>
    </div>
</body>
</html>
"@ | Out-File $HtmlPath -Encoding UTF8

Write-Host "IIS configurado e Painel pronto para receber logs!"

				
			

2. O Agente de Coleta Remota (Rodando em Cada Servidor)

Este é o script que transforma cada servidor em um “agente de campo”. Ele verifica o status de uma lista predefinida de serviços e, o ponto crucial, salva o resultado em um arquivo de log nomeado com o nome do próprio computador no caminho de rede centralizado.

Atenção: Agende este script via Task Scheduler para rodar a cada 5 minutos em todos os servidores que você deseja monitorar.

				
					<#
.DESCRIPTION
    Script para verificar o status de serviços essenciais e registrar em log centralizado.
    Gera arquivo TXT com o status atual do servidor, usando o nome da máquina.

.AUTHOR
    Paulo Costa

.VERSION
    1.2
.NOTES
    Este script sobrescreve o arquivo de log a cada execução para fornecer o status mais atual.
    Execução recomendada: via Task Scheduler a cada 15 minutos
#>

[CmdletBinding()]
param(
    [string]$LogDir = '\\NomeServidor\inetpub\wwwroot\painel\logs', 
    [switch]$VerboseOutput
)

## CONFIGURAÇÕES
$ErrorActionPreference = 'Stop'
$InformationPreference = if ($VerboseOutput) { 'Continue' } else { 'SilentlyContinue' }

Write-Information "Iniciando verificação de serviços em $(Get-Date -Format 'dd/MM/yyyy HH:mm:ss')"

$LogPath = Join-Path $LogDir "$env:COMPUTERNAME.txt"

try {
    if (-not (Test-Path $LogDir)) { New-Item -Path $LogDir -ItemType Directory -Force | Out-Null }
    Write-Information "Pasta de logs verificada: $LogDir"
} catch { 
    Write-Error "Não foi possível acessar ou criar a pasta de logs: $_"
    exit 1 
}

try {
    Write-Information "Obtendo e processando dados dos serviços..."
    
    $CurrentTime = Get-Date -Format 'dd/MM/yyyy HH:mm:ss'
    
    $Resultado = Get-Service | 
        Where-Object { 
            # Filtra serviços que estão em status relevante (Running, Stopped, Paused)
            $_.Status -in @('Running', 'Stopped', 'Paused') 
        } | 
        ForEach-Object {
            # Formato de saída exato: Servico;Status;Data
            "$($_.Name);$($_.Status);$CurrentTime" 
        }
    
    Write-Information "Total de logs formatados: $($Resultado.Count)"
    
    $Resultado | Out-File -FilePath $LogPath -Encoding UTF8 -Force
    
    Write-Host "Log de status atualizado com sucesso em $LogPath"

} catch {
    Write-Error "Erro ao obter ou salvar status dos serviços: $_"
    exit 1
}
				
			

 

3. A Central de Processamento (Gerador do Painel HTML)

Este script deve rodar no Servidor IIS (o servidor central) em um intervalo de tempo ligeiramente maior (ex: a cada 5 minutos, garantindo que os logs dos agentes já tenham chegado). Ele lê todos os logs, os consolida e gera o arquivo index.html visualmente aprimorado, utilizando CSS para sinalizar o status de forma clara e imediata.

Script de Geração do Painel HTML

Ao acessar o URL do seu IIS, o administrador tem uma visão instantânea, eliminando a necessidade de RDP. O uso de cores vibrantes sobre o fundo escuro garante que os problemas (vermelho e amarelo) saltem imediatamente aos olhos.

E aí, o que vocês acharam desse painel?

]]>
269
Monitore Logon e Logoff no Windows com PowerShell – Versão Melhorada https://paulocostati.com.br/windows-server/monitore-logon-e-logoff-no-windows-com-powershell-versao-melhorada/?utm_source=rss&utm_medium=rss&utm_campaign=monitore-logon-e-logoff-no-windows-com-powershell-versao-melhorada Tue, 30 Sep 2025 11:39:57 +0000 https://paulocostati.com.br/?p=255

Fala pessoal, tudo bem com vocês?

No post anterior eu mostrei como usar PowerShell para monitorar e automatizar serviços do Windows.

Agora eu trago uma versão melhorada e mais completa, voltada para quem precisa auditar logons e logoffs de usuários, seja em servidores ou estações de trabalho.


O que essa versão traz de novo

Com esse script você vai conseguir:

  • Coletar eventos de Logon (4624), Logoff (4634) e Logoff de usuário (4647).
  • Definir a quantidade de dias que deseja analisar.
  • Gerar relatórios em dois formatos:
    • CSV – perfeito para Excel ou Power BI.
    • HTML – visual limpo e pronto para abrir no navegador.
  • Obter informações importantes como:
    • Data do evento
    • Usuário
    • Tipo de logon
    • Máquina de origem

Tudo isso de forma automatizada, com mensagens claras durante a execução.


Requisitos

Antes de rodar, verifique:

  • PowerShell 5 ou superior (já vem no Windows 10/11 e Windows Server 2016+).
  • Executar como Administrador (o log de segurança exige permissão elevada).

Como usar

  1. Copie o script abaixo e salve como, por exemplo: C:\\Scripts\\Relatorio-LogonLogoff.ps1
  2. Abra o PowerShell como Administrador.
  3. Execute: .\\Relatorio-LogonLogoff.ps1
  4. Informe o número de dias de eventos que deseja coletar.
  5. O script cria a pasta: C:\\Temp\\LogonLogoff E salva lá os relatórios:
    • Relatorio-Logonlogoff.csv
    • Relatorio-Logonlogoff.html

Script

Write-Host "Iniciando coleta de eventos de Logon/Logoff..." -ForegroundColor Cyan

try {
    [int]$Dias = Read-Host "Quantos dias de eventos você deseja coletar?"
}
catch {
    Write-Host "Entrada inválida. Por favor, insira um número inteiro (ex: 10)." -ForegroundColor Red
    return
}

$OutputFolder = "C:\\Temp\\LogonLogoff"
$OutputCsv = "$OutputFolder\\Relatorio-Logonlogoff.csv"
$OutputHtml = "$OutputFolder\\Relatorio-Logonlogoff.html"

$ReportDate = Get-Date -Format "dd/MM/yyyy HH:mm:ss"
$ComputerName = $env:COMPUTERNAME
$ReportCreator = $env:USERNAME

Write-Host "Verificando/Criando o diretório de saída: $OutputFolder" -ForegroundColor Blue
if (-not (Test-Path $OutputFolder)) {
    try {
        New-Item -Path $OutputFolder -ItemType Directory -Force | Out-Null
        Write-Host "Diretório '$OutputFolder' criado com sucesso!" -ForegroundColor Green
    }
    catch {
        Write-Host "Erro ao criar o diretório. Por favor, verifique suas permissões." -ForegroundColor Red
        return
    }
}

Write-Host "Buscando eventos dos últimos '$Dias' dias..." -ForegroundColor Blue
Write-Progress -Activity "Coletando eventos..." -Status "Isso pode levar alguns minutos..." -PercentComplete 10

try {
    $Events = Get-WinEvent -FilterHashtable @{
        LogName   = 'Security'
        Id        = 4624, 4634, 4647
        StartTime = (Get-Date).AddDays(-$Dias)
    } | Select-Object @{Name='Data do Evento'; Expression={$_.TimeCreated}},
        Id,
        @{Name='Usuário'; Expression={$_.Properties[5].Value}},
        @{Name='Tipo de Logon'; Expression={
            switch ($_.Properties[8].Value) {
                2 { "Interativo (Local)" }
                3 { "Rede" }
                4 { "Batch" }
                5 { "Serviço" }
                7 { "Desbloquear (Tela)" }
                10 { "RemoteInteractive (RDP/Terminal)" }
                default { "Outros" }
            }
        }},
        @{Name='Máquina de Origem'; Expression={$_.Properties[11].Value}}

    Write-Progress -Activity "Coletando eventos..." -Status "Coleta concluída. Salvando relatórios..." -PercentComplete 50

    $Events | Export-Csv -Path $OutputCsv -NoTypeInformation -Delimiter ';'
    Write-Host "Relatório CSV salvo em: $OutputCsv" -ForegroundColor Green

    $HtmlHeader = @"
<head>
    <title>Relatório de Logon/Logoff dos últimos $Dias dias</title>
    <style>
        body { font-family: Arial, sans-serif; background-color: #f4f4f4; color: #333; margin: 20px; }
        h1 { color: #0056b3; text-align: center; }
        .header-info { text-align: center; margin-bottom: 20px; }
        .header-info p { margin: 5px 0; font-size: 14px; }
        table { width: 100%; border-collapse: collapse; margin-top: 20px; }
        th, td { padding: 12px 15px; text-align: left; border-bottom: 1px solid #ddd; }
        th { background-color: #007bff; color: white; }
        tr:nth-child(even) { background-color: #f9f9f9; }
        tr:hover { background-color: #f1f1f1; }
    </style>
</head>
"@
    $HtmlBody = @"
<body>
    <div class="header-info">
        <h1>Relatório de Logon/Logoff dos últimos $Dias dias</h1>
        <p><strong>Relatório Gerado em:</strong> $ReportDate</p>
        <p><strong>Computador:</strong> $ComputerName</p>
        <p><strong>Criado por:</strong> $ReportCreator</p>
    </div>
"@

    $EventsHtmlTable = $Events | ConvertTo-Html -As Table -Fragment
    $HtmlContent = "<html>" + $HtmlHeader + $HtmlBody + $EventsHtmlTable + "</body></html>"
    $HtmlContent | Out-File -FilePath $OutputHtml -Encoding UTF8

    Write-Host "Relatório HTML salvo em: $OutputHtml" -ForegroundColor Green
    Write-Progress -Activity "Coletando eventos..." -Status "Relatórios prontos!" -PercentComplete 100
    Start-Sleep -Seconds 2
}
catch {
    Write-Host "Ocorreu um erro ao coletar os eventos. Verifique se o script está rodando como Administrador e se você tem eventos de segurança disponíveis." -ForegroundColor Red
}


Resultado

O relatório em HTML final traz uma tabela bem organizada com todos os eventos coletados, pronta para:

  • consulta rápida,
  • envio em relatórios internos,
  • ou até integração em um processo de auditoria.

Conclusão

Esse script deixa o processo de auditoria de logon/logoff muito mais simples e visual.

Se você já faz esse tipo de análise no dia a dia, pode usar essa versão como base e adaptá-la conforme a sua necessidade.

E aí, o que vocês acharam dessa versão melhorada?

Deixem nos comentários como vocês fazem o monitoramento de logon/logoff no ambiente de vocês!

]]>
255
Cansado de tarefas manuais? Automatize tudo no Windows Server com PowerShell! https://paulocostati.com.br/windows-server/cansado-de-tarefas-manuais-automatize-tudo-no-windows-server-com-powershell/?utm_source=rss&utm_medium=rss&utm_campaign=cansado-de-tarefas-manuais-automatize-tudo-no-windows-server-com-powershell Sat, 20 Sep 2025 09:00:00 +0000 https://paulocostati.com.br/?p=250

Cansado de tarefas manuais? Automatize tudo no Windows Server com PowerShell!

Fala, pessoal, tudo bem com vocês?

Se você trabalha com administração de servidores, sabe que a rotina pode ser exaustiva. Gerenciar serviços, criar usuários, fazer backups… é um trabalho manual e que consome um tempo enorme. A boa notícia é que o PowerShell chegou para transformar essa rotina! Com ele, você automatiza tarefas repetitivas, economiza tempo e minimiza erros, podendo focar em coisas mais importantes.

Neste post, vou mostrar como automatizar as tarefas mais comuns para você dizer adeus ao trabalho manual.

Gerenciamento de Serviços: Fique no controle!

Manter os serviços essenciais do Windows Server funcionando é fundamental. O PowerShell permite que você gerencie esses serviços facilmente, seja para iniciar, parar ou apenas verificar o status.

  • Verificar o Status: Use Get-Service para ver o status de todos os serviços no servidor. Se quiser checar um específico, como o Windows Update, use Get-Service -Name wuauserv

  • Iniciar ou Parar: Para iniciar ou parar um serviço, os cmdlets são Start-Service e Stop-Service. Por exemplo, para iniciar o Windows Update, o comando é Start-Service -Name wuauserv.

    Para pará-lo, use Stop-Service -Name wuauserv

Scripts que trabalham para você

A cereja do bolo é criar um script que verifica se um serviço está parado e, se estiver, o inicia automaticamente. Isso garante a alta disponibilidade de serviços críticos.

				
					$servico = Get-Service -Name wuauserv
if ($servico.Status -eq 'Stopped') {
    Start-Service -Name wuauserv
    Write-Host "Serviço Windows Update iniciado."
} else {
    Write-Host "O serviço já está em execução."
}
				
			

Onde aplicar essa automação?

Essa automação é super útil para:

  • Garantir que serviços críticos como o SQL Server ou o Exchange estejam sempre em execução.

  • Automatizar a inicialização de serviços após uma reinicialização do servidor.

  • Monitorar e manter a saúde do seu ambiente sem precisar entrar no servidor a todo momento.

]]>
250
Monitore e Automatize Serviços do Windows com PowerShell https://paulocostati.com.br/windows-server/monitore-e-automatize-servicos-do-windows-com-powershell/?utm_source=rss&utm_medium=rss&utm_campaign=monitore-e-automatize-servicos-do-windows-com-powershell Tue, 16 Sep 2025 23:00:23 +0000 https://paulocostati.com.br/?p=237

Monitore e Automatize Serviços do Windows com PowerShell

Fala pessoal, tudo bem com vocês?

Já aconteceu de um serviço crítico parar de funcionar e você descobrir tarde demais?
Neste post, vou te mostrar como monitorar serviços do Windows automaticamente usando PowerShell, gerar relatórios diários e até reiniciar serviços parados — tudo de forma simples, prática e segura.

O que você vai aprender

  • Monitorar serviços essenciais (IIS, SQL Server, Exchange, etc.).

  • Reiniciar serviços automaticamente se eles estiverem parados.

  • Gerar relatórios HTML de status para auditoria.

  • Automatizar a execução diária com Task Scheduler.

				
					<#
.DESCRIPTION
Monitora serviços do Windows, reinicia se estiverem parados e gera relatório HTML.
.AUTHOR
Paulo Costa
.VERSION
1.0
#>

param(
    [String[]]$servicos = @("Spooler", "wuauserv", "BITS"), # Serviços para monitorar, adicione ou remova conforme necessário
    [String]$ReportFolder = "C:\ServiceReports\" # Pasta onde o relatório será salvo
)

if (-not (Test-Path $ReportFolder)) { New-Item -ItemType Directory -Path $ReportFolder -Force | Out-Null }
$ReportFile = Join-Path $ReportFolder ("ServiceReport_" + (Get-Date -Format "yyyyMMdd_HHmmss") + ".html")

$ReportData = @()

foreach ($svc in $servicos) {
    try {
        $servico = Get-Service -Name $svc -ErrorAction Stop
        $statusBefore = $servico.Status

        if ($servico.Status -ne "Running") {
            Start-Service -Name $svc -ErrorAction SilentlyContinue
            Start-Sleep -Seconds 3
            $servico.Refresh()
        }

        $ReportData += [PSCustomObject]@{
            Serviço = $svc
            StatusAnterior = $statusBefore
            StatusDepois  = $servico.Status
            Data    = Get-Date
        }
    } catch {
        $ReportData += [PSCustomObject]@{
            Serviço = $svc
            StatusAnterior = "Erro"
            StatusDepois  = "Erro"
            Data    = Get-Date
        }
    }
}

$Html = $ReportData | Sort-Object Serviço | ConvertTo-Html `
    -Title "Relatório de Serviços - $env:COMPUTERNAME" `
    -PreContent "<h2>Relatório de Serviços do Windows - $env:COMPUTERNAME</h2><p>Gerado em: $(Get-Date)</p>" `
    -PostContent "<p style='font-size:12px;color:gray;'>Script desenvolvido por Paulo Costa</p>"

$Html | Out-File -FilePath $ReportFile -Encoding UTF8
Write-Host "Relatório gerado: $ReportFile" -ForegroundColor Green

				
			

Automatizando a execução

Para rodar diariamente sem intervenção:

  1. Abra Task Scheduler.

  2. Crie Basic Task → Nome: Monitorar Serviços.

  3. Trigger: Daily → Hora desejada.

  4. Action: Start a Program → powershell.exe

    • Add arguments: -File "C:\temp\Services.ps1"

  5. Salve e teste.

Agora você terá relatórios diários automáticos e os serviços sempre monitorados.

]]>
237