Apprendre PowerShell Part I : L’aventure généalogique de Marie avec PowerShell – Résumé

Apprendre powershell avec son arbre généalogique
Apprendre powershell avec son arbre généalogique

Marie débute en PowerShell et décide de l’utiliser pour son arbre généalogique. Suivons ses premiers pas pour apprendre le powershell.

Commentaires : Les notes de famille

Marie apprend à documenter son travail avec des commentaires.

Une ligne

Pour une note rapide sur un ancêtre :

# Jean Durand, né en 1920

Multiligne

Pour des histoires familiales plus détaillées :

<#
Pierre Durand, né en 1950
Passionné de jardinage
A transmis son amour de la nature à ses enfants
#>

Variables : Le carnet d’adresses familial

Marie découvre comment stocker les informations de sa famille.

Base

Pour enregistrer le nom de famille dans une variable :

#de façon détaillé et précise
[String]$nomFamille = "Durand" 

#de façon simple et rapide
$nomFamille = "Durand"

#de façon conventionnelle
New-Variable -Name nomFamille -Value Durand 
New-Variable -Name nomFamille -Value Durand2 -Option ReadOnly #Eviter les modifications 
New-Variable -Name nomFamille -Value Durand2 #Error  
New-Variable -Name nomFamille -Value Durand2 -Force # Sans erreur
New-Variable -Name nomdefamille -Visibility Private # pour des modules
New-Variable -Name 'nom de famille' -value 'Durant' #déclarer une variable avec des espaces
${nom de famille} #affichage et appel de la variable

#Supprimer la valeur de nomfamille
Clear-Variable -name nomfamille
#Supprimer nomfamille
Remove-Variable -name nomfamille

Plusieurs variables en une ligne

Pour noter rapidement les informations d’un membre :

$prenom, $nom, $anneeNaissance = "Marie", "Durand", 1980

#déclaration de plusieurs string en d'autre terme un tableau
[string[]]$a 
[int[]]$c = 45,89,67, "tata" #erreur
[int[]]$c = 45,89,67, 72

#limite les possibilité de la variable 
[validateset("toto", "tata", "titi")][string]$name = "titi" #Ne pourra pas prendre d'autre valeur que toto, tata ou titi

Types

Marie apprend à utiliser différents types de données pour organiser ses informations :

#Oblige la variable à être un integer
[int]$age = 43  # Nombre
$age=quarante #erreur

#Oblige la valeur de la variable à être un string
$ville = [String]"Paris"  # Mot
$ville = 15 #sans erreur

$enfants = @("Luc", "Sophie", "Marc", "Cynthia")  # Liste
$infosPierre = @{
    "Nom" = "Durand"
    "Prenom" = "Pierre"
    "AnneeNaissance" = 1950
}  # Dictionnaire

Bien sûr, je vais ajouter une nouvelle partie sur l’affichage des variables dans la section « Variables ». Voici comment cela s’intégrerait dans l’article :

Affichage des variables

Marie apprend à afficher le contenu de ses variables pour vérifier les informations qu’elle a stockées.

Pour afficher une variable simple (chaîne de caractères) :

$nomFamille

Pour afficher le contenu d’un tableau :

$enfants
$name = "tata" 
[date]$d = "01/01/2025" 

"ce nom $name me plait"  #affiche la valeur
'ce nom $name me plait'  #affiche pas la valeur
"ce nom ayant la variable `$name s'appelant $name me plait"  #affiche pas puis affiche

"le colis de $name arrive dans $($d.AddDays(1.5))" 
"le colis de $name arrive dans $($d.AddDays(5.75))" 
"le colis de $name arrive dans $(#possible d'exécuter tout même un script dans cette espace)" 

Pour afficher le contenu d’un dictionnaire :

$infosPierre

en fonction du type de variable tu aura différent attribut  
[string]$d = "01/01/2025" 
#on peut faire 
$d.padLeft(100) 
#mais pas 
$d.AddDays(- (7*6)) 

[date]$d = "01/01/2025" 
#on peut pas faire 
$d.padLeft(100) 
#mais pas
$d.AddDays(- (7*6)) 

Marie peut aussi utiliser des chaînes de caractères pour formater l’affichage de ses variables :

"La famille $nomFamille a $($enfants.Count) enfants : $($enfants -join ', ')"

Cette image montre à Marie comment visualiser les informations qu’elle a stockées dans différents types de variables, ce qui est essentiel pour vérifier et présenter les données de son arbre généalogique.

