Surveiller la dernière heure du BIOS avec PowerShell pour des performances optimales du système

Dans cet article, nous allons voir comment obtenir la dernière heure du BIOS. De nos jours , l’environnement informatique évoluant rapidement, il est primordial de veiller à ce que les systèmes fonctionnent efficacement. Un aspect critique de cette efficacité est le temps de démarrage du système, souvent appelé « Last BIOS Time ».

Le contrôle et la gestion de ce temps peuvent aider les professionnels de l’informatique à optimiser les performances du système et à résoudre les problèmes plus efficacement. Ce billet de blogue se penchera sur un script PowerShell conçu pour récupérer le temps de démarrage du BIOS dans la section de démarrage du gestionnaire des tâches, et alerter les utilisateurs s’il dépasse un seuil spécifié.

Contexte

Le dernier délai du BIOS est une mesure disponible dans la section de démarrage du gestionnaire des tâches de Windows qui indique le temps nécessaire au BIOS du système pour s’initialiser au cours du processus de démarrage. Un délai plus long dans le BIOS peut indiquer des problèmes potentiels tels que des problèmes matériels ou des configurations erronées. Pour les professionnels de l’informatique et les fournisseurs de services gérés (MSP), le suivi de cette mesure peut s’avérer crucial pour maintenir la santé du système et garantir des temps de démarrage rapides.

Le script :

#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 {
    
    
    
}

 

Description détaillée

Le script PowerShell fourni est conçu pour récupérer la dernière heure du BIOS d’un système Windows et alerter l’utilisateur si elle dépasse un seuil spécifié. En outre, il peut enregistrer le résultat dans un champ personnalisé à des fins de documentation. Vous trouverez ci-dessous une explication détaillée, étape par étape, du fonctionnement du script.

Explication étape par étape

1. Définition de paramètres:

  • Le script commence par définir deux paramètres : $Seconds et $BootCustomField.
  • Le paramètre $Seconds spécifie le seuil du temps de démarrage.
  • $BootCustomField est un champ personnalisé dans lequel l’heure de démarrage peut être enregistrée.

2. Vérification des variables d’environnement :

  • Le script vérifie les variables d’environnement bootCustomField et bootTimeThreshold.
  • S’ils sont définis, ils remplacent les paramètres du script.

3. Fonction Set-NinjaProperty :

  • Cette fonction est utilisée pour définir la valeur de l’heure de démarrage dans un champ personnalisé spécifié.
  • Elle inclut la validation pour s’assurer que la valeur ne dépasse pas les limites de caractères et traite les différents types de données de manière appropriée.

4. Bloc « process » :

  • Le script récupère la dernière heure du BIOS à l’aide de plusieurs méthodes, en privilégiant la précision :
  • Journaux des événements de performance.
  • Valeurs du registre pour le temps POST du micrologiciel.
  • Les journaux d’événements du système comme solution de rechange.
  • L’heure obtenue est convertie dans un format lisible par l’homme.

5. Sorties et alertes :

  • Le script affiche la dernière heure du BIOS.
  • Si un champ personnalisé est spécifié, il définit cette valeur à l’aide de la fonction Set-NinjaProperty.
  • Si un seuil est défini, il compare le temps de démarrage à ce seuil et émet une alerte en cas de dépassement.

Cas d’utilisation potentiels

Imaginez un professionnel de l’informatique nommé Alex, qui gère un parc d’ordinateurs portables d’une entreprise. Un jour, Alex remarque que plusieurs utilisateurs signalent des temps de démarrage anormalement longs. En déployant ce script PowerShell sur le réseau, Alex peut automatiquement récupérer et surveiller la dernière heure du BIOS pour chaque système.

Si un système dépasse le seuil prédéfini, Alex est immédiatement alerté et peut mener une enquête plus approfondie, ce qui peut permettre d’identifier des problèmes matériels ou des erreurs de configuration qui doivent être résolus.

Comparaisons

D’autres méthodes permettant d’obtenir des résultats similaires peuvent inclure l’utilisation d’outils Windows intégrés ou de logiciels tiers. Cependant, ces approches manquent souvent des capacités de personnalisation et d’automatisation d’un script PowerShell. Par exemple :

  • Outils intégrés: Des outils tels que le gestionnaire des tâches peuvent afficher la dernière heure du BIOS, mais ne fournissent pas d’alertes ou d’automatisation.
  • Logiciels tiers: Bien qu’ils puissent offrir une surveillance complète, ils peuvent être plus coûteux et nécessiter une configuration supplémentaire.

FAQ

