TI | Expert Solutions Microsoft https://paulocostati.com.br Fri, 17 Oct 2025 00:10:28 +0000 pt-BR hourly 1 https://wordpress.org/?v=7.0 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 TI | Expert Solutions Microsoft https://paulocostati.com.br 32 32 209994073 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
Como Criar um Relatório de Usuários Inativos com Licença no Microsoft 365 Usando PowerShell https://paulocostati.com.br/powershell/como-criar-um-relatorio-de-usuarios-inativos-com-licenca-no-microsoft-365-usando-powershell/?utm_source=rss&utm_medium=rss&utm_campaign=como-criar-um-relatorio-de-usuarios-inativos-com-licenca-no-microsoft-365-usando-powershell Mon, 26 May 2025 01:23:12 +0000 https://paulocostati.com.br/?p=116 Fala pessoal, tudo bem com vocês? No post de hoje eu vou mostrar como usar PowerShell para identificar licenças do Microsoft 365 que estão paradas e custando dinheiro à toa para sua empresa.

Recentemente, recebi mensagens de profissionais que reclamam sobre como é difícil controlar essas licenças e evitar gastos desnecessários. A boa notícia? Dá para automatizar isso com PowerShell, e eu vou mostrar como.

Antes de começar, já vou avisar que não é algo super simples, mas é totalmente possível e vai te ajudar demais, especialmente se você não quer perder tempo fazendo isso tudo na mão, todo mês.

Por que identificar licenças ociosas é importante?

Você já parou para pensar quantas licenças do Microsoft 365 sua empresa paga e que não estão sendo usadas? Isso pode representar um gasto enorme todo mês, porque essas licenças ficam ativas mesmo sem uso.

Se o financeiro souber quais licenças estão paradas, pode cancelar essas assinaturas e economizar um bom dinheiro. Além disso, ajuda na segurança, porque menos contas ativas significam menos riscos.

O poder do PowerShell para resolver isso

Com PowerShell, você pode consultar o Microsoft 365, identificar quais usuários têm licença e não acessaram nada nos últimos 90 dias (ou outro período que desejar). Depois, gerar um relatório fácil de entender, em HTML, para mostrar para o financeiro ou seu gestor.

E o melhor: você pode agendar essa verificação para rodar automaticamente, sem precisar lembrar disso todo mês.

Pré-requisitos para rodar o script

Antes de rodar o script que vou mostrar, você precisa ter:

  • Uma conta com permissões de administrador no Microsoft 365 (Azure AD).
  • PowerShell 7 ou superior instalado na sua máquina.
  • O módulo Microsoft.Graph para PowerShell instalado (o script já verifica e instala se não tiver).
  • Conexão com a internet ativa.
  • Permissão para usar o Microsoft Graph API com o escopo User.Read.All.

O script que faz isso tudo pra você

Abaixo está o script completo. Ele conecta no Microsoft 365, busca os usuários com licenças e que não acessaram os serviços nos últimos 90 dias, e cria um relatório em HTML bem organizado.

<#
.DESCRIPTION
    Script para gerar um relatório de usuários do Microsoft 365 que possuem licenças atribuídas, mas não acessaram a conta nos últimos 90 dias. 
    O relatório é gerado em formato HTML e salvo na pasta atual.
.AUTHOR
    Paulo Costa

.EXAMPLE
   .\relatorio365lic.ps1
    Executa o script para gerar o relatório de usuários inativos com licenças atribuídas.

.PREREQUISITES
    - Módulo Microsoft.Graph instalado.
    - Permissões de leitura de usuários no Microsoft Graph (User.Read.All).
    - PowerShell 7.0 ou superior recomendado.
    - Compatível com PowerShell 5.1, mas com limitações de performance.
#>

if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) {
    Write-Host "Módulo Microsoft.Graph não encontrado. Instalando..." -ForegroundColor Yellow
    Install-Module Microsoft.Graph -Scope CurrentUser -Force
}

Import-Module Microsoft.Graph

Write-Host "Conectando ao Microsoft Graph..." -ForegroundColor Cyan
Connect-MgGraph -Scopes User.Read.All

$DataCorte = (Get-Date).AddDays(-90)

Write-Host "Buscando usuários com licenças e inativos há mais de 90 dias..." -ForegroundColor Cyan

$usuarios = Get-MgUser -All -Property DisplayName, UserPrincipalName, AssignedLicenses, SignInActivity

$UsuariosInativos = $usuarios | Where-Object {
    $_.AssignedLicenses.Count -gt 0 -and (
        $_.SignInActivity.LastSignInDateTime -eq $null -or 
        [datetime]$_.SignInActivity.LastSignInDateTime -lt $DataCorte
    )
}

if ($UsuariosInativos.Count -eq 0) {
    Write-Host "Nenhum usuário inativo encontrado com licença atribuída." -ForegroundColor Green
    exit
}

