Initiation aux scripts Microsoft Powershell /// Ressources utilisées : PowerShell Scripting – Get started with this Ultimate Guide Scripts PowerShell : tutoriel destiné aux débutant(e)s Introduction to PowerShell Scripting Paramètres La politique d’exécution des scripts Learn Windows PowerShell in a Month of Lunches Planifiez vos tâches avec des scripts PowerShell sur Windows Server L’objectif de cet atelier est d’apprendre les principes fondamentaux de l’écriture de scripts dans Microsoft Powershell : Écriture et exécution de scripts Utilisation de variables et fonctions pour rendre les scripts flexibles Utilisation de structures de contrôle (tests, boucles) pour déterminer les bons traitements à appliquer et/ou les effectuer de manière répétitive Gestion des erreurs pour apporter plus de robustesse aux scripts Pour cela, on va s’appuyer sur l’écriture d’un script Microsoft Powershell dont le rôle sera de détecter l’état — activé ou désactivé — du pare-feu Windows sur les différents profils (Privé/Domaine/Public) et proposer de le ré-activer le cas échéant. Compte rendu Reporter les commandes saisies pour répondre aux questions ainsi que leurs résultats d’exécution. 💻 Travail n° 1 Écriture et exécution de scripts depuis VSCode 🕮 Apport de connaissances : Il est possible d’écrire des scripts Microsoft Powershell avec un simple éditeur de texte comme le Bloc-notes Windows ou Notepad++ mais VSCode est doté de fonctions qui en facilitent l’écriture : coloration syntaxique auto-complétion détection d’erreurs organisation des scripts en projets … VSCode permet enfin d’exécuter les scripts sans quitter l’éditeur. 🎯 Travail à faire : Télécharger en local depuis le NAS l’extension “Powershell” (→ \\Diskstation\install\vscode\extensions\ms-vscode.PowerShell-<version>.vsix) L’installer depuis VSCode et recharger l’IDE comme proposé Créer un fichier test.ps1 dans votre répertoire de travail (ex. : ~/Documents) avec la cmdlet suivante : Write-Host -ForegroundColor green "Youpi ! ça marche !" …puis l’exécuter pour vérifier le bon fonctionnement À retenir : Un script Microsoft Powershell porte l’extension .ps1. 💻 Travail n° 2 Stratégies d’exécution 🕮 Apport de connaissances : Pour éviter tant que possible l’exécution de scripts malveillants, Windows met en place des stratégies d’exécution qui vont autoriser plus ou moins de choses : AllSigned Bypass Default RemoteSigned Restricted Undefined UnRestricted Voir Stratégies d’exécution PowerShell pour une description de ces différentes stratégies d’exécution. On a de plus la possibilité de définir une stratégie d’exécution pour une étendue particulière : l’ordinateur local (→ LocalMachine) pour l’utilisateur actuel (→ CurrentUser) pour une session particulière (→ Process) les ordinateurs d’un domaine (→ MachinePolicy) les utilisateurs d’un domaine (→ UserPolicy). 🎯 Travail à faire : Exécuter la cmdlet Get-ExecutionPolicy -List pour afficher la statégie d’exécution en cours sur chacune des étendues. Se référer à l’aide de la cmdlet Set-ExecutionPolicy et mettre en place une stratégie d’exécution RemoteSigned sur l’étendue LocalMachine 💻 Travail n° 3 Boucles 🕮 Apport de connaissances : Microsoft Powershell propose plusieurs instructions pour faire des boucles : for (…) {…} Exemple : For ($i = 0; $i -le 10; $i++) { Write-Host "'i' vaut $i" } ForEach(…) {…} Exemple : $heros = ("superman", "batman") ForEach($hero in $heros) { Write-Host "Nom Super-Héro : $hero" } Do {…} While(…) Exemple : Do { Write-Host "!! Risque de verglas !!" } While(temperature -lt 3) 🎯 Travail à faire : Créer un fichier firewall.ps1 dans lequel vous afficherez dans une boucle les propriétés name et Enabled de chaque objet retourné par la cmdlet Get-NetFirewallProfile sachant que celle-ci retourne un tableau parcourable grâce à l’instruction ForEach. Pour afficher une propriété d’une variable au sein d’une chaîne de caractères on doit utiliser l’opérateur de sous-expression (→ $()). Exemple PS > $today = Get-Date PS > Write-Host "Jour de la semaine : $today.DayOfWeek" (1) Jour de la semaine : 11/27/2023 12:37:38.DayOfWeek # NOK (2) PS > Write-Host "Jour de la semaine : $($today.DayOfWeek)" (3) Jour de la semaine : Monday # OK (4) 1 En écrivant $today.DayOfWeek on pense qu’on va afficher la propriété DayOfWeek de la variable $today… 2 … or on voit que DayOfWeek n’a pas été interprété comme le nom d’une propriété mais comme du texte littéral (c-à-d sans signification particulière). On affiche donc la date complète suivi de “.DayOfWeek” 3 On utilise cette fois-ci l’opérateur de sous-expression $() pour demander à Microsoft Powershell d’interpréter tout ce qu’il y a entre parenthèses et là… 4 …on vérifie qu’on affiche bien le jour de la semaine Voir How can you use an object’s property in a double-quoted string? pour un résumé des règles d’interpolation des variables dans les chaînes entre guillemets doubles. Résultat attendu : PS > .\ctrl-firewall.ps1 Parefeu du profil " Domain " -> True Parefeu du profil " Private " -> True Parefeu du profil " Public " -> True 💻 Travail n° 4 Structures conditionnelles 🕮 Apport de connaissances : Dans les scripts, on devra souvent tester des conditions pour décider si certaines commandes doivent être exécutées ou pas. Microsoft Powershell propose, comme dans la plupart des langages de programmation, une instruction If … ElseIf … Else … pour faire des tests. Les opérateurs de comparaison mis à disposition par Microsoft Powershell diffèrent cependant quelque peu de ceux des langages C++ ou Javascript par exemple : -eq→ “… égal à …” -le → “… inférieur ou égal à …” -ge → “… supérieur ou égal à …” -gt → “… supérieur à …” -lt → “… inférieur à …” Exemple $Age = 21 If ($Age -ge 18) { Write-Host "Vous êtes majeur" } Else { Write-Host "Vous êtes mineur" } L’opérateur -not permet d’inverser le sens de l’opérateur de comparaison : Exemple $vitesse = 75 If (-not ($vitesse -lt 80) ) { Write-Host "Dépassement vitesse autorisée" } Il est possible de combiner plusieurs tests avec les opérateurs : -or -and -xor Exemple If (($pH -ge 7) -and ($pH -le 7.4)) { Write-Host "Le Ph de la piscine est OK" } Enfin, pour tester si une condition est vraie ou fausse, Microsoft Powershell dispose de 2 constantes : $True et $False. Exemple If( ($allumageAuto -eq $True) -and ($luminosite -lt 15) ) { Write-Host "Allumage des feux de croisement" } 🎯 Travail à faire : Faire évoluer le script firewall.ps1 pour qu’il affiche en couleur l’état d’activation du firewall. Voir pour cela les options “-ForegroundColor"` et/ou "`-BackgroundColor” de la cmdlet Write-Host. Exemple de résultat attendu PS > .\firewall.ps1 Parefeu du profil "Domain" : Activé Parefeu du profil "Private" : Désactivé Parefeu du profil "Public" : Activé Modifier le script pour qu’il propose de réactiver — via la cmdlet Set-NetFirewallProfile — le parefeu sur le(s) profil(s) sur le(s)quel(s) il est désactivé. Ceci nécessite d’exécuter Microsoft Powershell en tant qu’administrateur. La cmdlet Read-Host permet à l’utilisateur de faire une saisie depuis la console. Exemple de résultat attendu PS > .\firewall.ps1 Parefeu du profil "Domain" : Activé Parefeu du profil "Private" : Désactivé Parefeu du profil "Public" : Désactivé Voulez-vous réactiver le parefeu pour le profil " Private " ? [Y/n] : Y Parefeu du profil "Private" : Activé Voulez-vous réactiver le parefeu pour le profil " Public " ? [Y/n] : Y Parefeu du profil "Public" : Activé PS > .\firewall.ps1 Parefeu du profil "Domain" : Activé Parefeu du profil "Private" : Activé Parefeu du profil "Public" : Activé 💻 Travail n° 5 Paramètres d’un script 🕮 Apport de connaissances : Il est possible de fournir aux scripts des paramètres comme on le fait pour les cmdlets de façon à les rendre plus flexibles. Pour déclarer un paramètre, on utilise un “bloc” Param()`. Dans ce bloc, les paramètres seront représentés par des variables dont le nom est défini par l’utilisateur. Le nom des paramètres à saisir lors de l’appel du script dépendra alors directement du nom de la variable qui lui est associée. Exemple : welcome.ps1 Param( [Parameter(Mandatory, HelpMessage = "Saisir un code de pays (en majuscules) SVP")] [ValidateNotNullOrEmpty()] [string]$IsoCode, (1) [Parameter(HelpMessage = "Force l'intitulé de la question en majuscules")] [switch]$Upper (2) ) Switch($IsoCode) { (3) 'EN' {$question = "Input your name"} 'FR' {$question = "Saisir votre nom"} } if($Upper) { (3) $question = $question.ToUpper() } $input = Read-Host $question Switch($IsoCode) { (3) 'EN' { Write-Host "Hello $input !"} 'FR' { Write-Host "Bonjour $input !"} } 1 On définit un paramètre (→ -IsoCode) obligatoire (→ Mandatory) de type chaîne (→ string) 2 On définit un paramètre (→ -Upper) optionnel à bascule (→ switch) 3 On adapte le traitement aux valeurs fournies aux paramètres lors de l’appel du script Exemple de résultat d’exécution PS > .\welcome.ps1 -IsoCode EN -Upper INPUT YOUR NAME: Ragnar (1) Hello Ragnar ! PS > .\welcome.ps1 -IsoCode EN Input your name: Ragnar (2) Hello Ragnar ! PS > .\welcome.ps1 -IsoCode FR -Upper SAISIR VOTRE NOM: Ragnar (3) Bonjour Ragnar ! PS > .\welcome.ps1 -Upper (4) cmdlet welcome.ps1 at command pipeline position 1 Supply values for the following parameters: (Type !? for Help.) IsoCode: EN INPUT YOUR NAME: Ragnar Hello Ragnar ! 1 Intitulé question en anglais et majuscules 2 Intitulé question en anglais et minuscules 3 Intitulé question en français et majuscules 4 Comportement quand le paramètre obligatoire (→ -IsoCode) n’est pas fourni 🎯 Travail à faire : S’inspirer de l’exemple de script welcome.ps1 pour compléter le script firewall.ps1 pour qu’il accepte un paramètre -Force de type “switch” dont le rôle sera de forcer l’activation du parefeu sur le(s) profil(s) sur le(s)quel(s) il est désactivé sans devoir passer par une confirmation de l’utilisateur 🞄 🞄 🞄 1er pas avec Microsoft Powershell Linux