Guide complet pour la surveillance de l’espace disque Hyper-V avec PowerShell

La gestion efficace de l’espace disque est un aspect essentiel pour le maintien d’une infrastructure informatique efficace et fiable. Un outil puissant pour les professionnels de l’informatique est PowerShell, un cadre d’automatisation des tâches de Microsoft. Aujourd’hui, nous allons nous pencher sur un script PowerShell conçu pour surveiller l’espace libre sur les volumes partagés dans un environnement de cluster Hyper-V. Ce script est particulièrement utile pour les professionnels de l’informatique et les fournisseurs de services gérés (MSP) qui doivent s’assurer que leurs systèmes fonctionnent sans problèmes et éviter les temps d’arrêt dus à des problèmes de stockage.

Contexte

Le contrôle de l’espace disque est essentiel pour éviter les pannes inattendues et garantir que les applications et les services fonctionnent sans interruption. Les volumes partagés de cluster Hyper-V peuvent héberger de nombreuses machines virtuelles et un manque d’espace peut avoir de graves conséquences. Ce script PowerShell simplifie le processus de surveillance, permettant aux administrateurs de garder un œil sur l’espace libre et de prendre des mesures avant que des problèmes ne surviennent.

Le script :

Requires -Version 5.1

<#
.SYNOPSIS
    Hyper-V Monitor shared volume disk free space. Must be ran as a Local or Domain Admin user.
.DESCRIPTION
    Hyper-V Monitor shared volume disk free space. Must be ran as a Local or Domain Admin user.

.EXAMPLE
    (No Parameters)
    ## EXAMPLE OUTPUT WITHOUT PARAMS ##
Name                       Path                  Size(GB) FreeSpace(GB) UsedSpace(GB) PercentFree
----                       ----                  -------- ------------- ------------- -----------
Cluster Virtual Disk (vd1) C:\ClusterStorage\vd1 3,068.98 168.77        2900.21       9.99

PARAMETER: -MinimumPercentage 20
    Only errors when any shared volume disk is below the specified percentage.
    Defaults to 10 percent.
.EXAMPLE
    -MinimumPercentage 20
    ## EXAMPLE OUTPUT WITH MinimumPercentage ##
Name                       Path                  Size(GB) FreeSpace(GB) UsedSpace(GB) PercentFree
----                       ----                  -------- ------------- ------------- -----------
Cluster Virtual Disk (vd1) C:\ClusterStorage\vd1 3,068.98 168.77        2900.21       9.99

PARAMETER: -MinimumFreeBytes 1073741824
    Only errors when any shared volume disk is below the specified percentage.
    Defaults to 1GB or 1073741824 bytes.
.EXAMPLE
    -MinimumFreeBytes 1073741824
    ## EXAMPLE OUTPUT WITH MinimumFreeBytes ##
Name                       Path                  Size(GB) FreeSpace(GB) UsedSpace(GB) PercentFree
----                       ----                  -------- ------------- ------------- -----------
Cluster Virtual Disk (vd1) C:\ClusterStorage\vd1 3,068.98 168.77        2900.21       9.99

PARAMETER: -ExcludeDrivesByName MyDisk
    Excludes drives that contains the text MyDisk in its name.
.EXAMPLE
    -ExcludeDrivesByName 1073741824
    ## EXAMPLE OUTPUT WITH ExcludeDrivesByName ##
Name                       Path                  Size(GB) FreeSpace(GB) UsedSpace(GB) PercentFree
----                       ----                  -------- ------------- ------------- -----------
Cluster Virtual Disk (vd1) C:\ClusterStorage\vd1 3,068.98 168.77        2900.21       9.99

PARAMETER: -ExcludeDrivesByPath C:\ClusterStorage\MyDisk
    Excludes drives that contains the text MyDisk in its name.
.EXAMPLE
    -ExcludeDrivesByPath C:\ClusterStorage\MyDisk
.EXAMPLE
    -ExcludeDrivesByPath MyDisk
    ## EXAMPLE OUTPUT WITH ExcludeDrivesByPath ##
Name                       Path                  Size(GB) FreeSpace(GB) UsedSpace(GB) PercentFree
----                       ----                  -------- ------------- ------------- -----------
Cluster Virtual Disk (vd1) C:\ClusterStorage\vd1 3,068.98 168.77        2900.21       9.99

PARAMETER: -CustomFieldParam "ReplaceMeWithAnyMultilineCustomField"
    Saves the results to a multi-line string custom field.
