Padroneggiare PowerShell: Genera report sulle attività degli utenti di Active Directory per la gestione dell’IT

Punti chiave

  • Reportistica automatica delle attività degli utenti AD: Lo script automatizza il processo di generazione dei report sulle attività degli utenti in AD.
  • Intervallo di tempo personalizzabile: Gli utenti possono specificare il numero di giorni per il monitoraggio delle attività utilizzando il parametro -NumberOfDays.
  • Esclusione di utenti disattivati: Lo script ha un’opzione che consente di escludere gli utenti disattivati dal report per ottenere dati più precisi.
  • Facilità di integrazione: Si integra bene con l’infrastruttura IT esistente, soprattutto per gli MSP e i professionisti IT.
  • Maggiore sicurezza e conformità: Fornisce dati essenziali per gli audit di conformità e il monitoraggio della sicurezza.
  • Efficienza rispetto ai metodi manuali: Molto più efficiente dei metodi di monitoraggio manuale delle attività degli utenti.
  • Approfondimenti utili: Fornisce informazioni utili sui modelli di accesso degli utenti e sull’attività degli account.
  • Compatibilità con NinjaOne: Integra strumenti come NinjaOne, migliorando la gestione IT e le capacità di reportistica.
  • Flessibilità dello script: Offre opzioni di personalizzazione per vari ambienti e requisiti IT.


Active Directory (AD) è una colonna portante dell’infrastruttura IT aziendale, che gestisce e autentica le identità degli utenti e l’accesso alle risorse di sistema. La comprensione dell’attività degli utenti in AD è fondamentale per la sicurezza e l’efficienza. Questo ci porta all’importanza degli script PowerShell per estrarre dati significativi da AD, in particolare uno script che presenta i dati relativi agli utenti attivi in un determinato periodo di tempo.


Lo script in discussione è ideato per i professionisti IT e i fornitori di servizi gestiti (MSP) che necessitano di una visione chiara dell’attività degli utenti in AD. Si tratta di uno script PowerShell, un’efficace strumento per automatizzare le attività amministrative di Windows. Lo script genera specificamente un report che illustra il numero di utenti attivi che hanno effettuato l’accesso in un determinato periodo. Tali informazioni sono preziose per le tracce di audit, la conformità, il monitoraggio della sicurezza e la gestione degli account utente.

Lo script per generare report sulle attività degli utenti in AD:

#Requires -Version 5.1

    Generates a report for the number of active users in active directory that have logged in the specified time frame.
    Generates a report for the number of active users in active directory that have logged in the specified time frame.

    (No Parameters)
    Number of active users: 2
    Total users (including active and inactive): 5
    Percent Active: 40%

    SamAccountName UserPrincipalName   mail           LastLogonDate      
    -------------- -----------------   ----           -------------      
    kbohlander     [email protected]                6/5/2023 8:58:20 AM
    tuser          [email protected]      [email protected] 6/6/2023 8:30:23 AM

PARAMETER: -NumberOfDays "ReplaceWithAnumber"
    How long ago in days to report on.
    -NumberOfDays "1" (If today was 6/7/2023)
    Number of active users: 2
    Total users (including active and inactive): 5
    Percent Active: 40%

    SamAccountName UserPrincipalName   mail           LastLogonDate      
    -------------- -----------------   ----           -------------      
    tuser          [email protected]      [email protected] 6/6/2023 8:30:23 AM

PARAMETER: -ExcludeDisabledUsers
    Excludes the user from the report if they're currently disabled.

PARAMETER: -CustomFieldName "ReplaceMeWithAnyMultilineCustomField"
    Name of a multiline custom field to save the results to.
    -CustomFieldName "ReplaceMeWithAnyMultilineCustomField"
    Number of active users: 2
    Total users (including active and inactive): 5
    Percent Active: 40%

    SamAccountName UserPrincipalName   mail           LastLogonDate      
    -------------- -----------------   ----           -------------      
    kbohlander     [email protected]                6/5/2023 8:58:20 AM
    tuser          [email protected]      [email protected] 6/6/2023 8:30:23 AM
    Minimum OS Architecture Supported: Windows 10, Windows Server 2016
    Release Notes: Renamed script and added Script Variable support
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at
    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
    Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).

