Monitora la durata dell’ultimo BIOS con PowerShell per ottimizzare le prestazioni del sistema

In questo articolo, discuteremo come ottenere ultima durata BIOS.  Nell’ambiente IT di oggi, caratterizzato da ritmi frenetici, è fondamentale garantire che i sistemi funzionino in modo efficiente. Un aspetto importante di questa efficienza è il tempo di avvio del sistema, spesso indicato come “Ultima durata BIOS”.

Il monitoraggio e la gestione dell’ora di avvio possono aiutare i professionisti IT a ottimizzare le prestazioni del sistema e a risolvere i problemi in modo più efficace. Il presente articolo analizzerà uno script PowerShell ideato per recuperare l’ultima durata BIOS dalla sezione di avvio del task manager, avvisando gli utenti se supera una soglia specificata.

Background

L’ultima durata BIOS è una metrica disponibile nella sezione di avvio del Task Manager di Windows che indica il tempo necessario per l’inizializzazione del BIOS del sistema durante il processo di avvio. Un tempo più lungo del BIOS può indicare potenziali problemi, come problemi hardware o configurazioni errate. Per i professionisti IT e i Managed Service Provider (MSP), tenere traccia di questa metrica può essere fondamentale per mantenere l’integità del sistema e garantire tempi di avvio rapidi.

Lo script per ottenere ultima durata BIOS:

#Requires -Version 5.1

<#
.SYNOPSIS
    Gets the Last BIOS time from the startup section of task manager and alerts if it exceeds a threshold you specify.
.DESCRIPTION
    Gets the Last BIOS time from the startup section of task manager and alerts if it exceeds a threshold you specify.
    Can save the result to a custom field.

.EXAMPLE
    (No Parameters)
    ## EXAMPLE OUTPUT WITHOUT PARAMS ##
    Last BIOS Time: 14.6s

PARAMETER: -BootCustomField "BootTime"
    Saves the boot time to this Text Custom Field.
.EXAMPLE
    -BootCustomField "BootTime"
    ## EXAMPLE OUTPUT WITH BootCustomField ##
    Last BIOS Time: 14.6s

PARAMETER: -Seconds 20
    Sets the threshold for when the boot time is greater than this number.
    In this case the boot time is over the threshold.
.EXAMPLE
    -Seconds 20
    ## EXAMPLE OUTPUT WITH Seconds ##
    Last BIOS Time: 14.6s
    [Error] Boot time exceeded threshold of 20s by 5.41s. Boot time: 14.6s

PARAMETER: -Seconds 10
    Sets the threshold for when the boot time is greater than this number.
    In this case the boot time is under the threshold.
.EXAMPLE
    -Seconds 10
    ## EXAMPLE OUTPUT WITH Seconds ##
    Last BIOS Time: 14.6s
    [Info] Boot time under threshold of 10s by 4.59s. Boot time: 14.6s

.OUTPUTS
    String
.NOTES
    Minimum OS Architecture Supported: Windows 10, Windows Server 2016
    Release Notes: Initial Release
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
    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).
#>

[CmdletBinding()]
param (
    $Seconds,
    [String]$BootCustomField
)