Affichage powershell des variable définit
Afficher ses variable sans boucles en powershell

Il y a un manquement de variable dans cette image seriez-vous la retrouver ? (J’attends vos réponse en commentaire)

Opérateurs : Analyser l’arbre familial

Marie utilise des opérateurs pour manipuler ses données familiales.

Arithmétique

Pour calculer l’âge d’un ancêtre :

$ageAncetre = 2023 - 1920

Ceci fonctionne aussi bien avec les additions (+), les multiplications (*), les divisions (/), les reste en division (%)

$ageFamilliale = 2023 - 1920 + 10

Logique

Pour vérifier si un membre est majeur :

$estMajeur = ($age -ge 18)

Comparaison

Voici ses exemples pour chacun de ces opérateurs de comparaison en PowerShell :

  1. -eq (égal à)
$age = 30
if ($age -eq 30) { "Vous avez 30 ans" }
  1. -in (dans)
$fruit = "pomme"
if ($fruit -in @("pomme", "banane", "orange")) { "C'est un fruit que j'aime" }
  1. -like (correspond au motif)
$nom = "Jean-Pierre"
if ($nom -like "Jean*") { "Le nom commence par Jean" }
  1. -le (inférieur ou égal à)
$temperature = 20
if ($temperature -le 25) { "Il fait bon" }
  1. -replace (remplacer)
$phrase = "J'aime les chats"
$nouvellePhrase = $phrase -replace "chats", "chiens"
$nouvellePhrase  # Affiche : "J'aime les chiens"

Voici quelques autres opérateurs de comparaison courants :

  1. -ne (différent de)
$couleur = "rouge"
if ($couleur -ne "bleu") { "La couleur n'est pas bleue" }
  1. -gt (supérieur à)
$score = 85
if ($score -gt 80) { "Excellent score!" }
  1. -contains (contient)
$fruits = @("pomme", "banane", "orange")
if ($fruits -contains "banane") { "Nous avons des bananes" }
  1. -match (correspond à l’expression régulière)
$email = "user@example.com"
if ($email -match "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") { "Email valide" }

Ces exemples vous donnent un aperçu de l’utilisation de ces opérateurs. Ils sont très utiles pour effectuer des comparaisons et des manipulations de chaînes en PowerShell.

opérateur de comparaison powershell
opérateur de comparaison powershell

Affectation

Pour créer un nom complet :

$agePapa++ # Ajoute plus 1 (soit 1an) à son age 
$agePapa-- #Soustration moins 1
$AgeGrandPapa *= 3 #Multiplier par 3

Incrémentation plus 3 ans:

$agePapa += 3 # Ajout à agePapa 
$agePapa -=3 #Soustration à agePapa 
$AgeGrandPapa /= 3 #Divisier à AgeGrandPapa 

Type

Pour vérifier le type de données d’une information :

5 -is [int] #True
500 -isnot [string] #True
"05/07/1980" -as [datetime]

Redirection

Pour sauvegarder le nom de famille dans un fichier :

$nomFamille > "famille.txt" #ajout dans un nouveau fichier
$nomFamille >> "famille.txt" #ajout à la suite du fichier

L’opérateur de redirection d’erreur (2>)

L’opérateur 2> redirige uniquement les messages d’erreur vers un fichier. Par exemple :

Get-Process nonexistentprocess 2> errors.txt

Cette commande redirige les erreurs générées par la recherche d’un processus inexistant vers le fichier errors.txt.

L’opérateur de redirection de sortie et d’erreur (&>)

L’opérateur &> redirige à la fois la sortie standard et les erreurs vers un même fichier. Par exemple :

Get-ChildItem C:\ -Recurse &> output_and_errors.txt

Cette commande redirige toutes les sorties et erreurs lors de la liste récursive des fichiers de C:\ vers un seul fichier.

L’opérateur de redirection de flux spécifique (n>)

PowerShell permet de rediriger des flux spécifiques en utilisant les numéros 1 à 5. Par exemple :

  • 1> : Redirige la sortie standard (équivalent à >)
  • 2> : Redirige les erreurs
  • 3> : Redirige les avertissements
  • 4> : Redirige les informations détaillées
  • 5> : Redirige les messages de débogage
  • *> : Redirige la sortie erreurs

L’opérateur de redirection vers la sortie standard (*)

L’opérateur * peut être utilisé pour rediriger tous les flux vers la sortie standard (l’erreur comme le bon). Par exemple :

Get-Service -Name Wide, WinRm *> t

#ou nous aurons un output en plus du fichier

