Pour les professionnels de l’informatique et les fournisseurs de services gérés (MSP), il est essentiel de connaître la stabilité des systèmes. Le suivi de la fiabilité au fil du temps permet une maintenance proactive du système, une analyse des tendances et de meilleurs résultats en matière d’assistance. Un outil sous-utilisé mais puissant à cet effet est l’indice de fiabilité de Windows, qui fournit un score de stabilité quantifiable basé sur les journaux d’événements. Cet article explique comment créer un rapport sur l’indice de fiabilité Windows avec PowerShell, ce qui vous permet d’évaluer, d’enregistrer et même de publier ces scores par le biais de champs personnalisés dans une plateforme telle que NinjaOne.
Contexte
L’indice de fiabilité de Windows existe depuis Windows Vista et continue d’être une mesure utile pour déterminer l’état général du système. Il analyse les événements critiques tels que les pannes d’application, les défaillances matérielles et les mises à jour de Windows, et attribue une note de stabilité quotidienne allant de 1 (instable) à 10 (très stable).
Malgré son utilité, il n’existe pas d’automatisation intégrée permettant de récupérer et d’afficher ces valeurs dans un format de rapport convivial, surtout s’il est intégré à une plateforme de gestion des terminaux. C’est là que ce script intervient. Conçu pour les environnements utilisant PowerShell 5.1 et NinjaOne, le script automatise la récupération, le formatage et la publication optionnelle des données de l’indice de fiabilité dans des champs personnalisés, offrant ainsi une visibilité immédiate et un suivi à long terme.
Le script
#Requires -Version 5.1
<#
.SYNOPSIS
Returns the last score and a daily average report of the Windows Reliability Index.
.DESCRIPTION
Returns the last score and a daily average report of the Windows Reliability Index.
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).
.EXAMPLE
(No Parameters)
[Info] Retrieving reliability index information for SRV19-TEST.
[Info] Successfully retrieved reliability index information!
[Info] Latest reliability index score for SRV19-TEST:
2/19/2025 1:00:00 PM | 6.835
[Info] Table of daily averages:
Date Average Reliability Index
---- -------------------------
2/19/2025 8.26
2/18/2025 10
2/17/2025 10
2/16/2025 10
2/15/2025 10
2/14/2025 10
2/13/2025 10
2/12/2025 10
2/11/2025 10
2/10/2025 10
2/9/2025 10
2/8/2025 10
2/7/2025 10
2/6/2025 10
2/5/2025 10
2/4/2025 10
2/3/2025 10
2/2/2025 10
2/1/2025 10
1/31/2025 10
1/30/2025 10
1/29/2025 10
1/28/2025 10
1/27/2025 10
1/26/2025 10
1/25/2025 10
1/24/2025 10
1/23/2025 10
1/22/2025 10
1/21/2025 10
1/20/2025 10
1/19/2025 10
.PARAMETER -WYSIWYGCustomFieldName "ReplaceMeWithAnyWYSIWYGCustomField"
Name of the WYSIWYG custom field to populate with the report.
.EXAMPLE
-WYSIWYGCustomFieldName "ExampleInput"
[Info] Retrieving reliability index information for SRV19-TEST.
[Info] Successfully retrieved reliability index information!
[Info] Retrieving current value of WYSIWYG Custom Field 'WYSIWYG'.
[Info] Successfully retrieved the current value of 'WYSIWYG'.
[Info] Publishing Reliability Index daily average table to WYSIWYG Custom Field 'WYSIWYG'.
[Info] Successfully set 'WYSIWYG' Custom Field!
[Info] Latest reliability index score for SRV19-TEST:
2/19/2025 1:00:00 PM | 6.835
[Info] Table of daily averages:
Date Average Reliability Index
---- -------------------------
2/19/2025 8.26
2/18/2025 10
2/17/2025 10
2/16/2025 10
2/15/2025 10
2/14/2025 10
2/13/2025 10
2/12/2025 10
2/11/2025 10
2/10/2025 10
2/9/2025 10
2/8/2025 10
2/7/2025 10
2/6/2025 10
2/5/2025 10
2/4/2025 10
2/3/2025 10
2/2/2025 10
2/1/2025 10
1/31/2025 10
1/30/2025 10
1/29/2025 10
1/28/2025 10
1/27/2025 10
1/26/2025 10
1/25/2025 10
1/24/2025 10
1/23/2025 10
1/22/2025 10
1/21/2025 10
1/20/2025 10
1/19/2025 10
.PARAMETER -TextCustomFieldName "ReplaceMeWithAnyTextCustomField"
Name of the Text custom field to populate with the most recent reliability index score.
.EXAMPLE
-TextCustomFieldName "ReplaceMeWithAnyMultilineCustomField"
[Info] Retrieving reliability index information for SRV19-TEST.
[Info] Successfully retrieved reliability index information!
[Info] Retrieving current value of Text Custom Field 'Text'.
[Info] Successfully retrieved the current value of 'Text'.
[Info] Publishing the latest reliability index score to Text Custom Field 'Text'.
[Info] Successfully set 'Text' Custom Field to value '2/19/2025 1:00:00 PM | 6.835'!
[Info] Latest reliability index score for SRV19-TEST:
2/19/2025 1:00:00 PM | 6.835
[Info] Table of daily averages:
Date Average Reliability Index
---- -------------------------
2/19/2025 8.26
2/18/2025 10
2/17/2025 10
2/16/2025 10
2/15/2025 10
2/14/2025 10
2/13/2025 10
2/12/2025 10
2/11/2025 10
2/10/2025 10
2/9/2025 10
2/8/2025 10
2/7/2025 10
2/6/2025 10
2/5/2025 10
2/4/2025 10
2/3/2025 10
2/2/2025 10
2/1/2025 10
1/31/2025 10
1/30/2025 10
1/29/2025 10
1/28/2025 10
1/27/2025 10
1/26/2025 10
1/25/2025 10
1/24/2025 10
1/23/2025 10
1/22/2025 10
1/21/2025 10
1/20/2025 10
1/19/2025 10
.NOTES
Minimum OS Architecture Supported: Windows 10, Windows Server 2016
Release Notes: Initial Release
#>
[CmdletBinding()]
param (
[Parameter()]
[string]$WYSIWYGCustomFieldName,
[Parameter()]
[string]$TextCustomFieldName
)
begin {
if ($env:WYSIWYGCustomFieldName){
$WYSIWYGCustomFieldName = $env:WYSIWYGCustomFieldName
}
if ($env:TextCustomFieldName){
$TextCustomFieldName = $env:TextCustomFieldName
}
# if custom field input is only spaces or a blank string, set it to null
# otherwise, trim any whitespace on the ends
if ([string]::IsNullOrWhiteSpace($WYSIWYGCustomFieldName)){
$WYSIWYGCustomFieldName = $null
}
else{
$WYSIWYGCustomFieldName = $WYSIWYGCustomFieldName.Trim()
}
if ([string]::IsNullOrWhiteSpace($TextCustomFieldName)){
$TextCustomFieldName = $null
}
else{
$TextCustomFieldName = $TextCustomFieldName.Trim()
}
# test custom field for invalid characters
if ($WYSIWYGCustomFieldName -match "[^0-9A-Z]"){
Write-Host "[Error] WYSIWYG Custom Field Name contains invalid character(s). Writing to the WYSIWYG Custom Field will be skipped."
Write-Host "[Error] https://ninjarmm.zendesk.com/hc/en-us/articles/360060920631-Custom-Field-Setup"
$WYSIWYGCustomFieldName = $null
$ExitCode = 1
Write-Host ""
}
if ($TextCustomFieldName -match "[^0-9A-Z]"){
Write-Host "[Error] Text Custom Field Name contains invalid character(s). Writing to the Text Custom Field will be skipped."
Write-Host "[Error] https://ninjarmm.zendesk.com/hc/en-us/articles/360060920631-Custom-Field-Setup"
$TextCustomFieldName = $null
$ExitCode = 1
Write-Host ""
}
function Get-CustomField {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $True, ValueFromPipeline = $True)]
[String]$Name,
[Parameter()]
[String]$Type,
[Parameter()]
[String]$DocumentName
)
# Initialize a hashtable for documentation parameters
$DocumentationParams = @{}
# If a document name is provided, add it to the documentation parameters
if ($DocumentName) { $DocumentationParams["DocumentName"] = $DocumentName }
# Define types that require options to be retrieved
$NeedsOptions = "DropDown", "MultiSelect"
# If a document name is provided, retrieve the property value from the document
if ($DocumentName) {
# Throw an error if the type is "Secure", as it's not a valid type in this context
if ($Type -Like "Secure") { throw [System.ArgumentOutOfRangeException]::New("$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") }
# Notify the user that the value is being retrieved from a Ninja document
Write-Host "Retrieving value from Ninja Document..."
$NinjaPropertyValue = Ninja-Property-Docs-Get -AttributeName $Name @DocumentationParams 2>&1
# If the property type requires options, retrieve them
if ($NeedsOptions -contains $Type) {
$NinjaPropertyOptions = Ninja-Property-Docs-Options -AttributeName $Name @DocumentationParams 2>&1
}
}
else {
# If no document name is provided, retrieve the property value directly
$NinjaPropertyValue = Ninja-Property-Get -Name $Name 2>&1
# If the property type requires options, retrieve them
if ($NeedsOptions -contains $Type) {
$NinjaPropertyOptions = Ninja-Property-Options -Name $Name 2>&1
}
}
# Throw an exception if there was an error retrieving the property value or options
if ($NinjaPropertyValue.Exception) { throw $NinjaPropertyValue }
if ($NinjaPropertyOptions.Exception) { throw $NinjaPropertyOptions }
# Handle the property value based on its type
switch ($Type) {
"Attachment" {
# Convert JSON formatted property value to a PowerShell object
$NinjaPropertyValue | ConvertFrom-Json
}
"Checkbox" {
# Convert the value to a boolean
[System.Convert]::ToBoolean([int]$NinjaPropertyValue)
}
"Date or Date Time" {
# Convert a Unix timestamp to local date and time
$UnixTimeStamp = $NinjaPropertyValue
$UTC = (Get-Date "1970-01-01 00:00:00").AddSeconds($UnixTimeStamp)
$TimeZone = [TimeZoneInfo]::Local
[TimeZoneInfo]::ConvertTimeFromUtc($UTC, $TimeZone)
}
"Decimal" {
# Convert the value to a double (floating-point number)
[double]$NinjaPropertyValue
}
"Device Dropdown" {
# Convert JSON formatted property value to a PowerShell object
$NinjaPropertyValue | ConvertFrom-Json
}
"Device MultiSelect" {
# Convert JSON formatted property value to a PowerShell object
$NinjaPropertyValue | ConvertFrom-Json
}
"Dropdown" {
# Convert options to a CSV format and match the GUID to retrieve the display name
$Options = $NinjaPropertyOptions -replace '=', ',' | ConvertFrom-Csv -Header "GUID", "Name"
$Options | Where-Object { $_.GUID -eq $NinjaPropertyValue } | Select-Object -ExpandProperty Name
}
"Integer" {
# Convert the value to an integer
[int]$NinjaPropertyValue
}
"MultiSelect" {
# Convert options to a CSV format, then match and return selected items
$Options = $NinjaPropertyOptions -replace '=', ',' | ConvertFrom-Csv -Header "GUID", "Name"
$Selection = ($NinjaPropertyValue -split ',').trim()
foreach ($Item in $Selection) {
$Options | Where-Object { $_.GUID -eq $Item } | Select-Object -ExpandProperty Name
}
}
"Organization Dropdown" {
# Convert JSON formatted property value to a PowerShell object
$NinjaPropertyValue | ConvertFrom-Json
}
"Organization Location Dropdown" {
# Convert JSON formatted property value to a PowerShell object
$NinjaPropertyValue | ConvertFrom-Json
}
"Organization Location MultiSelect" {
# Convert JSON formatted property value to a PowerShell object
$NinjaPropertyValue | ConvertFrom-Json
}
"Organization MultiSelect" {
# Convert JSON formatted property value to a PowerShell object
$NinjaPropertyValue | ConvertFrom-Json
}
"Time" {
# Convert the value from seconds to a time format in the local timezone
$Seconds = $NinjaPropertyValue
$UTC = ([timespan]::fromseconds($Seconds)).ToString("hh\:mm\:ss")
$TimeZone = [TimeZoneInfo]::Local
$ConvertedTime = [TimeZoneInfo]::ConvertTimeFromUtc($UTC, $TimeZone)
Get-Date $ConvertedTime -DisplayHint Time
}
default {
# For any other types, return the raw value
$NinjaPropertyValue
}
}
}
function Set-CustomField {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $True)]
[String]$Name,
[Parameter()]
[String]$Type,
[Parameter(Mandatory = $True, ValueFromPipeline = $True)]
$Value,
[Parameter()]
[String]$DocumentName,
[Parameter()]
[Switch]$Piped
)
# Remove the non-breaking space character
if ($Type -eq "WYSIWYG") {
$Value = $Value -replace ' ', ' '
}
# Measure the number of characters in the provided value
$Characters = $Value | ConvertTo-Json | Measure-Object -Character | Select-Object -ExpandProperty Characters
# Throw an error if the value exceeds the character limit of 200,000 characters
if ($Piped -and $Characters -ge 200000) {
throw [System.ArgumentOutOfRangeException]::New("Character limit exceeded: the value is greater than or equal to 200,000 characters.")
}
if (!$Piped -and $Characters -ge 45000) {
throw [System.ArgumentOutOfRangeException]::New("Character limit exceeded: the value is greater than or equal to 45,000 characters.")
}
# Initialize a hashtable for additional documentation parameters
$DocumentationParams = @{}
# If a document name is provided, add it to the documentation parameters
if ($DocumentName) { $DocumentationParams["DocumentName"] = $DocumentName }
# Define a list of valid field types
$ValidFields = "Attachment", "Checkbox", "Date", "Date or Date Time", "Decimal", "Dropdown", "Email", "Integer", "IP Address", "MultiLine", "MultiSelect", "Phone", "Secure", "Text", "Time", "URL", "WYSIWYG"
# Warn the user if the provided type is not valid
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" }
# Define types that require options to be retrieved
$NeedsOptions = "Dropdown"
# If the property is being set in a document or field and the type needs options, retrieve them
if ($DocumentName) {
if ($NeedsOptions -contains $Type) {
$NinjaPropertyOptions = Ninja-Property-Docs-Options -AttributeName $Name @DocumentationParams 2>&1
}
}
else {
if ($NeedsOptions -contains $Type) {
$NinjaPropertyOptions = Ninja-Property-Options -Name $Name 2>&1
}
}
# Throw an error if there was an issue retrieving the property options
if ($NinjaPropertyOptions.Exception) { throw $NinjaPropertyOptions }
# Process the property value based on its type
switch ($Type) {
"Checkbox" {
# Convert the value to a boolean for Checkbox type
$NinjaValue = [System.Convert]::ToBoolean($Value)
}
"Date or Date Time" {
# Convert the value to a Unix timestamp for Date or Date Time type
$Date = (Get-Date $Value).ToUniversalTime()
$TimeSpan = New-TimeSpan (Get-Date "1970-01-01 00:00:00") $Date
$NinjaValue = $TimeSpan.TotalSeconds
}
"Dropdown" {
# Convert the dropdown value to its corresponding GUID
$Options = $NinjaPropertyOptions -replace '=', ',' | ConvertFrom-Csv -Header "GUID", "Name"
$Selection = $Options | Where-Object { $_.Name -eq $Value } | Select-Object -ExpandProperty GUID
# Throw an error if the value is not present in the dropdown options
if (!($Selection)) {
throw [System.ArgumentOutOfRangeException]::New("Value is not present in dropdown options.")
}
$NinjaValue = $Selection
}
default {
# For other types, use the value as is
$NinjaValue = $Value
}
}
# Set the property value in the document if a document name is provided
if ($DocumentName) {
$CustomField = Ninja-Property-Docs-Set -AttributeName $Name -AttributeValue $NinjaValue @DocumentationParams 2>&1
}
else {
try {
# Otherwise, set the standard property value
if ($Piped) {
$CustomField = $NinjaValue | Ninja-Property-Set-Piped -Name $Name 2>&1
}
else {
$CustomField = Ninja-Property-Set -Name $Name -Value $NinjaValue 2>&1
}
}
catch {
Write-Host -Object "[Error] Failed to set custom field."
throw $_.Exception.Message
}
}
# Throw an error if setting the property failed
if ($CustomField.Exception) {
throw $CustomField
}
}
function Test-IsElevated {
$id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$p = New-Object System.Security.Principal.WindowsPrincipal($id)
$p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}
}
process {
if (-not (Test-IsElevated)) {
Write-Host -Object "[Error] Access Denied. Please run with Administrator privileges."
exit 1
}
$ExitCode = 0
# retrieve reliability index metrics
try{
Write-Host "[Info] Retrieving reliability index information for $env:computername."
$reliabilityMetrics = Get-CimInstance Win32_ReliabilityStabilityMetrics | Sort-Object TimeGenerated -Descending
Write-Host "[Info] Successfully retrieved reliability index information!`n"
}
catch{
Write-Host "[Error] Error retrieving reliability index information."
Write-Host "[Error] $($_.Exception.Message)"
exit 1
}
# if any metrics are present, continue with script
# otherwise, error out with a message that no information is available
if ($reliabilityMetrics){
# get unique dates from the metrics
$dates = $reliabilityMetrics | Group-Object {$_.TimeGenerated.ToShortDateString()}
# create table with averages of each dates' score, sorted by date (most recent to oldest)
$reliabilityIndexTable = $(foreach ($currentDate in $dates){
[PSCustomObject]@{
Date = $currentDate.Name
"Average Reliability Index" = [Math]::Round(($currentDate.Group.SystemStabilityIndex | Measure-Object -Average).Average,2)
}
}) | Sort-Object {[datetime]::Parse($_.Date)} -Descending
# get the most recent time and score
$currentIndexDate = ($reliabilityMetrics | Select-Object -First 1).EndMeasurementDate.ToString()
$currentIndexScore = ($reliabilityMetrics | Select-Object -First 1).SystemStabilityIndex
# above values will be written to the Text Custom Field and output to the activity feed using the below formatted string
$latestIndexInfo = "$currentIndexDate | $currentIndexScore"
# write to WYSIWYG Custom Field if provided
if ($WYSIWYGCustomFieldName){
# convert report to HTML table
$report = $reliabilityIndexTable | ConvertTo-HTML -Fragment
# attempt to get the current value of the field, to determine if it already matches the report
try{
Write-Host "[Info] Retrieving current value of WYSIWYG Custom Field '$WYSIWYGCustomFieldName'."
# output will be in JSON format for this type of field, need to first convert it to an object, and we want to compare the HTML so that is extracted into the variable
$currentValue = (Get-CustomField $WYSIWYGCustomFieldName | ConvertFrom-JSON).HTML
Write-Host "[Info] Successfully retrieved the current value of '$WYSIWYGCustomFieldName'.`n"
}
catch{
Write-Host "[Error] Error retrieving current value of '$WYSIWYGCustomFieldName'."
Write-Host "[Error] $($_.Exception.Message)`n"
# an error occurred while getting the current value of the custom field, so we will skip writing to it
$skipWYSIWYGCFWrite = $true
$ExitCode = 1
}
# check if the current value of the field is the same as the report. if so, output a message and do not try to write to the field again
if ($currentValue -eq $report){
Write-Host "[Info] WYSIWYG Custom Field '$WYSIWYGCustomFieldName' already has the latest information.`n"
}
# otherwise, continue with writing to the custom field unless there was an error retrieving the current value above
elseif (-not ($skipWYSIWYGCFWrite)){
try{
Write-Host "[Info] Publishing Reliability Index daily average table to WYSIWYG Custom Field '$WYSIWYGCustomFieldName'."
Set-CustomField -Name $WYSIWYGCustomFieldName -Value $report -Type "WYSIWYG"
Write-Host "[Info] Successfully set '$WYSIWYGCustomFieldName' Custom Field!`n"
}
catch{
Write-Host "[Error] Error setting '$WYSIWYGCustomFieldName'."
Write-Host "[Error] $($_.Exception.Message)`n"
$ExitCode = 1
}
}
}
# write to Text custom field if provided
if ($TextCustomFieldName){
# attempt to retrieve current value of the text custom field
try{
Write-Host "[Info] Retrieving current value of Text Custom Field '$TextCustomFieldName'."
$currentValue = Get-CustomField $TextCustomFieldName
Write-Host "[Info] Successfully retrieved the current value of '$TextCustomFieldName'.`n"
}
catch{
Write-Host "[Error] Error retrieving current value of '$TextCustomFieldName'."
Write-Host "[Error] $($_.Exception.Message)`n"
# an error occurred while getting the current value of the custom field, so we will skip writing to it
$skipTextCFWrite = $true
$ExitCode = 1
}
if ($currentValue -eq $latestIndexInfo){
Write-Host "[Info] Text Custom Field '$TextCustomFieldName' already has the latest information.`n"
}
elseif (-not ($skipTextCFWrite)){
try{
Write-Host "[Info] Publishing the latest reliability index score to Text Custom Field '$TextCustomFieldName'."
Set-CustomField -Name $TextCustomFieldName -Value $latestIndexInfo -Type "Text"
Write-Host "[Info] Successfully set '$TextCustomFieldName' Custom Field to value '$latestIndexInfo'!`n"
}
catch{
Write-Host "[Error] Error setting '$TextCustomFieldName' to value '$latestIndexInfo'."
Write-Host "[Error] $($_.Exception.Message)`n"
$ExitCode = 1
}
}
}
# output information to the activity feed
Write-Host "[Info] Latest reliability index score for $env:computername`:"
$latestIndexInfo | Out-Host
Write-Host "`n[Info] Table of daily averages:"
$reliabilityIndexTable | Out-Host
}
else{
Write-Host "[Error] Reliability index information could not be found on this machine."
exit 1
}
exit $ExitCode
}
end {
}
Description détaillée
Voici comment fonctionne le script, étape par étape :
- Traitement des paramètres :
- Accepte deux paramètres facultatifs :
-WYSIWYGCustomFieldNameet-TextCustomFieldName. - Ils déterminent si les résultats doivent être publiés dans les champs personnalisés WYSIWYG (format HTML) ou Texte de NinjaOne.
- Accepte deux paramètres facultatifs :
- Gestion des variables d’environnement :
- Si ces paramètres sont transmis en tant que variables d’environnement (ce qui est courant dans les scripts de tâches RMM), ils sont capturés et validés.
- Logique de validation:
- Permet de s’assurer que les noms des champs personnalisés ne contiennent que des caractères valides.
- Il supprime les espaces blancs et ignore les entrées non valides.
- Recherche d’indices de fiabilité:
- Utilise
Get-CimInstancepour interrogerWin32_ReliabilityStabilityMetrics. - Agrége les mesures dans un tableau de moyennes journalières, triées avec les plus récentes en haut.
- Extrait le dernier score enregistré et l’horodatage.
- Utilise
- Logique d’édition:
- Si un champ WYSIWYG est spécifié :
- Convertit le tableau en fragment HTML.
- Compare le contenu actuel et le nouveau contenu avant la mise à jour afin d’éviter les écritures redondantes.
- Si un champ Text est spécifié :
- Publie le score le plus récent sous forme de chaîne de caractères (par exemple,
2/19/2025 1:00:00 PM | 6.835).
- Publie le score le plus récent sous forme de chaîne de caractères (par exemple,
- Si un champ WYSIWYG est spécifié :
- Journalisation et sortie:
- Des messages
[Info]et[Error]détaillés sont fournis à des fins de transparence et de dépannage. - Affiche le score actuel et l’historique de fiabilité dans le flux d’activité.
- Des messages
Cas d’utilisation potentiels
Étude de cas : Jane, ingénieur système chez MSP
Jane gère plus de 500 terminaux dans divers environnements clients. Pour identifier de manière proactive les machines présentant des problèmes de stabilité, elle déploie ce script PowerShell via le module d’automatisation de NinjaOne :
- Les systèmes qui obtiennent un score inférieur à 8 pendant plusieurs jours consécutifs déclenchent l’envoi d’un ticket via les webhooks.
- Les champs WYSIWYG contiennent des rapports formatés pour les résumés exécutifs.
- Les champs de texte permettent de saisir le dernier score, qui s’intègre aux tableaux de bord.
Cette approche permet à Jane de détecter les tendances à la baisse de la stabilité avant qu’elles n’affectent les utilisateurs, améliorant ainsi la conformité aux accords de niveau de service (SLA) et la satisfaction des clients.
Comparaisons
| Méthode | Avantages | Inconvénients |
| Utilisation manuelle de l’interface graphique du moniteur de fiabilité | Simple, aucune connaissance en matière de script n’est requise | Chronophage, pas d’exportation ni d’automatisation |
| Filtrage du journal des événements | Contrôle granulaire | Complexe et non synthétique |
| Ce script PowerShell | Automatisé, convivial, intégré à NinjaOne | Nécessite PowerShell 5.1+, droits d’administrateur |
Par rapport aux méthodes traditionnelles, ce script offre une approche optimisée, reproductible et intégrée pour contrôler la fiabilité sur de nombreux terminaux.
Questions fréquentes
Q : Sur quoi se base l’indice de fiabilité de Windows ?
A : Il regroupe les journaux d’événements Windows, les pannes, les mises à jour et les erreurs matérielles.
Q : Puis-je l’utiliser sans NinjaOne ?
A : Oui, le rapport de fiabilité sera toujours généré et imprimé, mais la publication de champs personnalisés est spécifique aux environnements NinjaOne.
Q : À quelle fréquence ce script doit-il être exécuté ?
A : Quotidiennement ou hebdomadairement, en fonction de la volatilité de votre environnement.
Q : Que se passe-t-il si aucune donnée de fiabilité n’est trouvée ?
A : Le script se termine par un message d’erreur indiquant qu’aucune donnée n’est disponible.
Implications
En centralisant et en automatisant le suivi de la fiabilité des systèmes, les professionnels de l’informatique disposent d’un système d’alerte précoce en cas de dégradation du système. Des scores constamment bas peuvent signaler des problèmes plus importants, tels que des conflits de pilotes ou un matériel défaillant, qui pourraient autrement passer inaperçus. Ce script favorise également la prise de décision fondée sur des données, en particulier lorsqu’il est lié à des systèmes de ticketing et d’alerte.
Recommandations
- Programmez des exécutions régulières via le planificateur de tâches ou l’automatisation RMM afin de maintenir les enregistrements à jour.
- Définissez des seuils pour déclencher des alertes ou des actions d’assistance.
- Utilisez des conventions de dénomination significatives pour vos champs personnalisés afin d’éviter les erreurs de configuration.
- Testez sur quelques systèmes avant de passer à des environnements de production.
Conclusion
La création d’un rapport sur l’indice de fiabilité Windows avec PowerShell est un moyen efficace d’obtenir une visibilité sur la stabilité des terminaux gérés. Ce script, associé à NinjaOne, vous permet de stocker, de formater et de contrôler les scores de fiabilité d’une manière qui s’aligne sur les pratiques modernes d’automatisation informatique. Pour les MSP qui souhaitent offrir un service proactif et de qualité, cette solution ajoute à leur boîte à outils un outil de surveillance à faible coût et à forte valeur ajoutée.
En permettant la création de rapports de fiabilité automatisés grâce à des champs personnalisés, NinjaOne aide les équipes informatiques à combler le manque de visibilité et à améliorer les résultats opérationnels, le tout à partir d’un guichet unique.