begin {
    if ($env:bootCustomField -and $env:bootCustomField -notlike "null") {
        $BootCustomField = $env:bootCustomField
    }
    if ($env:bootTimeThreshold -and $env:bootTimeThreshold -notlike "null") {
        # Remove any non digits
        [double]$Seconds = $env:bootTimeThreshold -replace '[^0-9.]+'
    }
    function Set-NinjaProperty {
        [CmdletBinding()]
        Param(
            [Parameter(Mandatory = $True)]
            [String]$Name,
            [Parameter()]
            [String]$Type,
            [Parameter(Mandatory = $True, ValueFromPipeline = $True)]
            $Value,
            [Parameter()]
            [String]$DocumentName
        )
    
        $Characters = $Value | Measure-Object -Character | Select-Object -ExpandProperty Characters
        if ($Characters -ge 10000) {
            throw [System.ArgumentOutOfRangeException]::New("Character limit exceeded, value is greater than 10,000 characters.")
        }
        
        # 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 that can be set. If no type is given, it will be assumed that the input doesn't need to be changed.
        $ValidFields = "Attachment", "Checkbox", "Date", "Date or Date Time", "Decimal", "Dropdown", "Email", "Integer", "IP Address", "MultiLine", "MultiSelect", "Phone", "Secure", "Text", "Time", "URL", "WYSIWYG"
        if ($Type -and $ValidFields -notcontains $Type) { Write-Warning "$Type is an invalid type! Please check here for valid types. https://ninjarmm.zendesk.com/hc/en-us/articles/16973443979789-Command-Line-Interface-CLI-Supported-Fields-and-Functionality" }
        
        # The field below requires additional information to be 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 an error is received it will have an exception property, the function will exit 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 expects the GUID of the option to be selected. Therefore, the given value will be matched with a GUID.
                $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 [System.ArgumentOutOfRangeException]::New("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
        }
    }
}
process {
    $Ticks = try {
        # Get boot time from performance event logs
        $PerfTicks = Get-WinEvent -FilterHashtable @{LogName = "Microsoft-Windows-Diagnostics-Performance/Operational"; Id = 100 } -MaxEvents 1 -ErrorAction SilentlyContinue | ForEach-Object {
            # Convert the event to XML and grab the Event node
            $eventXml = ([xml]$_.ToXml()).Event
            # Output boot time in ms
            [int64]($eventXml.EventData.Data | Where-Object { $_.Name -eq 'BootTime' }).InnerXml
        }
        # Get the boot POST time from the firmware, when available
        $FirmwareTicks = Get-ItemPropertyValue -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power" -Name "FwPOSTTime" -ErrorAction SilentlyContinue
        # Get the boot POST time from Windows, used as fall back
        $OsTicks = Get-ItemPropertyValue -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power" -Name "POSTTime" -ErrorAction SilentlyContinue
        # Use most likely to be accurate to least accurate
        if ($FirmwareTicks -gt 0) {
            $FirmwareTicks
        }
        elseif ($OsTicks -gt 0) {
            $OsTicks
        }
        elseif ($PerfTicks -and $PerfTicks -gt 0) {
            $PerfTicks
        }
        else {
            # Fall back to reading System event logs
            $StartOfBoot = Get-WinEvent -FilterHashtable @{LogName = 'System'; Id = 12 } -MaxEvents 1 | Select-Object -ExpandProperty TimeCreated
            $LastUpTime = Get-WmiObject Win32_OperatingSystem -ErrorAction Stop | Select-Object @{Label = 'LastBootUpTime'; Expression = { $_.ConvertToDateTime($_.LastBootUpTime) } } | Select-Object -ExpandProperty LastBootUpTime
            New-TimeSpan -Start $LastUpTime -End $StartOfBoot -ErrorAction Stop | Select-Object -ExpandProperty TotalMilliseconds
        }
    }
    catch {
        Write-Host "[Error] Failed to get Last BIOS Time from registry."
        exit 2
    }

    $TimeSpan = [TimeSpan]::FromMilliseconds($Ticks)

    $BootTime = if ($TimeSpan.Days -gt 0) {
        "$($TimeSpan.Days)d, $($TimeSpan.Hours)h, $($TimeSpan.Minutes)m, $($TimeSpan.Seconds + [Math]::Round($TimeSpan.Milliseconds / 1000, 1))s"
    }
    elseif ($TimeSpan.Hours -gt 0) {
        "$($TimeSpan.Hours)h, $($TimeSpan.Minutes)m, $($TimeSpan.Seconds + [Math]::Round($TimeSpan.Milliseconds / 1000, 1))s"
    }
    elseif ($TimeSpan.Minutes -gt 0) {
        "$($TimeSpan.Minutes)m, $($TimeSpan.Seconds + [Math]::Round($TimeSpan.Milliseconds / 1000, 1))s"
    }
    elseif ($TimeSpan.Seconds -gt 0) {
        "$($TimeSpan.Seconds + [Math]::Round($TimeSpan.Milliseconds / 1000, 1))s"
    }
    else {
        # Fail safe output
        "$($TimeSpan.Days)d, $($TimeSpan.Hours)h, $($TimeSpan.Minutes)m, $($TimeSpan.Seconds + [Math]::Round($TimeSpan.Milliseconds / 1000, 1))s"
    }

    Write-Host "Last BIOS Time: $BootTime"

    if ($BootCustomField) {
        Set-NinjaProperty -Name $BootCustomField -Type Text -Value $BootTime
    }

    if ($Seconds -gt 0) {
        if ($TimeSpan.TotalSeconds -gt $Seconds) {
            Write-Host "[Error] Boot time exceeded threshold of $($Seconds)s by $($TimeSpan.TotalSeconds - $Seconds)s. Boot time: $BootTime"
            exit 1
        }
        Write-Host "[Info] Boot time under threshold of $($Seconds)s by $($Seconds - $TimeSpan.TotalSeconds)s. Boot time: $BootTime"
    }
    exit 0
}
end {
    
    
    
}

 

Analisi dettagliata

Lo script PowerShell fornito è progettato per recuperare l’ultima durata BIOS da un sistema Windows e avvisare l’utente se supera una soglia specificata. Inoltre, può salvare il risultato in un campo personalizzato per la documentazione. Di seguito è riportata una spiegazione dettagliata, passo dopo passo, di come funziona lo script.