Get-Service -Name Wide, WinRm > ta 2>&1
#ou 
Get-Service -Name Wide, WinRm 2>&1 | out-file -fliepath ta

Fractionnement & Jointure

Pour séparer un nom complet :

$nomComplet = "Jean Durand"
$prenom, $nom = $nomComplet.Split()

Affichage des résultats

Marie durant veut apprendre le powershell

Marie apprend à afficher les résultats de ses opérations pour vérifier ses analyses familiales. Elle peut combiner différents opérateurs et variables dans une seule instruction d’affichage :

"$prenom $nom est un membre de la famille Durand : $($nom -eq 'Durand'). Né(e) en $anneeNaissance, son âge est de $((Get-Date).Year - $anneeNaissance) ans."

Cette ligne combine l’affichage de variables, l’utilisation d’opérateurs de comparaison, et des calculs arithmétiques pour présenter un résumé concis des informations sur un membre de la famille.

Affichage Powshell des opérateur
Affichage Powshell des opérateur

Fonctions : Automatiser les tâches généalogiques

Marie crée des fonctions pour simplifier ses recherches.

Créer une fonction

Pour calculer l’âge à partir de l’année de naissance :

function CalculerAge($anneeNaissance) {
    return 2023 - $anneeNaissance
}

Appeler la fonction

Pour utiliser la fonction et obtenir l’âge :

$ageMarie = CalculerAge 1980

Paramètres dynamiques dans les scripts

L’utilisation de paramètres dans les scripts est une astuce essentielle pour créer des scripts flexibles et réutilisables :

Function t {
    Param(
        [string]$toto = 'tutu',
        [int]$age = 50
    )
    Write 'tttttttttttt'
}

Cette approche permet de modifier les variables du script lors de son exécution, par exemple :

PS C:\>t -toto titi
PS C:\>t -age titi #erreur

Création de cmdlets personnalisées

La création de cmdlets personnalisées est une astuce PowerShell avancée qui permet d’étendre les fonctionnalités de PowerShell :

Function tata {
    [cmdletBinding()]
    Param(
        [parameter(mandatory=$true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage="Mon message d'aide ne t'aide pas 😀 ")]
        [Alias('existence','generation')]
        [allowEmptyString()]
        [allowEmptyCollection()]
        [string[]]$toto ,
        [validateset('12','80')]
        [allowNull()]
        [int]$age = 50,
        [validateRange(0,5)]
        [int]$bebe
    )
    
    Write 'ton age est :' + $age + ' et ton nom est' + $toto
}

Cette fonction illustre l’utilisation de plusieurs attributs avancés pour créer une cmdlet robuste et flexible.

Gestion des fonctions

Lister et supprimer des fonctions

Pour gérer efficacement vos fonctions, vous pouvez utiliser ces astuces PowerShell :

Get-PSDrive
dir function # affiche toutes les fonctions 
Remove-Item function:\Ma_fonction # supprime la fonction 

Utilisation des blocs Begin, Process et End

La structure Begin-Process-End est une astuce puissante pour optimiser le traitement des pipelines :

function fufu { 
    begin {  write "tata" }
    process {  write "titi "}
    end {  write "toto" }
}

1..5 | fufu 

Cette structure permet d’exécuter du code avant, pendant et après le traitement des éléments du pipeline.

Tableaux & Dictionnaires : Organiser l’arbre généalogique

Marie utilise des structures de données pour mieux organiser ses informations.

Création tableau

Pour lister les enfants :

$enfants = @("Luc", "Sophie", "Thomas")

#ou forme unitaire (un tableau avec un membre)
$enfant = ,luc

#ou forme binaire (un tableau avec plusieurs membre)
$binaire = luc, sophie, thomas

L’ajout d’un élément se fait avec l’opérateur += (dans ce cas de figure on ajoute un nouvelle enfant)

$enfants += Joe

Manipulation tableau

Pour mettre à jour la liste des enfants :

# Modifier la 2e valeur
$enfants[1] = "Sophie-Anne"  # par "Sophie-Anne"
$enfants.SetValue("lia",1)  # par "Lia"

Quand vous écrivez « $enfants[0,2] », vous créez en fait un nouveau tableau contenant les éléments aux indices 0 et 2 du tableau original.

$enfants = $enfants[0,2]  # Supprimer une valeur (Sophie-Anne)

Connaitre le nombre de valeur qu’il y a dans le tableau

$enfants.Count

Récupération d’information et possibilité

Un tableau étant un objet .NET, nous pouvons faire cette commande cmdlet pour voir les possibilité :

