Pontos principais
- Detecte o risco: consulte a Microsoft Graph API com PowerShell para identificar licenças do Microsoft 365 expiradas e contas do Azure AD inativas há 90 dias ou mais.
- Garanta o acesso certo: configure uma função de Administrador Global ou Leitor de Relatórios, o Microsoft Graph PowerShell SDK e as permissões User.Read.All, LicenseAssignment.ReadWrite.All e AuditLog.Read.All antes de executar as verificações.
- Exporte e arquive os resultados: salve os achados em relatórios CSV com data e hora para manter uma trilha de auditoria que sustente decisões de conformidade e de recuperação de licenças.
- Automatize a programação: execute o script de forma recorrente com o Agendador de Tarefas do Windows em uma única máquina ou distribua-o para vários endpoints e tenants por meio de uma ferramenta de RMM.
- Faça exclusões e calibre: coloque contas de serviço e contas de emergência na lista de permissões e defina limites de inatividade compatíveis com a tolerância a risco da organização.
Licenças do Microsoft 365 sem uso drenam o orçamento em silêncio, enquanto contas Azure AD inativas representam um risco real de segurança. Automatize verificações com a Microsoft Graph API para detectar licenças expiradas e contas dormentes antes que virem desperdício de dinheiro ou brechas de segurança.
Neste guia, mostramos como agendar verificações críticas via PowerShell para fechar vulnerabilidades e ganhar escala entre clientes.
Para uma visão geral rápida, assista ao nosso guia em vídeo Como executar verificações agendadas na Graph API para licenças expiradas e usuários inativos.
Procedimento passo a passo para agendar verificações na Graph API via PowerShell
Automatize as verificações na Graph API para recuperar licenças desperdiçadas, proteger contas dormentes, atender à conformidade e simplificar o gerenciamento de tenants — tudo de uma vez só.
Caso de uso: use este método em revisões mensais de custos, auditorias de segurança ou antes de renovações de licenças. É ideal para MSPs que recuperam licenças expiradas do Office 365 ou reforçam a segurança após o desligamento de funcionários. Também ajuda a identificar usuários inativos antes que se tornem vulnerabilidades no sistema.
Pré-requisitos: antes de seguir com o procedimento, verifique se você tem o seguinte:
- Permissões administrativas: confirme que sua conta tem a função de Administrador Global ou Leitor de Relatórios no Azure AD.
- Ferramentas: Microsoft Graph PowerShell SDK (módulo Microsoft.Graph) e PowerShell 7+.
- Configuração no Azure: garanta que o aplicativo do Azure AD tenha as permissões User.Read.All, LicenseAssignment.ReadWrite.All e AuditLog.Read.All para a automação.
- Opcional, mas recomendado: baixe e instale uma ferramenta de RMM como NinjaOne para agendar scripts, monitorar saídas e escalar entre tenants.
Etapa 1: instale e autentique o Microsoft Graph SDK
Monte seu kit de ferramentas para automatizar as verificações de licenças e usuários. Instalar o Graph SDK para consultar dados do Azure AD (que o administrador costuma manter ocultos) conecta o script à API da Microsoft por meio da autenticação.
Procedimento passo a passo:
- Instale o SDK executando este script no PowerShell (Admin) ou no Terminal do Windows (Admin):
Install-Module Microsoft.Graph -Scope CurrentUser -Force
- Autentique com este script:
Connect-MgGraph -Scopes "User.Read.All", "LicenseAssignment.ReadWrite.All", "AuditLog.Read.All
Também dá para configurar um aplicativo registrado com um segredo do cliente e usar o fluxo de certificado ou de credenciais do cliente para execução sem supervisão.
Depois de autenticar o Graph SDK, nas próximas etapas você poderá consultar usuários inativos do Azure AD e licenças expiradas do Office 365.
Etapa 2: consulte usuários com licenças expiradas ou não atribuídas
Esta etapa ajuda a revelar licenças expiradas e contas inativas que representam risco de segurança e custos desnecessários.
Procedimento passo a passo:
- No PowerShell (Admin), execute este script para verificar licenças não atribuídas no nível do tenant:
Get-MgSubscribedSku |Select-Object SkuPartNumber,@{Name="TotalLicenses"; Expression={$_.PrepaidUnits.Enabled}},@{Name="UsedLicenses"; Expression={$_.ConsumedUnits}},@{Name="Available"; Expression={$_.PrepaidUnits.Enabled - $_.ConsumedUnits}} |Format-Table -AutoSize
- Execute este script para encontrar usuários sem licença:
Get-MgUser -Filter "assignedLicenses/`$count eq 0" `-ConsistencyLevel eventual `-CountVariable unlicensedCount `-All |Select-Object DisplayName, UserPrincipalName |Export-Csv -Path "UnlicensedUsers.csv" -NoTypeInformation
- Execute este script para encontrar usuários inativos com licença:
$daysInactive = 90$cutoffDate = (Get-Date).AddDays(-$daysInactive)# Get licensed inactive usersGet-MgUser -All -Property "DisplayName,UserPrincipalName,SignInActivity,AssignedLicenses" |Where-Object {($_.SignInActivity.LastSignInDateTime -lt $cutoffDate) -and($_.AssignedLicenses.Count -gt 0)} |Select-Object DisplayName,UserPrincipalName,@{Name="LastSignIn"; Expression={$_.SignInActivity.LastSignInDateTime}} |Export-Csv -Path "InactiveLicensedUsers.csv" -NoTypeInformation
Importante: lembre-se de que SignInActivity exige Azure AD Premium P1/P2. Evite também endpoints beta em scripts de produção.
Depois de executar esses scripts, você terá dois arquivos CSV: UnlicensedUsers.csv, com os usuários que precisam de atribuição de licença; e InactiveLicensedUsers.csv, que lista as contas que representam risco de segurança.
Etapa 3: exporte e registre os resultados da auditoria
Com a lista de licenças expiradas e não atribuídas em mãos, transforme esses dados em informações acionáveis com relatórios automatizados. Exportar os dados cria trilhas de auditoria permanentes como prova de conformidade, e a automação garante que os problemas sejam detectados antes de ficarem caros.
Procedimento passo a passo:
- No PowerShell (Admin), execute este script para exportar para um CSV com data e hora:
- Script para gerar um nome de arquivo com data e hora:
$timestamp = Get-Date -Format "yyyyMMdd-HHmm"$reportPath = "C:\Audits\LicenseReport_$timestamp.csv"
- Exporte os usuários inativos com licença:
$inactiveUsers | Export-Csv -Path $reportPath -NoTypeInformation
- Isso gera arquivos CSV que podem ser abertos em qualquer lugar, e a marcação de data e hora cria registros versionados para fins de conformidade.
- (Opcional): execute este script para enviar os relatórios por e-mail:
Send-MailMessage -From "[email protected]" -To "[email protected]" `-Subject "ACTION REQUIRED: $($inactiveUsers.Count) Inactive Licensed Users" `-Body "Attached: Users with licenses but no sign-ins for 90+ days" `-Attachments $reportPath -SmtpServer "smtp.office365.com" -Port 587 `-Credential (Get-Credential)
- Execute este script para automatizar tudo com o aplicativo do Azure AD:
$tenantId = "YOUR_TENANT_ID"$clientId = "YOUR_CLIENT_ID"$clientSecret = "YOUR_SECRET" | ConvertTo-SecureString -AsPlainText -ForceConnect-MgGraph -TenantId $tenantId -ClientId $clientId -ClientSecret $clientSecret
Dica: armazene os segredos no Azure Key Vault. Nunca os deixe fixos no código.
Depois de executar esses scripts, você terá relatórios CSV com data e hora salvos localmente e, se quiser, alertas por e-mail enviados na hora para as partes interessadas. Esses arquivos ajudam a criar execuções automatizadas pelo Agendador de Tarefas ou por ferramentas de RMM como NinjaOne, garantindo monitoramento contínuo.
Etapa 4: automatize com o Agendador de Tarefas ou uma política de RMM
Agende o script uma vez e deixe que ele rode todo mês, todo ano ou para sempre, com monitoramento proativo sem mover um dedo. Verificações regulares ajudam a detectar problemas antes que causem dor de cabeça. Há duas opções para fazer isso:
Opção 1: pelo Agendador de Tarefas (máquina única)
Procedimento passo a passo:
- Abra o Prompt de Comando (Admin) e execute este comando:
schtasks /create /tn "M365LicenseAudit" /tr `"powershell.exe -ExecutionPolicy Bypass -File C:\Scripts\LicenseAudit.ps1" `/sc weekly /d MON /st 02:00 /ru "NT AUTHORITY\SYSTEM"
- Isso funciona porque a execução ocorre como conta do sistema, mesmo sem nenhum usuário conectado.
Opção 2: por ferramentas de RMM
Procedimento passo a passo:
- Abra sua ferramenta de RMM preferida, como NinjaOne.
- Crie o script (da Opção 1) e armazene-o na biblioteca de scripts do NinjaOne.
- Atribua o script ao grupo de políticas Microsoft 365 Clients.
- Configure as saídas:
- Salve os CSVs em \\ClientShare\Audits.
- Faça upload para o painel do RMM para visualização centralizada.
Depois de agendado, o script roda na data e hora definidas, salva automaticamente os relatórios nas pastas designadas e mostra as tendências entre os tenants.
Pontos de atenção
Esta seção destaca possíveis desafios a considerar ao seguir este guia.
| Riscos | Possíveis consequências | Como reverter |
| 1. Dados ausentes nos relatórios | Auditorias incompletas, riscos não detectados | Verifique as permissões: execute Get-MgContext para conferir escopos como User.Read.All.Contorne bloqueios de MFA: use autenticação por certificado em vez de segredos. |
| 2. O script falha em silêncio | Falsa sensação de segurança, lacunas de conformidade | Ative os logs: adicione Start-Transcript -Path C:\Logs\Audit.log aos scripts.Monitore o Visualizador de Eventos: confira em Logs de Aplicativos e Serviços > PowerShell. |
| 3. Usuários não sinalizados | Licenças expiradas/contas inativas passam despercebidas | Valide os limites: confirme se $cutoffDate está alinhado à política. Confira os campos de licença: use |
| 4. Segredos fixos no código | Comprometimento do tenant, roubo de credenciais | Faça a rotação dos segredos imediatamente no Azure AD. Migre para o Azure Key Vault: use Get-AzKeyVaultSecret para recuperar os segredos com segurança. |
| 5. Dependência de API beta | O script quebra após atualizações da Microsoft | Substitua os endpoints beta: use Get-MgUser (v1.0) em vez de Get-MgBetaUser.Assine o changelog do Microsoft Graph. |
Considerações essenciais para auditorias à prova de falhas com Graph API e PowerShell
Ajuste estas configurações conforme o seu ambiente. A precisão evita alarmes falsos e mantém os fluxos de trabalho fluindo.
Exclusões nos relatórios
Deixe contas de serviço, caixas de correio compartilhadas e contas de emergência fora das varreduras de inatividade. Isso evita recuperar por engano licenças de recursos críticos. Use filtros do PowerShell para colocá-las na lista de permissões com este script:
$excludedUPNs = @("[email protected]", "[email protected]")Get-MgUser | Where-Object { $_.UserPrincipalName -notin $excludedUPNs }
Limites de inatividade
Defina os limites conforme a sua tolerância a risco. Uma conta inativa há 90 dias é de risco baixo; 60 dias, risco médio; e 30 dias, risco alto. Conforme o risco, tome uma ação: enviar e-mails de aviso, revogar as licenças ou desativar a conta e depois recuperá-la. Assim você fica protegido contra problemas.
Frequência das auditorias
Defina bem o momento das auditorias para evitar riscos de segurança e outros problemas. Para a maioria das empresas, o recomendado são verificações mensais, alinhadas aos ciclos de faturamento.
Em setores com alta rotatividade, verificações semanais mantêm os relatórios no ritmo das mudanças do ambiente. Dispare a auditoria imediatamente a cada saída de funcionário da empresa.
Mapeamento de ações
Crie POPs que disparem os próximos passos automaticamente. Execute os scripts a seguir para recuperar licenças e desativar contas:
- Para recuperar licenças:
Set-MgUserLicense -UserId "[email protected]" -RemoveLicenses @("skuId")
- Para desativar contas:
Update-MgUser -UserId "[email protected]" -AccountEnabled:$false
Depois de executar esses scripts, arquive os dados. Encaminhe-os ao gestor ou ao SharePoint via Graph API.
Como NinjaOne simplifica suas auditorias de licenças
Transforme as verificações na Graph API de tarefas manuais em motores de conformidade totalmente automatizados e multi-tenant.
- Implantação centralizada de scripts: envie seus scripts PowerShell da Graph API para mais de 100 endpoints/tenants em uma única ação.
- Monitoramento automático das saídas: acompanhe relatórios CSV e logs de todos os clientes. Os alertas disparam na hora se os arquivos não forem atualizados.
- Alertas de falha nas suas ferramentas: receba notificações no Slack, no Teams ou por e-mail quando um script falhar.
- Relatórios unificados entre tenants: reúna dados de licenças expiradas do Office 365 e de usuários inativos em um único painel executivo.
- Remediação disparada automaticamente: crie tickets automaticamente na sua ferramenta de PSA, com POPs predefinidos, para detectar licenças expiradas.
Controle custos e segurança com verificações de licença na Graph API
Automatizar as auditorias de licenças e usuários transforma uma supervisão reativa em controle proativo. Ao recuperar licenças sem uso e desativar contas dormentes, você evita vazamentos na fatura e fecha vetores de ataque. Use o procedimento acima para converter licenças ociosas em economia de orçamento e contas paradas em conformidade.
Guia de início rápido
NinjaOne ajuda a executar verificações agendadas na Graph API para licenças expiradas e usuários inativos. A plataforma NinjaOne oferece ferramentas e orientações para:
- Auditar licenças expiradas: use a Graph API para identificar licenças que já passaram da data de expiração
- Verificar usuários inativos: detecte quem não fez login nem usou os serviços dentro de um período definido
- Automatizar essas verificações: configure tarefas agendadas para rodar as auditorias com regularidade
Temas relacionados
- 8 melhores práticas para proteger APIs
- Como alertar sobre contas de usuário inativas no Linux: um guia completo de scripts
- Automatize a detecção de contas de usuário inativas com PowerShell
- Como identificar e gerenciar contas locais sem uso em sistemas Windows
- Guia completo para desativar contas de usuário no Linux para profissionais de TI
