La validation des paramètres

Dans cette article nous allons parler d’une option disponible dans Powershell : la validation des paramètres

Cette option a pour but, comme son nom l’indique, de valider qu’un paramètre passé à une fonction est bien celui que l’on attends.

Tout au long de cette article nous garderons le script suivant comme fil conducteur.

function Do-SomeThing {
    [CmdletBinding()]
    param (
        [String[]]$ComputerName,
        [Int]$Age
    )

    begin {
        #La valeur de computername ne doit pas être nul ou vide
        if (($null -eq $ComputerName) -or ($ComputerName -eq "")) {
            throw "La valeur de ComputerName ne peut pas être vide ou null"
        }
        #Test pour vérifier que le nom du computer ne dépasse pas 13 caractères
        If ($ComputerName.Length -gt 13) {
            Throw "Le nom du Computer ne doit pas dépasser 13 caractères"
        }

        #L'age de l'ordinateur doit-être compris entre 5 et 10 ans
        if (!(($Age -gt 5) -and ($Age -lt 10))) {
            throw "l'age doit-être compris entre 5 et 10 ans"
        }

    }

    process {
    }

    end {
    }
}

[ValidateNotNullOrEmpty()] and [ValidateNotNull()]

ValidateNotNull : vérifie uniquement si la valeur transmise au paramètre est une valeur null. Cela fonctionnera toujours s’il est passé une chaîne vide.

ValidateNotNullOrEmpty : vérifie également si la valeur transmise est une valeur null et s’il s’agit d’une chaîne ou d’une collection vide

Dans notre exemple nous pouvons remplacer le test suivant

if (($null -eq $ComputerName) -or ($ComputerName -eq "")) {
    throw "La valeur de ComputerName ne peut pas être vide ou null"
}

en modifiant simplement la déclaration de notre variable $ComputerName

Param (
    [ValidateNotNullOrEmpty()]
    [String[]]$ComputerName
)

[ValidateLength()]

Cette validation permet de définir une taille minimale et maximale attendue pour un paramètre.

Dans notre exemple nous voulons que le paramètre ComputerName fasse minimum 1 caractère et au maximum 13 caractères.

Nous pouvons donc remplacer le test :

    If ($ComputerName.Length -gt 13) {
        Throw "Le nom du Computer ne doit pas dépasser 13 caractère"
    }

par la déclaration de paramètre suivant :

Param (
    [ValidateLength(1,13)]
    [String[]]$ComputerName
)

Mais attendez ! Nous avions déjà modifié la déclaration de ce paramètre précédemment pour ajouter [ValidateNotNullOrEmpty()] ?

Effectivement les validations des paramètres peuvent être cumulées. Dans notre cas nous déclarons le paramètre de cette façon :

    param (
        [ValidateNotNullOrEmpty()]
        [ValidateLength(1,13)]
        [String[]]$ComputerName
    )

ComputerName ne doit-être ni Null, ni vide et doit faire entre 1 et 13 caractères.

[ValidateRange()]

C’est en quelque sorte le pendant de [ValidateLength()] mais pour les chiffres. Comme pour [ValidateLength()], il permet de définir une valeur minimale et maximale que peut prendre un paramètre.

Dans notre exemple l’age du PC doit-être compris entre 5 et 10 ans. Nous avions donc le test suivant :

    if (!(($Age -gt 5) -and ($Age -lt 10))) {
        throw "l'age doit-être compris entre 5 et 10 ans"
    }

nous pouvons donc remplacer ce test par :

param (
    [ValidateRange(5,10)]
    [int]$Age
    )

[ValidateCount()]

Comme pour ValidateRange() il permet de définir le nombre minimal et le nombre maximal d’objet que peux prendre une collection passée en paramètre.

    param (
        [ValidateNotNullOrEmpty()]
        [ValidateLength(1,13)]
        [ValidateCount(1,3)]
        [String[]]$ComputerName
    )

Dans notre exemple le paramètre ComputerName ne doit-être ni Null, ni vide, doit faire entre 1 et 13 caractères et nous ne pouvons passer que 1 à 3 objects dans la collection.

[ValidateSet()]

Cette validation permet de fournir une liste de réponse possible pour la valeur du paramètre.

Cette validation peut-être rendu Case Sensitive, si à la fin de la déclaration, la valeur ignorecase est définie à $False

le test de validation suivant

        #Être sur que la valeur est l'une de celle que je veux
        if("SIEGE","AGENCE","STOCK" -notcontains $Site) {
            throw "Le site doit-être SIEGE,AGENCE ou STOCK"
        }

peut-être remplacer par la déclaration de la variable Site suivante

    param (
        [ValidateSet("SIEGE","AGENCE","STOCK",ignorecase=$true)]
        [String]$Site
    )

Dans notre exemple, la paramètre ne peut prendre qu’une des 3 valeurs définies.

Nous avons également demandé à ce que le valeur du paramètre ne soit pas Case Sensitive donc SIEGE, Siege, sieGE sont toutes des valeurs corrects.

[ValidatePattern()]

Permet d’utiliser une expression régulière (REGEX) avant de tester la valeur d’un paramètre.

Dans notre script, nous avins le test suivant

        #Test pour savoir si le ComputerName correspond la nomenclature de l'entreprise
        if ($ComputerName -notmatch "^SRV-\D{6}\d{3}$") {
            Throw "Le ComputerName doit-être sous la forme SRV-LETTRE(6)CHIFFRE(3)"
        }

Nous voulons donc être sur que le paramètre ComputerName soit toujours sous la forme d’un string commençant par SRV- suivi de 6 lettres et de 3 chiffres.

Nous pouvons remplacer ce test par la validation

    param (
        [ValidateNotNullOrEmpty()]
        [ValidateLength(1,13)]
        [ValidateCount(1,3)]
        [ValidatePattern('^SRV-\D{6}\d{3}$')]
        [String[]]$ComputerName
    )

[ValidateScript()]

Cette validation permet de définir un script qui va être executer pour valider la valeur du paramètre.

Notre test pour valider l’existence du chemin

        #Savoir si le chemin passé en paramètre existe et est un répertoire
        IF (!(Test-Path $Path -PathType Container))
        {
            Throw "$($Path) n'est pas un dossier valide"
        }

peut-être remplacer par la validation suivante

    param (
        [ValidateScript(
            {IF (!(Test-Path -Path $_)) {
                Throw "$($Path) n'est pas un dossier valide"
            } else {
                $true
            }
            }
        )]
        [String]$Path
    )

Comme vous pouvez l’imaginer, le script peut-être quelque chose de plus compliqué qu’un simple test comme ici.

Conclusion

Pour conclure nous pouvons comparer simplement nos 2 versions de script.

Le script d’origine

function Do-SomeThing {
    [CmdletBinding()]
    param (
        [String[]]$ComputerName,
        [Int]$Age
    )

    begin {
        #La valeur de computername ne doit pas etre nul ou vide
        if (($null -eq $ComputerName) -or ($ComputerName -eq "")) {
            throw "La valeur de ComputerName ne peut pas être vide ou null"
        }
        #Test pour vérifier que le nom du computer ne dépasse pas 13 caractères
        If ($ComputerName.Length -gt 13) {
            Throw "Le nom du Computer ne doit pas dépasser 13 caractères"
        }

        #L'age de l'ordinateur doit-être compris entre 5 et 10 ans
        if (!(($Age -gt 5) -and ($Age -lt 10))) {
            throw "l'age doit-être compris entre 5 et 10 ans"
        }

    }

    process {
    }

    end {
    }
}

Le script final

function Do-SomeThing {
    [CmdletBinding()]
    param (
        [ValidateNotNullOrEmpty()]
        [ValidateLength(1,13)]
        [ValidateCount(1,3)]
        [ValidatePattern('^SRV-\D{6}\d{3}$')]
        [String[]]$ComputerName,
        [ValidateScript({IF (!(Test-Path -Path $_)) {
            Throw "$($Path) n'est pas un dossier valide"
        } else {
            $true
        }
        })]
        [String]$Path,
        [ValidateSet("SIEGE","AGENCE","STOCK",ignorecase=$true)]
        [String]$Site,
        [ValidateRange(5,10)]
        [int]$Age
    )

    begin {
    }

    process {
    }

    end {
    }
}

Nous constatons assez clairement que nous avons diminué les lignes de code nécessaire pour valider les paramètres et de ce fait simplifier la compréhension du script.

Laisser un commentaire