Get-Member -InputObject $enfants
Possibilité de manipulation de tableau powershell
Possibilité de manipulation de tableau powershell

Création dictionnaire

Pour stocker les informations détaillées d’un membre :

$infosMarie = @{
    "Nom" = "Durand"
    "Prenom" = "Marie"
    "AnneeNaissance" = 1980
}

Manipulation dictionnaire

Pour mettre à jour les informations :

$infosMarie["Ville"] = "Lyon"  # Ajouter une valeur
$infosMarie.Remove("AnneeNaissance")  # Supprimer une valeur

Récupération d’information et possibilité

Un dictionnaire étant un objet .NET, nous pouvons faire cette commande cmdlet pour voir les possibilité :

Get-Member -InputObject $infosMarie
Possibilité de manipulation de dictionnaire powershell
Possibilité de manipulation de dictionnaire powershell

Structure conditionnelle : Analyser les relations familiales

Marie utilise des conditions pour classer les membres de sa famille.

If

Pour vérifier si une personne est un ancêtre :

if ($anneeNaissance -lt 1950) {
    $statut = "Ancêtre"
}

Simplification des structures conditionnelles

PowerShell permet de simplifier les structures conditionnelles, une astuce particulièrement utile pour rendre le code plus concis :

$status = '' 
$out = if ($status) {0} else {1}

Else

Pour distinguer les générations :

if ($anneeNaissance -lt 1950) {
    $statut = "Ancêtre"
} else {
    $statut = "Génération récente"
}

Switch

Pour catégoriser les membres par génération :

switch ($anneeNaissance) {
    {$_ -lt 1950} { $generation = "Anciens" }
    {$_ -ge 1950 -and $_ -lt 1980} { $generation = "Parents" }
    {$_ -ge 1980} { $generation = "Jeunes" }
}

Optimisation des instructions switch

L’utilisation du switch peut être optimisée pour une assignation directe :

$status = 3 
$out = switch ($status) { 
   0 { 'ok' } 
   1 { 'Nok' } 
   2 { 'over' } 
   3 { 'overload' } 
   4 { 'overwhelming' } 
   default { 'no_idea'} 
}

Boucles : Parcourir l’arbre généalogique

Marie apprend à parcourir efficacement ses données familiales.

For

Pour numéroter les enfants :

for ($i = 0; $i -lt $enfants.Count; $i++) {
    $enfantsNumerotes += "Enfant $($i+1): $($enfants[$i])`n"
}
  • Utilisé quand on connaît à l’avance le nombre d’itérations
  • Syntaxe : for ($i=0; $i -lt 10; $i++) { ... }
  • Permet un contrôle précis sur l’index et les conditions d’itération
  • Généralement plus verbeux que les autres options

ForEach

Pour afficher les informations de chaque membre :

foreach ($membre in $famille) {
    $infoMembre += "Nom: $($membre.Nom), Prénom: $($membre.Prenom)`n"
}
  • Utilisé pour itérer sur tous les éléments d’une collection
  • Syntaxe : foreach ($item in $collection) { ... }
  • Charge toute la collection en mémoire avant de commencer l’itération
  • Plus rapide pour les petites à moyennes collections
  • Meilleure lisibilité pour les boucles simples

L’opérateur de plage

L’opérateur de plage (..) est une astuce PowerShell puissante pour générer des séquences de nombres ou manipuler des tableaux :

1..10
60..9
$s = Get-Service
$s[5..2]

#on peut utiliser dans le sens 
$s.Name | % { write " Nous avons la famille dans le service $_ "}
#dont % est un foreach-object

ForEach-Object

  • Utilisé principalement dans les pipelines PowerShell
  • Syntaxe : $collection | ForEach-Object { ... }
  • Traite les éléments un par un à mesure qu’ils arrivent dans le pipeline
  • Plus efficace en mémoire pour les grandes collections
  • Permet l’utilisation de $_ ou $PSItem pour référencer l’élément courant
  • Offre des blocs Begin, Process et End
  • Supporte le traitement parallèle avec -Parallel (PowerShell 7+)

Les principales différences sont :

  1. Utilisation : For pour un nombre connu d’itérations, ForEach pour des collections en mémoire, ForEach-Object pour le traitement en pipeline.
  2. Performance : ForEach est généralement plus rapide pour les petites collections, ForEach-Object est plus efficace en mémoire pour les grandes collections.
  3. Syntaxe : ForEach-Object utilise $_ ou $PSItem, les autres utilisent une variable nommée.
  4. Flexibilité : ForEach-Object offre plus d’options comme le traitement parallèle et les blocs Begin/End.