$htmlReport = @"
<html>
<head>
    <title>Relatório de Licenças Microsoft 365 Inativas</title>
    <style>
        body { font-family: Arial, sans-serif; background-color:#f4f4f4; }
        table { border-collapse: collapse; width: 100%; background-color: #fff; }
        th, td { padding: 12px; border: 1px solid #ddd; text-align: left; }
        th { background-color: #0078d4; color: white; }
        tr:hover { background-color: #e1f5fe; }
    </style>
</head>
<body>
    <h2>Relatório de Licenças Microsoft 365 Inativas (mais de 90 dias)</h2>
    <p><strong>Empresa:</strong> Paulo Costa TI</p>
    <p><strong>Data:</strong> $(Get-Date -Format 'dd/MM/yyyy')</p>
    <p><strong>Gerado por:</strong> $env:USERNAME</p>
    <table>
        <tr>
            <th>Nome</th>
            <th>Email</th>
            <th>Último Login</th>
        </tr>
"@

foreach ($user in $UsuariosInativos) {
    $lastSignIn = if ($user.SignInActivity.LastSignInDateTime) {
        [datetime]$user.SignInActivity.LastSignInDateTime
    } else {
        "Nunca"
    }

    $htmlReport += @"
        <tr>
            <td>$($user.DisplayName)</td>
            <td>$($user.UserPrincipalName)</td>
            <td>$lastSignIn</td>
        </tr>
"@
}

$htmlReport += @"
    </table>
</body>
</html>
"@

$reportPath = Join-Path -Path $PWD -ChildPath "LicencasInativas_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
$htmlReport | Out-File -FilePath $reportPath -Encoding UTF8

Write-Host "Relatório gerado com sucesso em: $reportPath" -ForegroundColor Green

Exemplo do relatório:

Como usar:

  1. Abra o PowerShell 7 ou superior como administrador.
  1. Abra o PowerShell 7 ou superior como administrador.
  2. Copie e cole o script ou salve num arquivo .ps1.
  3. Execute o script. Ele vai pedir para você se conectar no Microsoft 365.
  4. Após a conexão, ele vai gerar um relatório HTML na pasta onde você rodou o script.
  5. Abra o arquivo HTML no navegador e veja as licenças que estão inativas.

Quer mais scripts prontos e dicas para automatizar seu dia a dia?

Eu tenho uma área especial no meu GitHub onde compartilho scripts PowerShell como esse e outros que vão ajudar muito no seu trabalho, te economizar horas e mostrar seu valor na empresa.

Se liga lá no meu perfil e fique de olho nas novidades. Curte, comenta, compartilha e segue para não perder nada!

Automatizar tarefas com PowerShell é um divisor de águas para quem quer crescer na área de TI e mostrar resultados concretos. Então, bora colocar a mão na massa e parar de perder tempo com tarefas repetitivas?







]]>
116
Como Gerar Relatório de Uso de Licenças no Microsoft 365 com PowerShell https://paulocostati.com.br/powershell/como-gerar-relatorio-de-uso-de-licencas-no-microsoft-365-com-powershell/?utm_source=rss&utm_medium=rss&utm_campaign=como-gerar-relatorio-de-uso-de-licencas-no-microsoft-365-com-powershell Sat, 26 Apr 2025 11:25:46 +0000 https://paulocostati.com.br/?p=105 Fala pessoal, tudo bem com vocês?

Se você trabalha administrando Microsoft 365, com certeza já passou pela situação de ter que descobrir quem está usando quais licenças — seja pra controle de custos, planejamento ou só pra entender o que realmente está sendo usado.

Esse script aqui vai salvar teu tempo (e tua paciência também rsrs).

O que esse script faz?

  • Lista todos os usuários que possuem determinadas licenças específicas
  • Mostra o nome de usuário, SKU da licença e o nome da licença
  • Exporta tudo pra um arquivo .csv bonitinho
  • Tudo automatizado, sem sofrimento

O que você precisa pra rodar?

  • Ter o módulo Microsoft.Graph instalado
  • Ter permissão pra rodar consultas com Directory.Read.All
  • Uma conta com acesso de admin no Microsoft 365

Bora lá pro código:

#
.DESCRIPTION
    Criar relatório de licenças usadas via PowerShell
#>

Install-Module -Name Microsoft.Graph -Force

Connect-MgGraph -Scopes "Directory.Read.All"

Get-MgSubscribedSku | Select-Object SkuId, SkuPartNumber

# Aqui você coloca as SKUs que quer rastrear

$skuid = @(
    "f8a1db68-be16-40ed-86d5-cb42ce701560", # POWER_BI_PRO
    "f30db892-07e9-47e9-837c-80727f46fd3d", # FLOW_FREE
    "606b54a9-78d8-4298-ad8b-df6ef4481c80", # CCIBOTS_PRIVPREV_VIRAL
    "c42b9cae-ea4f-4ab7-9717-81576235ccac", # DEVELOPERPACK_E5
    "3f9f06f5-3c31-472c-985f-62d9c10ec167", # Power_Pages_vTrial_for_Makers
    "8c4ce438-32a7-4ac5-91a6-e22ae08d9c8b", # RIGHTSMANAGEMENT_ADHOC
    "5b631642-bd26-49fe-bd20-1daaa972ef80"  # POWERAPPS_DEV
)

$users = Get-MgUser -All

$usersL= @()

foreach ($user in $users) {
    $userslicenses = Get-MgUserLicenseDetail -UserId $user.Id

    foreach ($licenca in $userslicenses) {
        if ($skuid -contains $licenca.SkuId) {
            $usersL += [PSCustomObject]@{
               Nome        = $user.UserPrincipalName
               Licenca     = $licenca.SkuId
               NomeLicenca = $licenca.SkuPartNumber
            }
        }
    }
}

$usersL | Export-Csv -Path "C:\Temp\LicencasUsuarios.csv" 

Write-Host "Relatório gerado com sucesso: C:\Temp\LicencasUsuarios.csv" -ForegroundColor Green

Disconnect-Graph

Qual a parte boa aqui?

  • Você não precisa sair catando usuário por usuário.
  • Pode rodar o script sempre que quiser atualizar o relatório.
  • O resultado vai direto pro C:\Temp\LicencasUsuarios.csv — se quiser, é só abrir no Excel.

Administrar sem automação é pedir pra sofrer, né? Script simples assim vira ouro no dia a dia.
Se curtiu, compartilha com teu time. E fica de olho aqui no blog — vem muito mais coisa útil por aí! 🚀

]]>
105