/
/

Come eseguire controlli Graph API pianificati per licenze scadute e utenti inattivi

di Team Ninja
How to Run Scheduled Graph API Checks for Expired Licenses and Inactive Users blog banner image

Riepilogo

Questo post del blog NinjaOne offre un elenco completo di comandi CMD di base e un’analisi approfondita dei comandi di Windows con oltre 70 comandi cmd essenziali sia per i principianti che per gli utenti avanzati. La guida si propone si piegare in modo pratico i comandi del prompt dei comandi per la gestione dei file, la navigazione nelle directory, la risoluzione dei problemi di rete, le operazioni su disco e l’automazione, con esempi reali per migliorare la produttività. Che tu voglia imparare i comandi cmd fondamentali o padroneggiare gli strumenti avanzati della CLI di Windows, questa guida ti aiuterà a utilizzare il Prompt dei comandi in modo più efficace.

Punti chiave

  • Individua il rischio: interroga la Microsoft Graph API con PowerShell per identificare le licenze Microsoft 365 scadute e gli account Azure AD inattivi da oltre 90 giorni.
  • Prevedi gli accessi corretti: configura un ruolo Amministratore globale o Lettore di report, il Microsoft Graph PowerShell SDK e le autorizzazioni User.Read.All, LicenseAssignment.ReadWrite.All e AuditLog.Read.All prima di eseguire i controlli.
  • Esporta e archivia i risultati: salva i dati raccolti in report CSV con marca temporale per mantenere una traccia di audit utile alla conformità e alle decisioni di recupero delle licenze.
  • Automatizza la pianificazione: esegui lo script a intervalli regolari con l’Utilità di pianificazione di Windows su una singola macchina, oppure distribuiscilo su più endpoint e tenant tramite uno strumento RMM.
  • Escludi e calibra: inserisci in whitelist gli account di servizio e quelli di emergenza (break-glass) e imposta soglie di inattività coerenti con la tolleranza al rischio della tua organizzazione.

Le licenze Microsoft 365 inutilizzate erodono silenziosamente il budget, mentre gli account Azure AD inattivi rappresentano un rischio concreto per la sicurezza. Automatizza i controlli con la Microsoft Graph API per individuare licenze scadute e account dormienti prima che si traducano in spese inutili o falle di sicurezza.

In questa guida ti mostriamo come pianificare controlli critici tramite PowerShell per chiudere le vulnerabilità e scalare su più clienti.

Per una panoramica visiva rapida, guarda la nostra video guida su Come eseguire controlli Graph API pianificati per licenze scadute e utenti inattivi.

Procedura passo passo per pianificare i controlli Graph API con PowerShell

Automatizza i controlli Graph API per recuperare le licenze sprecate, mettere in sicurezza gli account dormienti, rispettare la conformità e semplificare la gestione dei tenant: tutto in un’unica passata.

Situazione d’uso: usa questo metodo durante le revisioni mensili dei costi, gli audit di sicurezza o prima dei rinnovi delle licenze. È ideale per gli MSP che recuperano licenze Office 365 scadute o che applicano l’hardening della sicurezza dopo l’offboarding di un dipendente. Ti aiuta inoltre a individuare gli utenti inattivi prima che diventino vulnerabilità per il tuo sistema.

Prerequisiti: prima di procedere con la procedura, assicurati di avere quanto segue:

  • Autorizzazioni amministrative: verifica che il tuo account disponga del ruolo Amministratore globale o Lettore di report in Azure AD.
  • Strumenti: Microsoft Graph PowerShell SDK (modulo Microsoft.Graph) e PowerShell 7+.
  • Configurazione di Azure: assicurati che la tua app Azure AD disponga delle autorizzazioni User.Read.All, LicenseAssignment.ReadWrite.All e AuditLog.Read.All per l’automazione.
  • Facoltativo ma consigliato: scarica e installa uno strumento RMM come NinjaOne per pianificare gli script, monitorarne gli output e scalare su più tenant.

Passaggio 1: installa e autentica il Microsoft Graph SDK

Prepara gli strumenti necessari per automatizzare i controlli su licenze e utenti. L’installazione del Graph SDK, che consente di interrogare i dati di Azure AD normalmente nascosti dall’amministratore, collega il tuo script all’API di Microsoft tramite autenticazione.

Procedura passo passo:

  1. Installa l’SDK eseguendo questo script in PowerShell (Admin) o Windows Terminal (Admin):

Install-Module Microsoft.Graph -Scope CurrentUser -Force

  1. Autenticati con questo script:

Connect-MgGraph -Scopes "User.Read.All", "LicenseAssignment.ReadWrite.All", "AuditLog.Read.All

Puoi anche configurare un’app registrata con un client secret e usare il flusso con certificato o con credenziali client per l’esecuzione non presidiata.

Una volta autenticato il Graph SDK, nei passaggi successivi potrai interrogare gli utenti Azure AD inattivi e le licenze Office 365 scadute.

Passaggio 2: individua gli utenti con licenze scadute o non assegnate

Questo passaggio ti aiuta a far emergere licenze scadute e account inattivi che comportano rischi per la sicurezza e costi superflui.

Procedura passo passo:

  1. In PowerShell (Admin), esegui questo script per verificare le licenze non assegnate a livello di tenant:

Get-MgSubscribedSku |
Select-Object SkuPartNumber,
@{Name="TotalLicenses"; Expression={$_.PrepaidUnits.Enabled}},
@{Name="UsedLicenses"; Expression={$_.ConsumedUnits}},
@{Name="Available"; Expression={$_.PrepaidUnits.Enabled - $_.ConsumedUnits}} |
Format-Table -AutoSize

  1. Esegui questo script per trovare gli utenti senza licenza:

Get-MgUser -Filter "assignedLicenses/`$count eq 0" `
-ConsistencyLevel eventual `
-CountVariable unlicensedCount `
-All |
Select-Object DisplayName, UserPrincipalName |
Export-Csv -Path "UnlicensedUsers.csv" -NoTypeInformation

  1. Esegui questo script per trovare gli utenti inattivi con licenza:

$daysInactive = 90
$cutoffDate = (Get-Date).AddDays(-$daysInactive)# Get licensed inactive users
Get-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: tieni presente che SignInActivity richiede Azure AD Premium P1/P2. Evita inoltre gli endpoint beta negli script di produzione.

Dopo aver eseguito questi script otterrai due file CSV: UnlicensedUsers.csv, che contiene gli utenti a cui assegnare una licenza, e InactiveLicensedUsers.csv, che elenca gli account che costituiscono un rischio per la sicurezza.

Passaggio 3: esporta e registra i risultati dell’audit

Una volta ottenuto l’elenco delle licenze scadute e non assegnate, trasforma questi dati in informazioni utili con un reporting automatizzato. L’esportazione crea tracce di audit permanenti a prova di conformità e l’automazione ti garantisce di intercettare i problemi prima che diventino costosi.

Procedura passo passo:

  1. In PowerShell (Admin), esegui questo script per esportare in un CSV con marca temporale:
    • Script per generare un nome file con marca temporale:

$timestamp = Get-Date -Format "yyyyMMdd-HHmm"
$reportPath = "C:\Audits\LicenseReport_$timestamp.csv"

    • Esporta gli utenti inattivi con licenza:

$inactiveUsers | Export-Csv -Path $reportPath -NoTypeInformation

    • In questo modo otterrai file CSV apribili ovunque e la marca temporale creerà record versionati ai fini della conformità.
  1. (Facoltativo): esegui questo script per inviare i report via email:

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)

  1. Esegui questo script per automatizzare completamente il processo con l’app Azure AD:

$tenantId = "YOUR_TENANT_ID"
$clientId = "YOUR_CLIENT_ID"
$clientSecret = "YOUR_SECRET" | ConvertTo-SecureString -AsPlainText -ForceConnect-MgGraph -TenantId $tenantId -ClientId $clientId -ClientSecret $clientSecret

Suggerimento: conserva i segreti in Azure Key Vault. Non inserirli mai direttamente nel codice.

Dopo aver eseguito questi script avrai report CSV con marca temporale salvati in locale e, se vuoi, avvisi via email immediati per le parti interessate. Questi file ti permettono di impostare esecuzioni automatizzate tramite l’Utilità di pianificazione o strumenti RMM come NinjaOne, così da garantire un monitoraggio continuo.

Passaggio 4: automatizza con l’Utilità di pianificazione o una policy RMM

Pianifica lo script una sola volta e lascialo girare ogni mese, ogni anno o all’infinito: avrai un monitoraggio proattivo senza muovere un dito. Controlli regolari aiutano a intercettare le anomalie prima che diventino problemi. Ci sono due modi per farlo:

Opzione 1: con l’Utilità di pianificazione (singola macchina)

Procedura passo passo:

  1. Apri il Prompt dei comandi (Admin), quindi esegui questo 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"

    • Questo approccio funziona perché l’esecuzione avviene con un account di sistema anche quando nessun utente ha effettuato l’accesso.

Opzione 2: con strumenti RMM

Procedura passo passo:

  1. Apri lo strumento RMM che preferisci, ad esempio NinjaOne.
  2. Crea lo script (quello dell’Opzione 1) e salvalo nella libreria di script di NinjaOne.
  3. Assegna lo script al gruppo di policy Microsoft 365 Clients.
  4. Configura gli output:
    • Salva i CSV in \\ClientShare\Audits.
    • Caricali nella dashboard dell’RMM per una visualizzazione centralizzata.

Una volta pianificato, lo script verrà eseguito nella data e nell’ora assegnate, salvando automaticamente i report nelle cartelle designate e mostrando gli andamenti tra i vari tenant.

Aspetti a cui prestare attenzione

Questa sezione evidenzia le possibili difficoltà da tenere a mente mentre segui la guida.

Rischi Possibili conseguenze Rimedi
1. Dati mancanti nei report Audit incompleti, rischi non rilevati Controlla le autorizzazioni: esegui Get-MgContext per verificare ambiti come User.Read.All.

Aggira i blocchi MFA: usa l’autenticazione con certificato invece dei segreti.

2. Lo script fallisce senza segnalarlo Falso senso di sicurezza, lacune di conformità Attiva la registrazione: aggiungi Start-Transcript -Path C:\Logs\Audit.log agli script.

Monitora il Visualizzatore eventi: controlla in Registri applicazioni e servizi > PowerShell.

3. Utenti non segnalati Licenze scadute/account inattivi non rilevati Verifica le soglie: conferma che $cutoffDate sia coerente con la policy.

Verifica i campi delle licenze: usa Get-MgUser -UserId [email protected] -Property AssignedLicenses.

4. Segreti inseriti direttamente nel codice Compromissione del tenant, furto di credenziali Ruota subito i segreti in Azure AD.

Passa ad Azure Key Vault: usa Get-AzKeyVaultSecret per recuperare i segreti in modo sicuro.

5. Dipendenza dalle API beta Lo script smette di funzionare dopo gli aggiornamenti Microsoft Sostituisci gli endpoint beta: usa Get-MgUser (v1.0) al posto di Get-MgBetaUser.

Iscriviti al changelog di Microsoft Graph.

Considerazioni chiave per audit PowerShell con Graph API a prova di errore

Adatta queste impostazioni al tuo ambiente. La precisione evita i falsi allarmi e mantiene fluidi i flussi di lavoro.

Esclusioni dai report

Escludi dalle scansioni di inattività gli account di servizio, le cassette postali condivise e gli account di emergenza (break-glass). In questo modo eviti di recuperare per errore licenze legate a risorse critiche. Puoi inserirli in whitelist con i filtri di PowerShell, usando questo script:

$excludedUPNs = @("[email protected]", "[email protected]")
Get-MgUser | Where-Object { $_.UserPrincipalName -notin $excludedUPNs }

Soglie di inattività

Imposta le soglie in base alla tua tolleranza al rischio. Un account inattivo da 90 giorni è a rischio basso, 60 giorni corrispondono a un rischio medio e 30 giorni a un rischio elevato. In base al livello di rischio puoi intervenire inviando email di avviso, revocando le licenze oppure disabilitando l’account e recuperando la licenza. Così resti al riparo dai problemi.

Frequenza degli audit

Scegli il momento giusto per gli audit, così da evitare rischi di sicurezza e altri inconvenienti. Per la maggior parte delle aziende si consigliano controlli mensili, allineati ai cicli di fatturazione.

Nei settori con un ricambio elevato, controlli settimanali permettono ai report di stare al passo con i cambiamenti dell’ambiente. È inoltre opportuno avviare subito un audit a ogni uscita di un dipendente dall’azienda.

Mappatura delle azioni

Crea procedure operative standard che attivino automaticamente i passaggi successivi. Esegui gli script seguenti per recuperare le licenze e disabilitare gli account:

  • Per recuperare le licenze:

Set-MgUserLicense -UserId "[email protected]" -RemoveLicenses @("skuId")

  • Per disabilitare gli account:

Update-MgUser -UserId "[email protected]" -AccountEnabled:$false

Dopo aver eseguito questi script, archivia i dati. Inoltrali al responsabile o a SharePoint tramite la Graph API.

Come NinjaOne semplifica gli audit delle licenze

Trasforma i controlli Graph API da attività manuali a motori di conformità completamente automatizzati e multi-tenant.

  • Distribuzione centralizzata degli script: invia i tuoi script PowerShell per la Graph API a oltre 100 endpoint/tenant con una sola operazione.
  • Monitoraggio automatico degli output: tieni traccia di report CSV e log su tutti i clienti. Gli avvisi scattano all’istante se i file non si aggiornano.
  • Avvisi di errore nei tuoi strumenti: ricevi notifiche su Slack, Teams o via email quando uno script fallisce.
  • Report unificati su più tenant: unisci i dati su licenze Office 365 scadute e utenti inattivi in un’unica dashboard per la direzione.
  • Remediation automatica: crea automaticamente ticket nel tuo strumento PSA usando procedure operative standard predefinite per rilevare le licenze scadute.

Tieni sotto controllo costi e sicurezza con i controlli delle licenze via Graph API

Automatizzare gli audit di licenze e utenti trasforma una supervisione reattiva in un controllo proattivo. Recuperando le licenze inutilizzate e disabilitando gli account dormienti, eviti perdite di budget e chiudi possibili vettori di attacco. Segui la procedura descritta sopra per convertire le licenze inutilizzate in risparmio e gli account obsoleti in conformità.

Guida rapida

NinjaOne ti aiuta a eseguire controlli Graph API pianificati per licenze scadute e utenti inattivi. La piattaforma NinjaOne offre strumenti e indicazioni per:

  • Verificare le licenze scadute: usa la Graph API per individuare le licenze che hanno superato la data di scadenza
  • Controllare gli utenti inattivi: individua gli utenti che non hanno effettuato l’accesso o utilizzato i servizi entro un periodo definito
  • Automatizzare questi controlli: imposta attività pianificate per eseguire regolarmente questi audit

Argomenti correlati

FAQs

Ti serve il ruolo Amministratore globale o Lettore di report in Azure AD, insieme al Microsoft Graph PowerShell SDK e a PowerShell 7 o versioni successive. Anche la registrazione dell’app Azure AD deve disporre delle autorizzazioni User.Read.All, LicenseAssignment.ReadWrite.All e AuditLog.Read.All.

La maggior parte delle organizzazioni esegue questi controlli ogni mese per allinearsi ai cicli di fatturazione, mentre i settori con un ricambio elevato traggono vantaggio da controlli settimanali. Avvia un audit immediatamente dopo l’uscita di un dipendente dall’azienda.

Sì. Usa un filtro PowerShell per inserire in whitelist account di servizio, cassette postali condivise e account di emergenza (break-glass) in base al loro user principal name, così non verranno segnalati né disabilitati per errore.

L’Utilità di pianificazione è adatta a una singola macchina o a un singolo tenant. Uno strumento RMM come NinjaOne può distribuire lo stesso script su molti endpoint e tenant, centralizzare gli output e avvisarti quando un’esecuzione non va a buon fine.

Ti potrebbe interessare anche

Pronto a semplificare le parti più complesse dell'IT?

Termini e condizioni NinjaOne

Cliccando sul pulsante “Accetto” qui sotto, dichiari di accettare i seguenti termini legali e le nostre condizioni d’uso:

  • Diritti di proprietà: NinjaOne possiede e continuerà a possedere tutti i diritti, i titoli e gli interessi relativi allo script (compreso il copyright). NinjaOne ti concede una licenza limitata per l’utilizzo dello script in conformità con i presenti termini legali.
  • Limitazione d’uso: Puoi utilizzare lo script solo per legittimi scopi personali o aziendali interni e non puoi condividere lo script con altri soggetti.
  • Divieto di ripubblicazione: In nessun caso ti è consentito ripubblicare lo script in una libreria di script appartenente o sotto il controllo di un altro fornitore di software.
  • Esclusione di garanzia: Lo script viene fornito “così com’è” e “come disponibile”, senza garanzie di alcun tipo. NinjaOne non promette né garantisce che lo script sia privo di difetti o che soddisfi le tue esigenze o aspettative specifiche.
  • Assunzione del rischio: L’uso che farai dello script è da intendersi a tuo rischio. Riconosci che l’utilizzo dello script comporta alcuni rischi intrinseci, che comprendi e sei pronto ad assumerti.
  • Rinuncia e liberatoria: Non riterrai NinjaOne responsabile di eventuali conseguenze negative o indesiderate derivanti dall’uso dello script e rinuncerai a qualsiasi diritto legale o di equità e a qualsiasi rivalsa nei confronti di NinjaOne in relazione all’uso dello script.
  • EULA: Se sei un cliente NinjaOne, l’uso dello script è soggetto al Contratto di licenza con l’utente finale (EULA) applicabile.