Fonction Powershell – Complexe et professionnel – Part 1.3.1

Les fonctions powershell
Les fonctions powershell

Introduction

Les fonctions en PowerShell sont des outils puissants pour automatiser et simplifier les tâches répétitives. Dans cet article, nous allons explorer en profondeur les différentes façons de créer et d’utiliser des fonctions en PowerShell, en utilisant des exemples concrets liés à la gestion d’une bibliothèque numérique.

Création de fonctions de base

Fonction simple

function Calculer-DureePret($dateEmprunt, $dateRetour) {
    return ($dateRetour - $dateEmprunt).Days
}

$duree = Calculer-DureePret "2023-01-01" "2023-01-15"
Write-Host "Le livre a été emprunté pendant $duree jours."

Explication : Cette fonction calcule la durée de prêt d’un livre en jours. Elle prend deux paramètres (dateEmprunt et dateRetour) et retourne la différence en jours. L’appel de la fonction démontre son utilisation avec des dates spécifiques.

Fonction avec paramètres nommés

function Calculer-DureePret {
    param(
        [DateTime]$dateEmprunt,
        [DateTime]$dateRetour
    )
    return ($dateRetour - $dateEmprunt).Days
}

$duree = Calculer-DureePret -dateEmprunt "2023-01-01" -dateRetour "2023-01-15"

Explication : Cette version améliorée utilise des paramètres nommés et spécifie explicitement le type DateTime pour chaque paramètre, ce qui améliore la robustesse de la fonction.

Paramètres avancés

Paramètres obligatoires et optionnels

function Ajouter-Livre {
    param(
        [Parameter(Mandatory=$true)]
        [string]$titre,

        [Parameter(Mandatory=$true)]
        [string]$auteur,

        [Parameter(Mandatory=$false)]
        [int]$anneePublication = (Get-Date).Year,

        [Parameter(Mandatory=$false)]
        [string]$genre = "Non spécifié"
    )

    Write-Host "Nouveau livre ajouté : $titre par $auteur ($anneePublication) - Genre : $genre"
}

Ajouter-Livre -titre "1984" -auteur "George Orwell" -anneePublication 1949 -genre "Science-fiction"

Explication : Cette fonction démontre l’utilisation de paramètres obligatoires (titre et auteur) et optionnels (anneePublication et genre) avec des valeurs par défaut. L’attribut [Parameter] permet de définir ces caractéristiques.

Validation des paramètres

function Ajouter-Livre {
    param(
        [Parameter(Mandatory=$true)]
        [string]$titre,

        [Parameter(Mandatory=$true)]
        [string]$auteur,

        [Parameter(Mandatory=$false)]
        [ValidateRange(1000, (Get-Date).Year)]
        [int]$anneePublication = (Get-Date).Year,

        [Parameter(Mandatory=$false)]
        [ValidateSet("Fiction", "Non-fiction", "Science-fiction", "Biographie", "Histoire")]
        [string]$genre = "Non spécifié"
    )

    Write-Host "Nouveau livre ajouté : $titre par $auteur ($anneePublication) - Genre : $genre"
}

Explication : Cette version ajoute une validation des paramètres. ValidateRange assure que l’année de publication est comprise entre 1000 et l’année actuelle. ValidateSet limite les choix de genre à une liste prédéfinie.

Fonctions avancées

Utilisation de CmdletBinding

Options de CmdletBinding

CmdletBinding est un attribut qui transforme une fonction PowerShell en une fonction avancée, lui donnant des fonctionnalités similaires à celles des cmdlets. Voici les principales options disponibles :

1. SupportsShouldProcess
function Supprimer-Fichier {
    [CmdletBinding(SupportsShouldProcess=$true)]
    param(
        [Parameter(Mandatory=$true)]
        [string]$Chemin
    )

    if ($PSCmdlet.ShouldProcess($Chemin, "Supprimer le fichier")) {
        Remove-Item $Chemin
    }
}

Cette option permet d’utiliser -WhatIf et -Confirm avec votre fonction. Elle est utile pour les opérations potentiellement dangereuses.

2. ConfirmImpact
function Formater-Disque {
    [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='High')]
    param(
        [Parameter(Mandatory=$true)]
        [string]$Lecteur
    )

    if ($PSCmdlet.ShouldProcess($Lecteur, "Formater le disque")) {
        # Code pour formater le disque
    }
}

ConfirmImpact définit le niveau de risque de l’opération. Les valeurs possibles sont ‘Low’, ‘Medium’, ‘High’.

3. DefaultParameterSetName

Cette option est utile lorsque votre fonction a plusieurs jeux de paramètres et que vous voulez en définir un par défaut.

Exemple détaillé