Spiegazione passo per passo

1. Definizione dei parametri:

  • Lo script inizia definendo due parametri: $Seconds e $BootCustomField.
  • $Secondi specifica la soglia per il tempo di avvio.
  • $BootCustomField è un campo personalizzato in cui è possibile salvare l’ora di avvio.

2. Controllo delle variabili d’ambiente:

  • Lo script controlla le variabili d’ambiente bootCustomField e bootTimeThreshold.
  • Se questi sono impostati, sovrascrivono i parametri dello script.

3. Funzione Set-NinjaProperty:

  • Questa funzione viene utilizzata per impostare il valore dell’ora di avvio su un campo personalizzato specificato.
  • Include la convalida per garantire che il valore non superi i limiti di caratteri e gestisce in modo appropriato i diversi tipi di dati.

4. Blocco del processo:

  • Lo script recupera l’ultima durata BIOS utilizzando diversi metodi, dando priorità alla precisione.
  • Registri eventi relativi alle prestazioni.
  • Valori di registro per il tempo di POST firmware.
  • Registri eventi di sistema come soluzione di ripiego.
  • L’ora recuperata viene convertita in un formato leggibile dall’uomo.

5. Output e avvisi:

  • Lo script fornisce l’ultima durata BIOS.
  • Se viene specificato un campo personalizzato, lo script imposta questo valore utilizzando la funzione Set-NinjaProperty.
  • Se è impostata una soglia, confronta il tempo di avvio con questa soglia e avvisa se viene superata.

Casi d’uso potenziali

Immagina un professionista IT di nome Alex, che gestisce un parco di computer portatili aziendali. Un giorno, Alex nota che diversi utenti segnalano tempi di avvio insolitamente lunghi. Distribuendo questo script PowerShell sulla rete, Alex può recuperare e monitorare automaticamente l’ultima durata BIOS per ogni sistema.

Se un sistema supera la soglia predefinita, Alex viene immediatamente avvisato e può indagare ulteriormente, identificando potenziali problemi hardware o configurazioni errate che devono essere risolti.

Confronti

Altri metodi per ottenere risultati simili possono essere l’utilizzo di strumenti integrati in Windows o di software di terze parti. Tuttavia, questi approcci spesso mancano delle capacità di personalizzazione e automazione di uno script PowerShell. Per esempio:

  • Strumenti integrati: Strumenti come Task Manager possono mostrare l’ultima durata BIOS, ma non forniscono avvisi o automazione.
  • Software di terze parti: Sebbene possano offrire un monitoraggio completo, possono avere un costo maggiore e richiedere una configurazione aggiuntiva.

Domande frequenti

D: Cosa succede se lo script non riesce a recuperare l’ultima durata BIOS?

R: Lo script include diversi metodi di fallback per garantire il recupero accurato dell’ultima durata BIOS. Se tutti i metodi falliscono, viene emesso un messaggio di errore.

D: Posso modificare la soglia dopo aver distribuito lo script?

R: Sì, è possibile impostare la soglia utilizzando il parametro -Secondsparameter o impostando la variabile d’ambiente bootTimeThreshold.

D: Come si salva l’ultima durata BIOS in un campo personalizzato?

R: Utilizza il parametro -BootCustomField per specificare il campo personalizzato in cui salvare l’ora di avvio.

Implicazioni

Il monitoraggio dell’ultima durata BIOS può avere un impatto significativo sulla sicurezza IT e sulle prestazioni IT. Una durata prolungata del BIOS potrebbe indicare problemi di fondo che incidono sulla stabilità generale del sistema e sulla produttività dell’utente. Monitorando e risolvendo in modo proattivo questi problemi, i professionisti IT possono mantenere le prestazioni ottimali del sistema e ridurre i tempi di inattività.

Raccomandazioni

  • Monitora regolarmente l’ultima durata BIOS utilizzando questo script per individuare tempestivamente potenziali problemi.
  • Imposta soglie realistiche basate sulle prestazioni tipiche dei tuoi sistemi.
  • Documenta qualsiasi anomalia e indaga tempestivamente per evitare problemi a lungo termine.

Considerazioni finali

In conclusione, questo script PowerShell offre una soluzione robusta per il monitoraggio dell’ultima durata BIOS, fornendo informazioni essenziali sulle prestazioni del sistema. Integrando questo script nelle tue pratiche di gestione IT, potrai garantire che i sistemi funzionino in modo fluido ed efficiente. NinjaOne offre un set di strumenti in grado di migliorare ulteriormente le tue operazioni IT, fornendo funzionalità complete di monitoraggio e automazione per mantenere i sistemi in perfetta forma.

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.

Categorie:

Ti potrebbe interessare anche

×

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.