param (
    [int]$NumberOfDays = 30,
    [Switch]$ExcludeDisabledUsers = [System.Convert]::ToBoolean($env:excludeDisabledUsersFromReport)

begin {
    # Tests for administrative rights which is required to get the last logon date.
    function Test-IsElevated {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $p = New-Object System.Security.Principal.WindowsPrincipal($id)

    # Tests if the device the script is running on is a dmona controller.
    function Test-IsDomainController {
        return $(Get-CimInstance -ClassName Win32_OperatingSystem).ProductType -eq 2

    # This function is to make it easier to set Ninja Custom Fields.
    function Set-NinjaProperty {
            [Parameter(Mandatory = $True)]
            [Parameter(Mandatory = $True, ValueFromPipeline = $True)]

        # If we're requested to set the field value for a Ninja document we'll specify it here.
        $DocumentationParams = @{}
        if ($DocumentName) { $DocumentationParams["DocumentName"] = $DocumentName }

        # This is a list of valid fields we can set. If no type is given we'll assume the input doesn't have to be changed in any way.
        $ValidFields = "Attachment", "Checkbox", "Date", "Date or Date Time", "Decimal", "Dropdown", "Email", "Integer", "IP Address", "MultiLine", "MultiSelect", "Phone", "Secure", "Text", "Time", "URL"
        if ($Type -and $ValidFields -notcontains $Type) { Write-Warning "$Type is an invalid type! Please check here for valid types." }

        # The below field requires additional information in order to set
        $NeedsOptions = "Dropdown"
        if ($DocumentName) {
            if ($NeedsOptions -contains $Type) {
                # We'll redirect the error output to the success stream to make it easier to error out if nothing was found or something else went wrong.
                $NinjaPropertyOptions = Ninja-Property-Docs-Options -AttributeName $Name @DocumentationParams 2>&1
        else {
            if ($NeedsOptions -contains $Type) {
                $NinjaPropertyOptions = Ninja-Property-Options -Name $Name 2>&1

        # If we received some sort of error it should have an exception property and we'll exit the function with that error information.
        if ($NinjaPropertyOptions.Exception) { throw $NinjaPropertyOptions }

        # The below type's require values not typically given in order to be set. The below code will convert whatever we're given into a format ninjarmm-cli supports.
        switch ($Type) {
            "Checkbox" {
                # While it's highly likely we were given a value like "True" or a boolean datatype it's better to be safe than sorry.
                $NinjaValue = [System.Convert]::ToBoolean($Value)
            "Date or Date Time" {
                # Ninjarmm-cli is expecting the time to be representing as a Unix Epoch string. So we'll convert what we were given into that format.
                $Date = (Get-Date $Value).ToUniversalTime()
                $TimeSpan = New-TimeSpan (Get-Date "1970-01-01 00:00:00") $Date
                $NinjaValue = $TimeSpan.TotalSeconds
            "Dropdown" {
                # Ninjarmm-cli is expecting the guid of the option we're trying to select. So we'll match up the value we were given with a guid.
                $Options = $NinjaPropertyOptions -replace '=', ',' | ConvertFrom-Csv -Header "GUID", "Name"
                $Selection = $Options | Where-Object { $_.Name -eq $Value } | Select-Object -ExpandProperty GUID

                if (-not $Selection) {
                    throw "Value is not present in dropdown"

                $NinjaValue = $Selection
            default {
                # All the other types shouldn't require additional work on the input.
                $NinjaValue = $Value

        # We'll need to set the field differently depending on if its a field in a Ninja Document or not.
        if ($DocumentName) {
            $CustomField = Ninja-Property-Docs-Set -AttributeName $Name -AttributeValue $NinjaValue @DocumentationParams 2>&1
        else {
            $CustomField = Ninja-Property-Set -Name $Name -Value $NinjaValue 2>&1

        if ($CustomField.Exception) {
            throw $CustomField

    # Todays date
    $Today = Get-Date

    if ($env:numberOfDaysToReportOn -and $env:numberOfDaysToReportOn -notlike "null") { $NumberOfDays = $env:numberOfDaysToReportOn }
    if ($env:customFieldName -and $env:customFieldName -notlike "null") { $CustomFieldName = $env:customFieldName }
process {
    # Erroring out when ran without administrator rights
    if (-not (Test-IsElevated)) {
        Write-Error -Message "Access Denied. Please run with Administrator privileges."
        exit 1

    # Erroring out when ran on a non-domain controller
    if (-not (Test-IsDomainController)) {
        Write-Error -Message "The script needs to be run on a domain controller!"
        exit 1

    # If disabled users are to be excluded we're going to fetch different properties and Filter out disabled users
    if ($ExcludeDisabledUsers) {
        $Users = Get-ADUser -Filter * -Properties SamAccountName, UserPrincipalName, mail, LastLogonDate, Enabled | 
            Where-Object { $_.Enabled -eq $True }
        $ActiveUsers = Get-ADUser -Filter { LastLogonDate -ge 0 } -Properties SamAccountName, UserPrincipalName, mail, LastLogonDate, Enabled |
            Where-Object { (New-TimeSpan $_.LastLogonDate $Today).Days -le $NumberOfDays -and $_.Enabled -eq $True } |
            Select-Object SamAccountName, UserPrincipalName, mail, LastLogonDate
    else {
        $Users = Get-ADUser -Filter * -Properties SamAccountName, UserPrincipalName, mail, LastLogonDate
        $ActiveUsers = Get-ADUser -Filter { LastLogonDate -ge 0 } -Properties SamAccountName, UserPrincipalName, mail, LastLogonDate |
            Where-Object { (New-TimeSpan $_.LastLogonDate $Today).Days -le $NumberOfDays } |
            Select-Object SamAccountName, UserPrincipalName, mail, LastLogonDate

    # Creating a generic list to start assembling the report
    $Report = New-Object System.Collections.Generic.List[string]

    # Actual report assembly each section will be print on its own line
    $Report.Add("Active users: $(($ActiveUsers | Measure-Object).Count)")
    $Report.Add("Total users: $(($Users | Measure-Object).Count)")
    $Report.Add("Percent Active: $(if((($Users | Measure-Object).Count) -gt 0){[Math]::Round(($ActiveUsers | Measure-Object).Count / (($Users | Measure-Object).Count) * 100, 2)}else{0})%")

    # Set's up table to use in the report
    $Report.Add($($ActiveUsers | Format-Table | Out-String))

    if ($ActiveUsers) {
        # Exports report to activity log
        $Report | Write-Host

        if ($CustomFieldName) {
            # Saves report to custom field.
            try {
                Set-NinjaProperty -Name $CustomFieldName -Value ($Report | Out-String)
            catch {
                # If we ran into some sort of error we'll output it here.
                Write-Error -Message $_.ToString() -Category InvalidOperation -Exception (New-Object System.Exception)
                exit 1
    else {
        Write-Error "[Error] No active users found!"
        exit 1
end {


Accedi a oltre 700 script nel Dojo NinjaOne

Ottieni l’accesso

Analisi dettagliata

Lo script è strutturato in diverse sezioni:

  • Parametri: Accetta parametri come il numero di giorni da considerare per gli utenti attivi, il nome di un campo personalizzato per il salvataggio dei risultati e l’opzione per escludere gli utenti disattivati.
  • Preparazione: Verifica le condizioni necessarie, come i diritti amministrativi e la presenza del controller di dominio.
  • Raccolta dei dati degli utenti: Utilizza i cmdlet di Active Directory (Get-ADUser) per raccogliere i dati degli utenti in base ai parametri specificati.
  • Generazione di report: Crea un elenco e lo popola con i dati degli utenti, calcolando gli utenti attivi, gli utenti totali e la percentuale di utenti attivi.
  • Gestione degli output: Lo script visualizza il report sulla console o lo salva in un campo personalizzato utilizzando una funzione, Set-NinjaProperty.

Casi d’uso potenziali

Immagina un amministratore IT di una grande azienda che deve verificare regolarmente le attività degli utenti per garantire la conformità alla sicurezza. Potrebbe programmare l’esecuzione mensile di questo script, che fornisce una visione chiara degli accessi degli utenti, aiutando a identificare gli account inattivi o gli schemi di attività insoliti.


Altri metodi, come i controlli manuali o l’uso di strumenti basati su GUI, richiedono molto tempo e sono meno efficienti rispetto agli script PowerShell. Gli script possono essere automatizzati, personalizzati ed elaborare più velocemente grandi volumi di dati.

Domande frequenti

  • Come posso personalizzare l’asso di tempo del report?
    • Utilizza il parametro -NumberOfDays per impostare l’intervallo di tempo desiderato.
  • Lo script può escludere gli utenti disattivati?
    • Sì, utilizza l’opzione -ExcludeDisabledUsers.
  • È possibile salvare il report a scopo di documentazione?
    • Sì, utilizza il parametro -CustomFieldName per salvare il report in un campo personalizzato.


I risultati di questo script possono essere utili per identificare i rischi per la sicurezza, come gli account utente obsoleti o i modelli di login irregolari. Inoltre, contribuisce a garantire la conformità alle varie policy e normative IT.


  • Programma regolarmente lo script per generare report sulle attività degli utenti in AD per un monitoraggio costante.
  • Esegui sempre lo script con le autorizzazioni appropriate.
  • Utilizza le opzioni di personalizzazione per adattare il report alle tue esigenze specifiche.

Considerazioni finali

Nel contesto di NinjaOne, una piattaforma nota per le sue solide funzionalità di gestione IT, questo script ne completa le caratteristiche fornendo informazioni dettagliate sulle attività degli utenti in AD. È un esempio perfetto di come lo scripting PowerShell possa migliorare le funzionalità di strumenti di gestione IT completi come NinjaOne, offrendo approfondimenti e capacità di automazione.

Passi successivi

La creazione di un team IT efficiente ed efficace richiede una soluzione centralizzata che funga da principale strumento per la fornitura di servizi. NinjaOne consente ai team IT di monitorare, gestire, proteggere e supportare tutti i dispositivi, ovunque essi si trovino, senza la necessità di una complessa infrastruttura locale.

Per saperne di più su NinjaOne Endpoint Management, fai un tour dal vivo, o inizia la tua prova gratuita della piattaforma NinjaOne.


Ti potrebbe interessare anche

Guarda una demo×

Guarda NinjaOne in azione!

Inviando questo modulo, accetto La politica sulla privacy di NinjaOne.

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.