Q : Que se passe-t-il si le script ne parvient pas à récupérer la dernière heure du BIOS ?

R : Le script comprend plusieurs méthodes de secours pour s’assurer que la dernière heure du BIOS est récupérée avec précision. Si toutes les méthodes échouent, un message d’erreur est affiché.

Q : Puis-je modifier le seuil après avoir déployé le script ?

R : Oui, vous pouvez définir le seuil à l’aide du paramètre -Seconds ou en définissant la variable d’environnement bootTimeThreshold.

Q : Comment enregistrer la dernière heure du BIOS dans un champ personnalisé ?

R : Utilisez le paramètre -BootCustomField pour spécifier le champ personnalisé dans lequel l’heure de démarrage doit être enregistrée.

Implications

La surveillance de la dernière heure du BIOS peut avoir un impact significatif sur la sécurité et les performances informatiques. Un temps d’attente prolongé au BIOS peut indiquer des problèmes sous-jacents susceptibles d’affecter la stabilité globale du système et la productivité de l’utilisateur. En surveillant et en traitant ces problèmes de manière proactive, les professionnels de l’informatique peuvent maintenir des performances optimales du système et réduire les temps d’arrêt.

Recommandations

  • Surveillez régulièrement la dernière heure du BIOS à l’aide de ce script afin de détecter rapidement les problèmes potentiels.
  • Fixez des seuils réalistes basés sur les performances typiques de vos systèmes.
  • Documenter toute anomalie et enquêter rapidement pour prévenir les problèmes à long terme.

Conclusion

En conclusion, ce script PowerShell offre une solution robuste pour surveiller la dernière heure du BIOS, ce qui permet d’obtenir des informations essentielles sur les performances du système. En intégrant ce script dans vos pratiques de gestion informatique, vous pouvez garantir le bon fonctionnement et l’efficacité de vos systèmes. NinjaOne offre une suite d’outils qui peuvent encore améliorer vos opérations informatiques, en fournissant des capacités complètes de surveillance et d’automatisation pour maintenir vos systèmes en parfait état.

Pour aller plus loin

Créer une équipe informatique efficace et performante nécessite une solution centralisée qui soit l’outil principal pour fournir vos services. NinjaOne permet aux équipes informatiques de surveiller, gérer, sécuriser et prendre en charge tous les appareils, où qu’ils soient, sans avoir besoin d’une infrastructure complexe sur site.

Pour en savoir plus sur NinjaOne Endpoint Management, participez à une visite guidée ou commencez votre essai gratuit de la plateforme NinjaOne.

Catégories :

Vous pourriez aussi aimer

×

Voir NinjaOne en action !

En soumettant ce formulaire, j'accepte la politique de confidentialité de NinjaOne.

Termes et conditions NinjaOne

En cliquant sur le bouton « J’accepte » ci-dessous, vous indiquez que vous acceptez les termes juridiques suivants ainsi que nos conditions d’utilisation:

  • Droits de propriété: NinjaOne possède et continuera de posséder tous les droits, titres et intérêts relatifs au script (y compris les droits d’auteur). NinjaOne vous accorde une licence limitée pour l’utilisation du script conformément à ces conditions légales.
  • Limitation de l’utilisation: Les scripts ne peuvent être utilisés qu’à des fins personnelles ou professionnelles internes légitimes et ne peuvent être partagés avec d’autres entités.
  • Interdiction de publication: Vous n’êtes en aucun cas autorisé à publier le script dans une bibliothèque de scripts appartenant à, ou sous le contrôle d’un autre fournisseur de logiciels.
  • Clause de non-responsabilité: Le texte est fourni « tel quel » et « tel que disponible », sans garantie d’aucune sorte. NinjaOne ne promet ni ne garantit que le script sera exempt de défauts ou qu’il répondra à vos besoins ou attentes particulières.
  • Acceptation des risques: L’utilisation du script est sous votre propre responsabilité. Vous reconnaissez qu’il existe certains risques inhérents à l’utilisation du script, et vous comprenez et assumez chacun de ces risques.
  • Renonciation et exonération de responsabilité: Vous ne tiendrez pas NinjaOne pour responsable des conséquences négatives ou involontaires résultant de votre utilisation du script, et vous renoncez à tout droit ou recours légal ou équitable que vous pourriez avoir contre NinjaOne en rapport avec votre utilisation du script.
  • EULA: Si vous êtes un client de NinjaOne, votre utilisation du script est soumise au contrat de licence d’utilisateur final qui vous est applicable (End User License Agreement (EULA)).