Le choix entre ces boucles dépend donc du contexte d’utilisation, de la taille des données traitées et de la nécessité ou non d’utiliser le pipeline PowerShell.

While

La boucle while en PowerShell est une structure de contrôle qui permet d’exécuter un bloc de code de manière répétitive tant qu’une condition spécifiée est vraie. Voici sa syntaxe de base :

#Syntaxe de base de while
while (condition) {
    # Bloc de code à exécuter tant que la condition est vraie
}

Pour remonter les générations jusqu’à un ancêtre spécifique :

$anneeActuelle = 2023
while ($anneeActuelle -gt 1850) {
    Write "Nous sommes dans les années $anneeActuelle "
    $anneeActuelle -= 25
}
Apprendre powershell avec son arbre généalogique
Apprendre powershell avec son arbre généalogique

Fonctionnement de la boucle until

La boucle until en PowerShell est une structure de contrôle qui présente des caractéristiques uniques par rapport aux autres types de boucles.

La boucle until en PowerShell s’utilise généralement sous la forme do...until :

do {
    # Code à exécuter
} until ($condition)

Caractéristiques principales :

  1. Le bloc de code s’exécute au moins une fois avant que la condition ne soit évaluée.
  2. La boucle continue à s’exécuter jusqu’à ce que la condition devienne vraie.
  3. Une fois la condition vraie, la boucle se termine.

Exemple concret

Voici un exemple illustrant l’utilisation de until pour valider une entrée utilisateur :

do {
    $input = Read-Host "Entrez un nombre entre 1 et 10"
    $number = [int]$input
} until ($number -ge 1 -and $number -le 10)

Write-Host "Vous avez entré un nombre valide : $number"

Dans cet exemple, la boucle continue à demander une entrée à l’utilisateur jusqu’à ce que le nombre saisi soit entre 1 et 10.

En résumé, la boucle until est particulièrement utile lorsque vous voulez exécuter un bloc de code au moins une fois et continuer jusqu’à ce qu’une condition spécifique soit remplie. Elle offre une alternative élégante aux autres types de boucles dans certains scénarios, notamment lorsque la logique de sortie est plus naturellement exprimée comme « continuer jusqu’à ce que » plutôt que « continuer tant que ».

Exemple de combinaison: foreach en mode parallèle + while

Pour exécuter une boucle while en parallèle, nous pouvons utiliser la cmdlet Start-Job ou ForEach-Object -Parallel (disponible à partir de PowerShell 7). Voici un exemple utilisant ForEach-Object -Parallel :

$maxJobs = 5
$jobsRunning = 0

1..10 | ForEach-Object -Parallel {
    $jobId = $_
    $counter = 0
    while ($counter -lt 5) {
        Write-Host "Job $jobId : Itération $counter"
        $counter++
        Start-Sleep -Seconds (Get-Random -Minimum 1 -Maximum 5)
    }
} -ThrottleLimit $maxJobs

Dans cet exemple :

  1. Nous définissons $maxJobs pour limiter le nombre de jobs parallèles à 5.
  2. Nous utilisons ForEach-Object -Parallel pour créer 10 jobs parallèles.
  3. Chaque job exécute une boucle while qui :
    • S’exécute 5 fois ($counter -lt 5)
    • Affiche le numéro du job et l’itération actuelle
    • Incrémente le compteur
    • Attend un temps aléatoire entre 1 et 5 secondes
  4. Le paramètre -ThrottleLimit $maxJobs limite le nombre de jobs s’exécutant simultanément à 5.

Conclusion

Cette approche permet d’exécuter plusieurs boucles while en parallèle, chacune dans son propre runspace, ce qui peut considérablement améliorer les performances pour certains types de tâches, en particulier celles qui impliquent des opérations d’entrée/sortie ou des attentes. Il est important de noter que l’exécution parallèle introduit des complexités supplémentaires, notamment en termes de gestion de la concurrence et de partage des ressources. Assurez-vous que votre code est thread-safe si vous manipulez des ressources partagées dans les boucles parallèles.

Marie a découvert les bases de PowerShell pour gérer son arbre généalogique. Elle peut maintenant stocker, manipuler et analyser les informations de sa famille Durand de manière simple et efficace. Vous avez également appris comment apprendre le powershell est simple, alors je vous retrouve la semaine prochaine même heure même endroit pour apprendre le powershell de manière plus pousser.

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 *