function Rechercher-Employe {
    [CmdletBinding(DefaultParameterSetName='Nom')]
    param(
        [Parameter(ParameterSetName='Nom', Mandatory=$true, Position=0)]
        [string]$Nom,

        [Parameter(ParameterSetName='ID', Mandatory=$true)]
        [int]$ID,

        [Parameter(ParameterSetName='Email', Mandatory=$true)]
        [string]$Email
    )

    switch ($PSCmdlet.ParameterSetName) {
        'Nom' {
            Write-Host "Recherche par nom : $Nom"
        }
        'ID' {
            Write-Host "Recherche par ID : $ID"
        }
        'Email' {
            Write-Host "Recherche par email : $Email"
        }
    }
}

# Utilisation du jeu de paramètres par défaut (Nom)
Rechercher-Employe "Dupont"

# Utilisation explicite d'autres jeux de paramètres
Rechercher-Employe -ID 12345
Rechercher-Employe -Email "dupont@entreprise.com"

Dans cet exemple :

  • La fonction a trois jeux de paramètres : ‘Nom’, ‘ID’, et ‘Email’.
  • DefaultParameterSetName=’Nom’ signifie que si aucun paramètre n’est spécifié, PowerShell utilisera le jeu ‘Nom’.
  • Vous pouvez utiliser la fonction avec n’importe lequel des trois paramètres, mais pas simultanément.
  • Si vous appelez la fonction sans spécifier de paramètre nommé, elle s’attendra à recevoir un nom (jeu par défaut).

Cette approche est utile lorsque vous voulez offrir différentes façons de rechercher un employé, tout en ayant une méthode préférée (ici, par nom).

4.PositionalBinding

L’option PositionalBinding contrôle si les paramètres de votre fonction peuvent être utilisés de manière positionnelle (sans spécifier le nom du paramètre) ou non.

Exemple avec PositionalBinding=$true (valeur par défaut)

function Test-PositionalBinding {
    [CmdletBinding(PositionalBinding=$true)]
    param(
        [Parameter(Position=0)]
        [string]$Param1,

        [Parameter(Position=1)]
        [int]$Param2
    )

    Write-Host "Param1: $Param1, Param2: $Param2"
}

# Ces deux appels sont équivalents :
Test-PositionalBinding "Bonjour" 42
Test-PositionalBinding -Param1 "Bonjour" -Param2 42

Dans cet exemple, vous pouvez utiliser les paramètres de manière positionnelle ou nommée.

Exemple avec PositionalBinding=$false

function Test-NonPositionalBinding {
    [CmdletBinding(PositionalBinding=$false)]
    param(
        [Parameter()]
        [string]$Param1,

        [Parameter()]
        [int]$Param2
    )

    Write-Host "Param1: $Param1, Param2: $Param2"
}

# Cet appel fonctionne :
Test-NonPositionalBinding -Param1 "Bonjour" -Param2 42

# Cet appel ne fonctionnera pas comme prévu :
Test-NonPositionalBinding "Bonjour" 42  # Erreur : les paramètres ne sont pas reconnus

Avec PositionalBinding=$false, vous devez obligatoirement utiliser les noms des paramètres.

5. HelpUri
function Get-InfoSysteme {
    [CmdletBinding(HelpUri='https://mon-site.com/aide/get-infosysteme')]
    param()

    # Code pour obtenir les informations système
}

Cette option permet de spécifier une URL vers une page d’aide en ligne pour votre fonction.

Conclusion CmdletBinding

Ces options de CmdletBinding permettent de créer des fonctions PowerShell avancées avec un comportement similaire aux cmdlets natifs. Elles offrent une meilleure gestion des paramètres, des confirmations d’actions, et une intégration plus poussée avec l’environnement PowerShell.

Pour votre site modern-workplace.fr, ces exemples pourraient être utiles pour illustrer comment créer des fonctions PowerShell robustes et professionnelles dans le contexte de Microsoft 365 et de l’administration système.

function Rechercher-Livre {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$false, Position=0)]
        [string]$titre,

        [Parameter(Mandatory=$false)]
        [string]$auteur,

        [Parameter(Mandatory=$false)]
        [switch]$disponible
    )

    begin {
        Write-Verbose "Début de la recherche de livres..."
    }

    process {
        $message = "Recherche de livres"
        if ($titre) { $message += " avec le titre '$titre'" }
        if ($auteur) { $message += " de l'auteur '$auteur'" }
        if ($disponible) { $message += " actuellement disponibles" }
        Write-Verbose $message
    }

    end {
        Write-Verbose "Fin de la recherche de livres."
    }
}

Rechercher-Livre -titre "1984" -auteur "Orwell" -disponible -Verbose

Explication : Cette fonction utilise CmdletBinding pour la transformer en une fonction avancée. Elle utilise les blocs begin, process et end pour structurer le traitement, et Write-Verbose pour fournir des informations détaillées lorsque -Verbose est utilisé.

Utilisation de pipeline