.EXAMPLE
    -CustomFieldParam "ReplaceMeWithAnyMultilineCustomField"
    ## EXAMPLE OUTPUT WITH CustomFieldParam ##
Name                       Path                  Size(GB) FreeSpace(GB) UsedSpace(GB) PercentFree
----                       ----                  -------- ------------- ------------- -----------
Cluster Virtual Disk (vd1) C:\ClusterStorage\vd1 3,068.98 168.77        2900.21       9.99
.OUTPUTS
    None
.NOTES
    Minimum OS Architecture Supported: 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 (
    [int]$MinimumPercentage = 10,
    $MinimumFreeBytes = 1GB,
    [String]$ExcludeDrivesByName,
    [String]$ExcludeDrivesByPath,
    [string]$CustomFieldParam
)

begin {
    function Test-IsElevated {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $p = New-Object System.Security.Principal.WindowsPrincipal($id)
        $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
    }
    function Test-IsSystem {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        return $id.Name -like "NT AUTHORITY*" -or $id.IsSystem
    }
    function Get-FriendlySize {
        param($Bytes)
        # Converts Bytes to the highest matching unit
        $Sizes = 'Bytes,KB,MB,GB,TB,PB,EB,ZB' -split ','
        for ($i = 0; ($Bytes -ge 1kb) -and ($i -lt $Sizes.Count); $i++) { $Bytes /= 1kb }
        $N = 2
        if ($i -eq 0) { $N = 0 }
        if ($Bytes) { "$([System.Math]::Round($Bytes,$N)) $($Sizes[$i])" }else { "0 B" }
    }
    function Get-Size {
        param (
            [string]$String,
            [ValidateSet("PB", "TB", "GB", "MB", "KB", "B", "Bytes")][string]$DefaultSize = "GB"
        )
        switch -wildcard ($String) {
            '*PB' { [int64]$($String -replace '[^\d+]+') * 1PB; break }
            '*TB' { [int64]$($String -replace '[^\d+]+') * 1TB; break }
            '*GB' { [int64]$($String -replace '[^\d+]+') * 1GB; break }
            '*MB' { [int64]$($String -replace '[^\d+]+') * 1MB; break }
            '*KB' { [int64]$($String -replace '[^\d+]+') * 1KB; break }
            '*B' { [int64]$($String -replace '[^\d+]+') * 1; break }
            '*Bytes' { [int64]$($String -replace '[^\d+]+') * 1; break }
            Default { Get-Size -String "$String $DefaultSize" }
        }
    }
    function Invoke-FilterDisks {
        [CmdletBinding()]
        param(
            [parameter(ValueFromPipeline = $true)]
            $Disks
        )
        process {
            $Disks | ForEach-Object {
                # Check if exclude by name is needed
                if ($([string]::IsNullOrEmpty($ExcludeDrivesByName) -or [string]::IsNullOrWhiteSpace($ExcludeDrivesByName))) {
                    $_
                }
                else {
                    if (
                        $_.Name -like "*$ExcludeDrivesByName*"
                    ) {
                        # Output Nothing
                    }
                    else {
                        $_
                    }
                }
            } | ForEach-Object {
                # Check if exclude by name is needed
                if ($([string]::IsNullOrEmpty($ExcludeDrivesByPath) -or [string]::IsNullOrWhiteSpace($ExcludeDrivesByPath))) {
                    $_
                }
                else {
                    if (
                        $_.Path -like "*$ExcludeDrivesByPath*"
                    ) {
                        # Output Nothing
                    }
                    else {
                        $_
                    }
                }
            }
        }
    }
    if ($env:MinimumPercentage) {
        $MinimumPercentage = $env:MinimumPercentage
    }
    if ($env:minimumFreeSpace) {
        $MinimumFreeBytes = Get-Size -String $env:minimumFreeSpace
    }
    if ($env:ExcludeDrivesByName) {
        $ExcludeDrivesByName = $env:ExcludeDrivesByName
    }
    if ($env:ExcludeDrivesByPath) {
        $ExcludeDrivesByPath = $env:ExcludeDrivesByPath
    }
    if ($env:CustomFieldParam) {
        $CustomFieldParam = $env:CustomFieldParam
    }
}
process {
    if (Test-IsSystem) {
        Write-Error -Message "Access Denied. Please run with a Domain Account or a Local Account that has permissions to access this node."
        exit 1
    }

    if (-not (Test-IsElevated)) {
        Write-Error -Message "Access Denied. Please run with Administrator privileges."
        exit 1
    }

    Import-Module FailoverClusters -ErrorAction SilentlyContinue

    if (-not $(Get-Command -Name "Get-Cluster" -ErrorAction SilentlyContinue)) {
        Write-Error "[Error] Must run this script on a server that is apart of a Cluster or can communicate with a Cluster."
        exit 1
    }

    try {
        Get-ClusterNode -ErrorAction Stop | Out-Null
    }
    catch {
        Write-Error "[Error] Failed to get Cluster Nodes."
        exit 1
    }

    # Get Cluster Shared Volume Info
    $Volumes = foreach ( $csv in $(Get-ClusterSharedVolume) ) {
        foreach ( $csvinfo in $($csv | Select-Object -Property Name -ExpandProperty SharedVolumeInfo) ) {
            [PSCustomObject]@{
                Name        = $csv.Name
                Path        = $csvinfo.FriendlyVolumeName
                Size        = $csvinfo.Partition.Size
                FreeSpace   = $csvinfo.Partition.FreeSpace
                UsedSpace   = $csvinfo.Partition.UsedSpace
                PercentFree = $csvinfo.Partition.PercentFree
            }
        }
    }

    # Prep Format-Table substitutions
    $Size = @{ Label = "Size(GB)" ; Expression = { (Get-FriendlySize -Bytes $_.Size) } }
    $FreeSpace = @{ Label = "FreeSpace(GB)" ; Expression = { (Get-FriendlySize -Bytes $_.FreeSpace) } }
    $UsedSpace = @{ Label = "UsedSpace(GB)" ; Expression = { (Get-FriendlySize -Bytes $_.UsedSpace) } }
    $PercentFree = @{ Label = "PercentFree" ; Expression = { ($_.PercentFree) } }
    # Sort disks by FreeSpace
    $Disks = $Volumes | Sort-Object FreeSpace
    # Save results as a string
    $DisksFormattedString = $Disks | Format-Table -AutoSize Name, Path, $Size, $FreeSpace, $UsedSpace, $PercentFree | Out-String

    # If using a custom field sent that to the specified custom field, should be a multi-line
    if ($CustomFieldParam) {
        Ninja-Property-Set -Name $CustomFieldParam -Value $DisksFormattedString
    }

    # Loop through each disk
    $DiskUnderPercentage = $Disks | Invoke-FilterDisks | Where-Object { $_.PercentFree -lt $MinimumPercentage }
    $DiskUnderFreeBytes = $Disks | Invoke-FilterDisks | Where-Object { $_.FreeSpace -lt $MinimumFreeBytes }

    if ($DiskUnderPercentage -or $DiskUnderFreeBytes) {
        if ($DiskUnderPercentage) {
            Write-Host "[Issue] One or more Disks under $MinimumPercentage % free!"
        }
        if ($DiskUnderFreeBytes) {
            Write-Host "[Issue] One or more Disks under $(Get-FriendlySize -Bytes $MinimumFreeBytes) free!"
        }
        $DisksFormattedString | Write-Host
        exit 1
    }

    # List all shared volumes
    if (-not $DiskUnderPercentage) {
        Write-Host "[Info] One or more Disks over $MinimumPercentage % free."
    }
    if (-not $DiskUnderFreeBytes) {
        Write-Host "[Info] One or more Disks over $(Get-FriendlySize -Bytes $MinimumFreeBytes) free."
    }
    $DisksFormattedString | Write-Host
    exit 0
}
end {
    
    
    
}

 

Description détaillée

Décortiquons le script étape par étape pour comprendre sa fonctionnalité et la manière dont il peut être utilisé efficacement.

1. Conditions préalables et configuration initiale Le script nécessite la version 5.1 de PowerShell et doit être exécuté avec des droits d’administrateur. Il commence par définir divers paramètres tels que MinimumPercentage, MinimumFreeBytes, ExcludeDrivesByName, ExcludeDrivesByPath et CustomFieldParam.

2. Fonctions de contrôle des privilèges et de calcul de la taille

  • Test-IsElevated vérifie si le script est exécuté avec des privilèges d’administrateur.
  • Test-IsSystem permet de s’assurer que le script n’est pas exécuté en tant que compte système.
  • Get-FriendlySize et Get-Size convertissent les valeurs en octets en unités plus lisibles telles que Ko, Mo, Go, etc.

3. Filtrage et variables d’environnement Le script met en place des fonctions pour filtrer les lecteurs en fonction de noms ou de chemins d’accès spécifiés. Il vérifie également la présence de variables d’environnement susceptibles de remplacer les paramètres du script.

4. Récupération d’informations sur les clusters et les volumes Le script importe le module FailoverClusters et vérifie qu’il est exécuté sur un serveur faisant partie d’un cluster. Il récupère ensuite des informations sur les volumes partagés du cluster, notamment leur taille, l’espace libre, l’espace utilisé et le pourcentage d’espace libre.

