La validation des paramètres

Posted by : at

Category : PowerShell   Niv100


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.


About LIENHARD Laurent
LIENHARD Laurent

Email : laurent@lienhard.fr

Website :

About LIENHARD Laurent

Auto-Didacte en PowerShell, Co-fondateur et animateur du French PowerShell & DevOps UserGroup

Useful Links