{{tag>sysadmin windows cli powershell}} :TODO_DOCUPDATE: ====== PowerShell ====== **PowerShell** est une solution d’automatisation, le terme désigne à la fois : * Le shell ou interpréteur en ligne de commande ; * Le langage de script ; * Un framework de gestion de la configuration désigné **DSC**((**D**esired **S**tate **C**onfiguration)). Conçu initialement pour automatiser les tâches d'administration de Windows, PowerShell est à présent multiplateforme et utilisé plus largement pour de la gestion de ressources Cloud, de l'intégration/livraison continues (CI/CD) de ou de l'automatisation des flux de travail en général. Powershell possède des fonctionnalités communes à la plupart des shells : * Historique de ligne de commande ; * Autocomplétion : saisie semi-automatique via la touche Tab et prédiction ; * **Système d'aide intégrée**; * **Système de pipeline** permettant le chaînage des commandes; * Prise en charge des**alias** ou noms alternatifs pour les commandes et les paramètres rendant les appels aux traitements similaires à d'autres systèmes/Shell. Powershell a cependant quelques spécificités : * Il opère sur des objets .NET encapsulant le texte. Les commandes manipulent des objets. Cela évite beaucoup de traitements et d'opération de remise en forme ou de filtrage sur le texte. * Les commandes partagent un runtime commun et son désignée commandlets ou applets. Ce parti pris de conception permet d'offrir une expérience cohérente dans l'analyse des paramètres et le comportement des pipelines. * Il existe de nombreux types de commandes : natif, cmdlet, fonction, script, alias. Pour interagir avec PowerShell, on utilise une application qui héberge le moteur de PowerShell comme : * La console PowerShell ; * L' environnement d’écriture de scripts intégré **ISE**((PowerShell **I**ntegrated **S**cript **E**nvironment)). ===== Commentaires ===== Les commentaires sont introduits par le caractère # # Ceci est un commentaire Les commentaires permettent d'auto-documenter le code (scripts et fonctions) et peuvent être extraits par la commande **Get-Help**. Cet usage est présenté dans le wiki [[dev/powershell/integration_aide| intégration de l'aide]]. ===== Généralités sur les commandes ===== Une applet est une commande compilée. Le nom de l'applet respecte un standard "verbe-substantif" ou "action-objet". La liste des verbes standards/approuvés et leur description peut être obtenue via la commande ''Get-Verb'' Get-Verb Trois commandes permettent d'explorer les cmdlet disponibles : * **Get-Command** : lister/filtrer les commandes disponibles; * **Get-Help** : appelle l'aide intégrée d'une commande (alias help); * **Get-Member** : détaille les attributs d'un objet. # Affiche l'aide générale Powershell Help # L' alias Help permet d' obtenir l'aide paginée de la commande Get-Random Help Get-Random # En général les commandes bénéficient d'une aide plus détaillée en ligne Get-Help Get-Random -Online # Rechercher les commandes ayant pour verbe get et "network" dans le substantif Get-Command -Verb Get -Noun *network* ==== Appel d'une cmdlet ==== On peut invoquer une cmdlet via son nom, un alias ou son nom pleinement qualifié : # Exécution de la cmdlet via son nom usuel Get-Childtem # Exécution de la même cmdlet via un de ses alias ls # Exécution de la cmdlet via son nom pleinement qualifié (module\cmdlet) Microsoft.PowerShell.Management\Get-ChildItem ==== Paramètres ==== Des paramètres peuvent être spécifiés lors de l'appel d'une commande. Les paramètres permettent de modifier le comportement par défaut de la commande. Chaque commande définit ses paramètres cependant ils respectent une syntaxe et des conventions communes: * Le nom du paramètre commence par un tiret - et utilise la notation CamelCase ; * La valeur du paramètre est placée après le nom, elle est séparée par un espace ; * Si la valeur contient des espace elle doit être placée entre guillemets ; * Si le paramètre accepte plusieurs valeurs elles sont séparées par des virgules , sans espacement. # Exemple d'appel avec deux paramètres Verbe-Substantif -Param1 "valeur un" -Param2 "autre valeur",SecondeValeur,Troisieme === Les commutateurs === Le commutateur (Switch) est un cas particulier de variable booléenne : sa valeur est définie à $True uniquement si le commutateur est inclus lors de l’exécution de la commande. ===== Aide ===== Les fichiers d'aide peuvent être mis à jour, ils sont alors téléchargés. Si Powershell est lancé depuis un système Mac ou Linux il faut préciser # Préciser les locales pour Linux/MacOS Update-Help -UICulture fr-FR -Verbose # Sur un système Windows, les locales sont définies Update-Help L'aide est standardisées, elle contient les sections ^ NAME | Mnémonique de la commande. | ^ SYNTAX | Syntaxe et usage des options (indicateurs) et paramètres. | ^ ALIASES | Liste des alias existants sur la commande. | ^ REMARKS | Compléments d'informations. | ^ PARAMETERS | détail des paramètres : types, description, valeurs etc. | # Inclus la section paramètres à la réponse standard Help File-Hash -Detailed # Affiche l' aide complète Help File-Hash -Full # Seulement des exemples Help File-Hash -Examples # Informations sur un paramètre désigné Help Get-FileHash -Parameter Algorithm Des pages d'aide génériques sont également disponibles : Get-Help about* # Equivalent Get-Help -Category HelpFile ===== Version ===== Il existe deux principales plateformes pour PowerShell : * **Windows PowerShell** fournit avec l'OS et bénéficiant des mêmes licence, contrat de support et cycle de vie que l'OS. Les versions de PowerShell jusqu'à 5.1 sont incluses à un système d'exploitation Windows (binaire powershell.exe); * **PowerShell** (initalement désigné PowerShell Core) fourni, installé et configuré séparément de Windows offrant une prise en charge multiplateformes (Windows, macOS et GNU/Linux) : binaire pwsh.exe. Ces versions peuvent coexister sur un même système Windows. La variable **$PSVersionTable** stocke les informations de version de Powershell $PSVersionTable # On peut accéder à la valeur d' un attribut de l'objet en particulier $PSVersionTable.PSVersion ===== Introspection des objets ===== Les commandes retournent des objets. La réponse fournie par la commande est une mis en forme par défaut ne présentant pas forcément l'ensemble des informations disponibles dans l'objet. L' applet **Get-Member** permet d'analyser/d'introspecter l'objet retourné. On utilise Get-Member à la suite d'une commande pour obtenir les informations sur les objets retournés: # Affiche attributs et méthodes de l' objet retourné par la commande Get-Process Get-Process -Name "cmd" | Get-Member # Afficher les attributs de l'objet retourné par Get-Process Get-Process -Name "cmd" | Get-Member -MemberType Property # Affiche les méthodes de l'objet retourné par Get-Process Get-Process -Name "cmd" | Get-Member -MemberType Method En entête de la réponse, **Get-Member** indique le **type de l'objet** dont il présente les attributs et méthodes. Ce type peut être utilisée comme argument de la commande **Get-Command** pour rechercher les commandes travaillant avec le même type d'objet. # Lister les commandes manipulant des objets System.Diagnostics.Process Get-Command -ParameterType Process Les objets peuvent contenir de nombreux attributs, le filtre **Select-object** permet de filtrer/sélectionner un sous ensemble d' attributs: # Sélectionne et affiche les propriétés ProcessName et Description de l'objet # Process retourné par la commande Get-Process Get-Process -Name "cmd" | Select-Object ProcessName,Description | Format-List ===== Sortie par défaut ===== Lorsque qu'une commande s'exécute, sa sortie par défaut est dirigée vers la console (l'écran). Le formatage de cette sortie par défaut est géré par Powershell via l'ajout transparent de la commande **Out-Default**. # Commande saisie Get-Process -Name "cmd" # Commande exécutée par Powershell Get-Process -Name "cmd" | Out-Default La vue par défaut associée à l'objet ne présentent pas toutes ses propriétés. Selon les besoin, l'utilisateur peut utiliser **Select-Object** pour selectionner les attributs sur lesquels il souhaite travailler. Les commandes **Format-*** permettent d'afficher les propriétés sélectionnées sous différentes formes. ===== Tri ===== La commande **Sort-Object** permet d'effectuer des tris en fonction des propriétés des objets. # Tri décroissant sur les attributs Name puis CPU des objets Process Get-Process | Sort-Object -Descending -Property Name, CPU ===== Bonnes pratiques ===== Filtrer à gauche, c'est a dire introduire un **filtre au plus tôt** dans le pipeline de traitement afin de limiter la quantité d'objets retournés au nécessaire. - Utiliser les options de filtrages intégrées aux applets si elles existent; - Utiliser les applets de filtrage **Where-Object** et **Select-Object** au plus tôt. Terminer par la mise en forme : Le traitement de mise en forme modifie la structure des objets, l'utilisation de **Select-Object** ou d'une boucle **foreach** sur les résultats devient impossible. Ne pas utiliser d'alias dans les scripts. Les alias sont pratiques pour l'usager en mode interactif mais doivent être évités lors de l'écriture des scripts : appeler systématiquement les applets essentiellement pour les deux raisons suivantes : * Les alias peuvent être supprimés ou redéfinis dans par le script de profil; * Les alias rendent le code plus difficile à maintenir. ===== Exécution des scripts ===== De manière générale powershell tente de limiter les exécutions involontaires de la part des utilisateurs de deux façons : * Un script ne peut être exécuté qu'en précisant son chemin d'accès relatif ou absolu : cela permet de lancer explicitement le script et de ne pas le confondre avec une applet, un alias ou une fonction ; * L'application d'une **stratégie d'exécution**. La stratégie d’exécution s'appliquant par défaut peut empêcher le lancement des scripts powershell, dans ce cas un message d'erreur est retourné. La stratégie de sécurité a une étendue de définition, un périmètre (ou scope) sur lequel elle s'applique. La stratégie d'exécution n'est pas conçue comme un mécanisme de sécurité permettant de réellement limiter les actions de l'utilisateur car toutes les commandes présentes dans le script pourront être saisies manuellement. C'est simplement une fonctionnalité visant à empêcher les exécution involontaires. Les stratégies d'exécutions sont les suivantes : * **Restricted** : Aucun script ne peut être exécuté ; * **AllSigned** : Des scripts ne peuvent être exécutés que s’ils sont signés numériquement ; * **RemoteSigned** : Des scripts téléchargés ne peuvent être exécutés que s’ils sont signés numériquement ; * **Unrestricted** : Tous les scripts peuvent être exécutés, mais une invite de confirmation s’affiche lors de l’exécution de scripts non signés qui sont téléchargés ; * **Bypass** : Tous les scripts sont exécutés sans invite ; * **Undefined** : La stratégie n'est pas définie. # Retourne la stratégie d'exécution effective Get-ExecutionPolicy # Retourne les étendues d'exécution par ordre de priorité et la politique associée Get-ExecutionPolicy -List # Retourne la stratégie associée à l'étendue "CurrentUser" Get-ExecutionPolicy -Scope CurrentUser Si la stratégie effective est **undefined** la stratégie d’exécution la plus restrictive est appliquée (**Restricted**). La documentation officielle en ligne détaille les différentes [[https://learn.microsoft.com/fr-fr/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-5.1|stratégies d'exécution de powershell]]. Pour changer la politique d’exécution seulement pour le processus courant : Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned Cette modification est transitoire, elle ne sera pas conservée après terminaison du processus. Il est possible de faire des modifications permanentes : # Autorise l’exécution des scripts définis localement pour l'utilisateur courant Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned # Autorise tous les scripts pour l'utilisateur courant Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass Certaines applications peuvent marquer les fichiers de script comme provenant d'Internet, le système peut alors refuser leur exécution. L'applet **Unblock-File** permet de débloquer les scripts afin de les exécuter avec powershell. ===== Extensions des scripts ===== ^ .ps1xml | Mise en forme et configuration | ^ .psm1 | Modules de scripts PowerShell | ^ .ps1 | Scripts PowerShell | ===== Variables ===== Les variables ne sont pas uniquement destinées aux scripts et peuvent être définies via la console dans l'environnement d'exécution courant. ==== Lister les variables ==== # Lister les variables en consultant le lecteur PowerShell "Variable" Get-ChildItem Variable: # Equivalent Get-Variables PowerShell n'est pas sensible à la casse : les noms de variables $avar, $aVar ou $AVAR sont considérés identiques Par convention on utilise le CamelCase pour les labels des variables, ce n'est pas recommandé mais le nom de variable peut contenir certains caractères spéciaux. Pour créer une variable avec un nom contenant un espace utiliser la notation ''${ma variable}'' ==== Affectation/suppression ==== L'opérateur = permet d'affecter une valeur à une variable. Le retour d'une évaluation peut également être affecté : $aNumber = 10 $aService = Get-Service -ServiceName sshd # La cmdlet 'Set-Variable' peut également être utilisée Set-Variable -Name anotherNumber -Value 5 Pour supprimer le contenu d'une variable on peut lui affecter la valeur $null ou utiliser la cmdlet Clear-Variable : aNumber = $null Clear-Variable anotherNumber # Pour supprimer la variable on peut utiliser la cmdlet Remove-Item Remove-Item -Path Variable:\aNumber ==== Typage des variables ==== A l' affectation PowerShell détermine automatiquement le type de la variable. Pour lever les ambiguïtés il est possible de spécifier le type attendu. Lors de l'affectation PowerShell tentera de convertir vers le type attendu et retournera une erreur en cas d'échec. # Définition de la variable PI avec la valeur 3.14 (typage automatique) $PI = 3.14 # On peut spécifier le type souhaité d'une variable [float] $PI = 3.14 [DateTime] $today = Get-Date # Pour afficher/retourner le type de la variable $PI.GetType() # Pour afficher les attributs et méthodes de l'objet référencé par la variable $aVar | Get-Member ==== Interpolation ==== Les valeurs des variables peuvent être insérées dans des chaînes de caractères : c'est l'interpolation. [float] $PI = 3.14 # Pas d'interpolation dans les chaînes de caractères # entourées par des simples guillements Write-Host 'Pas d interpolation ici.' # Entre double guillemets les variables sont interpolées # le caractère backcote permet d'échapper une interpolation Write-Host "`$PI vaut $PI" # Retourne $PI vaut 3.14 # L'usage de $() permet de définir une expression qui sera interpolée Write-Host "`$PI vaut $($PI + 1)" # Retourne $PI vaut 4.14 ==== Portée ==== Les étendues s'imbriquent. Une étendue peut avoir une étendue parente et des étendues enfants. Par défaut les éléments (variables ou fonctions) sont visibles dans l'étendue actuelle (étendue locale) et ses étendues enfants. Ce comportement par défaut peut être modifié en rendant l'élément privé dans l'étendue. Les éléments ne peuvent être modifiés que dans l'étendue de le création. ===== Les modules ===== Le module permet de regrouper/associer des fonctionnalités (cmdlets) PowerShell : il peut être vu comme un conteneur. Cette unité peut ensuite être facilement distribuée. Pour utiliser les cmdlets d'un module, celui-ci doit être préalablement chargé via la commande **Import-Module**. A partir de Windows PowerShell 3 et supérieur, lors du premier usage d'une cmdlet le module est automatiquement chargé si toutefois il se trouve dans un des dossier de **''$env:PSModulePath''**. # Afficher les dossiers de recherche des modules $env:PSModulePath Afficher le module de la cmdlet "Get-DNSClientCache" # Le module est afficher dans la colonne "Source" Get-Command -Name Get-DnsClientCache CommandType Name Version Source ----------- ---- ------- ------ Function Get-DnsClientCache 1.0.0.0 DnsClient Retourner le nom du module associé à la commande Get-Command -Name Get-DnsClientCache | Select-Object ModuleName # lister les commandes du module "Dism" Get-Command -Module Dism ===== PowerShell Gallery ===== PowerShell Gallery est un dépôt centralisé dédié aux technologies PowerShell. A partir de Windows PowerShell 5.0 le module PowerShellGet permet de rechercher et d'installer des scripts et modules. **Find-Command** fonctionne de façon similaire à Get-Command mais permet de rechercher dans le dépôt. Le résultat filtré pourra être envoyer a **Install-Module** pour installer localement le module souhaité. Les principales cmdlets pour rechercher dans PowerShell Gallery : ^ Find-Command | | ^ Find-Script | | ^ Find-Module | | ===== Références ===== * https://learn.microsoft.com/fr-fr/training/modules/introduction-to-powershell/ * https://learn.microsoft.com/fr-fr/powershell/scripting/learn/ps101/01-getting-started?view=powershell-5.1 * https://www.powershellgallery.com/ * [[https://www.youtube.com/watch?v=UYs8Cn-qvVg|15 commandes indispensables pour débuter avec PowerShell (youtube.com) ]]