5. Formatage et résultat Le script formate les informations du disque pour qu’elles soient lisibles et vérifie si des volumes sont inférieurs aux seuils d’espace libre spécifiés. Si des problèmes sont détectés, il fournit les détails et se finit avec un statut d’erreur. Dans le cas contraire, il confirme que tous les volumes disposent de suffisamment d’espace libre.

Cas d’utilisation potentiels

Imaginez un administrateur informatique responsable d’un cluster Hyper-V hébergeant des machines virtuelles cruciales. Cet administrateur peut utiliser le script pour automatiser la surveillance de l’espace disque, ce qui lui permet d’être alerté avant qu’un volume ne manque cruellement d’espace. Cette approche proactive lui permet d’allouer un espace de stockage supplémentaire ou de nettoyer les fichiers inutiles, afin d’éviter les pannes potentielles et de maintenir les performances du système.

Comparaisons

Par rapport à une surveillance manuelle ou à l’utilisation d’outils intégrés de base, ce script fournit une approche plus automatisée et plus détaillée. Il vérifie non seulement l’espace libre, mais permet également une personnalisation basée sur les noms de volumes, les chemins d’accès et les exigences spécifiques en matière d’espace libre. D’autres méthodes, telles que des outils de surveillance tiers, peuvent offrir des fonctionnalités similaires, mais elles sont souvent plus coûteuses et nécessitent une configuration supplémentaire.

FAQ

Q : Ce script peut-il être exécuté sur n’importe quelle version de Windows Server ?

R : Le script prend en charge Windows Server 2016 et les versions ultérieures en raison des exigences du module FailoverClusters.

Q : Quelles sont les autorisations nécessaires pour exécuter ce script ?

R : Le script doit être exécuté avec les privilèges d’administrateur local ou de domaine pour accéder aux informations nécessaires sur le cluster.

Q : Comment puis-je exclure certains volumes de la surveillance ?

R : Vous pouvez utiliser les paramètres ExcludeDrivesByName ou ExcludeDrivesByPath pour filtrer des volumes spécifiques en fonction de leur nom ou de leur chemin d’accès.

Implications

Les résultats de ce script peuvent avoir un impact significatif sur les opérations informatiques. En identifiant les volumes dont l’espace libre est insuffisant, les administrateurs peuvent prendre des mesures préventives pour éviter les interruptions de service. Cette surveillance proactive améliore également la fiabilité et les performances globales du système, contribuant ainsi à un environnement informatique plus stable.

Recommandations

Lors de l’utilisation de ce script, il est important de suivre les bonnes pratiques suivantes :

  • Planifiez l’exécution du script à intervalles réguliers à l’aide d’un planificateur de tâches ou d’outils similaires.
  • Personnalisez les paramètres en fonction des besoins spécifiques de votre environnement.
  • Assurez-vous que vous disposez des autorisations suffisantes et que vous exécutez le script sur les serveurs appropriés.

Conclusion

Les scripts PowerShell comme celui-ci sont des outils inestimables pour les professionnels de l’informatique et les entreprises MSP, car ils offrent de puissantes capacités d’automatisation pour gérer et surveiller les systèmes importants. En intégrant de tels scripts dans leurs flux de travail, les administrateurs peuvent mieux contrôler leur infrastructure, garantir des performances optimales et prévenir les problèmes potentiels avant qu’ils ne s’aggravent.

NinjaOne, l’un des principaux logiciels d’opérations informatiques, peut encore améliorer ce processus en intégrant l’exécution de scripts à ses capacités de surveillance et de gestion, fournissant ainsi une solution complète pour la gestion de l’infrastructure informatique.

Pour aller plus loin

Pour créer une équipe informatique efficace et performante, il est essentiel d'avoir une solution centralisée qui joue le rôle de nœud principal pour 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 profitez d'un 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)).