function Afficher-InfoLivre {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [PSCustomObject]$livre
    )

    process {
        Write-Host "Titre: $($livre.Titre)"
        Write-Host "Auteur: $($livre.Auteur)"
        Write-Host "Année: $($livre.AnneePublication)"
        Write-Host "Genre: $($livre.Genre)"
        Write-Host "---"
    }
}

$livres = @(
    [PSCustomObject]@{Titre="1984"; Auteur="George Orwell"; AnneePublication=1949; Genre="Science-fiction"},
    [PSCustomObject]@{Titre="Le Petit Prince"; Auteur="Antoine de Saint-Exupéry"; AnneePublication=1943; Genre="Fiction"}
)

$livres | Afficher-InfoLivre

Explication : Cette fonction accepte des entrées via le pipeline grâce à ValueFromPipeline et ValueFromPipelineByPropertyName. Elle traite chaque livre passé dans le pipeline et affiche ses informations.

Les fonctions powershell
Les fonctions powershell

Gestion avancée des fonctions

Alias de fonction

New-Alias -Name rl -Value Rechercher-Livre

rl -titre "1984" -Verbose

Explication : Cette commande crée un alias ‘rl’ pour la fonction Rechercher-Livre, permettant de l’appeler plus rapidement.

Exportation de fonctions

function Export-BiblioFunctions {
    Export-ModuleMember -Function Ajouter-Livre, Rechercher-Livre, Afficher-InfoLivre
    Export-ModuleMember -Alias rl
}

Explication : Cette fonction exporte les fonctions et alias spécifiés, les rendant disponibles lorsque le module est importé dans d’autres scripts.

Utilisation de DynamicParam

function Emprunter-Livre {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$titre
    )

    DynamicParam {
        $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

        $livresDisponibles = (Get-Content "livres_disponibles.json" -Encoding UTF8 | ConvertFrom-Json).Livres

        $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $paramAttribute = New-Object System.Management.Automation.ParameterAttribute
        $paramAttribute.Mandatory = $true
        $paramAttribute.ParameterSetName = "__AllParameterSets"
        $attributeCollection.Add($paramAttribute)

        $titresASCII = $livresDisponibles.Titre | ForEach-Object { 
            [Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($_))
        }

        $validateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute([string[]]$titresASCII)
        $attributeCollection.Add($validateSetAttribute)

        $dynParam = New-Object System.Management.Automation.RuntimeDefinedParameter("LivreDisponible", [string], $attributeCollection)
        $paramDictionary.Add("LivreDisponible", $dynParam)

        return $paramDictionary
    }

    process {
        $livreChoisi = $PSBoundParameters["LivreDisponible"]
        $livreTrouve = $livresDisponibles | Where-Object { 
            [Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($_.Titre)) -eq $livreChoisi 
        }
        Write-Host "Vous avez emprunté le livre : $($livreTrouve.Titre)"
    }
}

Explication : Cette fonction utilise DynamicParam pour créer un paramètre dynamique basé sur le contenu d’un fichier JSON. Cela permet de valider le choix du livre contre une liste de livres disponibles qui peut changer dynamiquement.

{
"Livres": [
{
"Titre": "1984",
"Auteur": "George Orwell",
"Année": 1949
},
{
"Titre": "Le Petit Prince",
"Auteur": "Antoine de Saint-Exupéry",
"Année": 1943
},
{
"Titre": "Cent ans de solitude",
"Auteur": "Gabriel García Márquez",
"Année": 1967
},
{
"Titre": "L'Étranger",
"Auteur": "Albert Camus",
"Année": 1942
},
{
"Titre": "Harry Potter à l'école des sorciers",
"Auteur": "J.K. Rowling",
"Année": 1997
},
{
"Titre": "Le Seigneur des Anneaux",
"Auteur": "J.R.R. Tolkien",
"Année": 1954
},
{
"Titre": "Orgueil et Préjugés",
"Auteur": "Jane Austen",
"Année": 1813
},
{
"Titre": "Crime et Châtiment",
"Auteur": "Fiodor Dostoïevski",
"Année": 1866
},
{
"Titre": "Le Comte de Monte-Cristo",
"Auteur": "Alexandre Dumas",
"Année": 1844
},
{
"Titre": "Les Misérables",
"Auteur": "Victor Hugo",
"Année": 1862
}
]
}

Conclusion

Les fonctions en PowerShell offrent une grande flexibilité et puissance pour automatiser et simplifier la gestion d’une bibliothèque numérique. En utilisant des paramètres avancés, la validation, le pipeline et des techniques comme CmdletBinding et DynamicParam, nous pouvons créer des outils robustes et flexibles pour gérer efficacement notre collection de livres.

Liens internes

Liens externes

Comments

No comments yet. Why don’t you start the discussion?

    Laisser un commentaire

    Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *