Powershell en 10 min: les cmdlets (partie 2)

Le but de cet article est de détailler l’utilisation des commandes Powershell. Ces commandes s’appellent des “command-lets” mais l’abbréviation cmdlets est couramment utilisée pour les désigner.
Les cmdlets peuvent être exécutées dans une console Powershell directement ou dans un script .ps1.

Les commandes disponibles en Powershell sont plus nombreuses et plus perfectionnées que les commandes batch classiques:

  • Commandes batch: on peut utiliser les mêmes commandes batch en powershell comme: cd, dir, copy etc…
  • Commandes Linux: on peut utiliser des commandes provenant de Linux comme: cd, ls, cp etc…
  • Commandes cmdlet: ce sont des commandes spécifiques à Powershell (cmdlet se prononce “command-let”).

La syntaxe des cmdlets est souvent la même c’est-à-dire:

<Verbe>-<Nom>

On peut trouver le verbe et nom en minuscules ou avec la première lettre en majuscule comme, par exemple:
Get-Help, Get-Command etc…

Powershell n’est pas sensible à la casse

Powershell n’est pas sensible à la casse, les commandes écrites en majuscules ou en minuscules seront interprétées de la même façon. De même, Powershell n’est pas sensible aux espaces ou tabulations.

Dans le cas où la cmdlet comporte un argument sous forme d’option, la syntaxe que l’on peut rencontrer peut être de la forme:

<verbe>-<nom> -<nom_option> <valeur de l'option>

Par exemple:

Start-Service -name eventlog

PowerShell Module Browser

Microsoft a mis en place un browser capable d’afficher de l’aide sur toutes les commandes Powershell: PowerShell Module Browser.
Ce browser est particulièrement efficace puisqu’il permet d’accéder aux pages d’aides pour toutes les commandes et pour toutes les versions de Powershell.
On peut, d’autre part, restreindre la recherche à une version spécifique en cliquant sur “Tous les paquets” et en sélectionnant la version adéquate.

Alias

Il est possible d’utiliser des alias pour raccourcir le nom des cmdlets. Ces alias ne sont pas forcément clairs toutefois ils permettent de raccourcir des cmdlets fréquemment utilisées.

Afficher les “alias”

Get-Alias permet d’afficher tous les alias.

Get-ChildItem est un équivalent de ls.

Paramétrer un “alias” personnalisé

On peut paramètrer des alias personnalisés en utilisant la syntaxe suivante:

Set-Alias <nom de l´alias> <commande à exécuter>

Par exemple:

Set-Alias list Get-ChildItem

La durée de vie de l’alias est égal à celle de l’invite de commande Powershell. Si on la ferme, l’alias est perdu.

Persister un “alias”

Pour persister un alias, on peut utiliser la commande Export-Alias:

Export-Alias "<fichier CSV où l´alias sera sauvegardé>" <nom de l´alias>

Récupérer un “alias” sauvegardé

Pour récupérer un alias sauvegardé dans un fichier CSV:

Import-Alias "<chemin du fichier CSV où l´alias a été sauvegardé>" 

Quelques exemples de “cmdlets”

Afficher toutes les commandes

Pour afficher toutes les commandes disponibles:

Get-Command

On peut ajouter des arguments pour chercher suivant un critère particulier:

Get-Command –verb "<nom du verbe>" 
Get-Command –noun "<nom à chercher>"

Changer le répertoire courant

Pour changer le répertoire courant:

Set-Location "<chemin du répertoire>" 

Plus simplement on peut utiliser les alias proches des commandes utilisées sur Linux ou sur le batch comme cd.

Lister le contenu d’un répertoire

Pour avoir le contenu d’un répertoire:

Get-ChildItem

L’alias pour cette commande est ls.

Afficher de l’aide

Pour afficher de l’aide sur les commandes, on peut écrire:

Get-Help <nom de la commande>

Pour afficher l’aide concernant une commande avec des exemples, on peut écrire:

Get-Help <nom de la commande> -examples

On peut aussi utiliser pour avoir de l’aide:

<nom de la commande> -?

Par exemple:

Get-Command -? 

Effacer le contenu d’une console

Pour effacer le contenu de la ligne de commandes:

Clear-Host

Afficher l’historique de la console

Il suffit de taper:

Get-History

Avoir la liste des processus

Pour avoir la liste des processus en cours d’exécution sur la machine, on peut exécuter:

Get-Process

Lancer un processus

Pour lancer un processus, on peut utiliser la commande Start-Process avec le chemin de l’exécutable. En utilisant cette commande avec un fichier, un programme par défaut se lancera suivant l’extension
de ce fichier, par exemple:

$filePath = "example.csv" 
$process = Start-Process $filePath

On peut aussi lancer un programme avec des arguments de cette façon:

$args = "customFile.txt"
& 'C:\Windows\System32\notepad.exe' $args

Référencer un autre fichier .ps1

Pour référencer à un autre fichier de scripts .ps1 de façon à utiliser les fonctions qu’il contient, on peut écrire:

Import-Module "<chemin du fichier .ps1>"

Retarder l’exécution

On peut mettre en pause l’exécution pendant quelques secondes en écrivant:

Start-Sleep -Seconds 3
Ecrire une commande sur plusieurs lignes

On peut écrire une commande sur plusieurs lignes en utilisant le caractère ` (accent grave), ce caractère est accessible avec la combinaison [AltGr] + [7].

Par exemple si on écrit la commande suivante, elle sera interprétée en une seule ligne:

Get-Process | `
where-Object {$_.Name -like "powershell"} | `
Select-Object Id

Mettre en forme des données

Certaines commandes renvoient des listes d’éléments, il est possible de mettre en forme ces éléments pour rendre plus lisible leur lecture. Cette mise en forme peut se faire en utilisant:

  • Format-List: pour lister tous les éléments sous la forme d’une liste avec une seule colonne.
  • Format-Table: pour lister les éléments sous la forme d’un tableau avec plusieurs colonnes.
  • Format-Wide: pour lister les éléments sous la forme de plusieurs colonnes, on peut choisir le nombre de colonnes.

Par exemple:

Get-Process | Format-List
Get-Process | Format-Table 

# Pour mettre en forme sur 3 colonnes
Get-Process | Format-Wide -Column 3

Chaines de caractères

Comme en .NET, les chaines de caractères sont identifiées par des quotes:

$var="classic string"

Par défaut, les variables utilisées dans les chaines de caractères avec des double quotes (cf. " ") sont remplacées par leur valeur. Ainsi si on écrit:

$a="powershell"
Write-Host "classic $a string"

On aura:

classic powershell string

Pour que les variables à l’intérieur d’une chaine de caractères ne soient pas interprétées, il faut définir la chaine avec quotes simples (cf. ' '):

$b='classic $a string'
Write-Host $b

Le résultat sera:

classic $a string

Pour définir une chaine de caractères sur plusieurs lignes, on utilise les caractères @. Les variables se trouvant dans une chaine définie avec @ sont interprétées.

Par exemple:

$bigString= @"
      Ligne 1
      Ligne 2
      Variable: $a
      Ligne 3 etc...
"@
Write-Host $bigString

Le résultat sera:

      Ligne 1
      Ligne 2
      Variable: powershell
      Ligne 3 etc...

Pour ne pas interpréter les variables avec l’utilisation du caractère @, il faut précéder la variable avec ` (` est le caractère accent grave accessible avec [AltGr] + [7]). Avec la chaine précédente, on aurait:

$bigString= @"
      Ligne 1
      Ligne 2
      Variable: `$a
      Ligne 3 etc...
"@
Write-Host $bigString

Dans ce cas le résultat sera:

      Ligne 1
      Ligne 2
      Variable: $a
      Ligne 3 etc...

Retour à la ligne

Pour effectuer des retours à la ligne dans une chaine de caractères, on peut utiliser `n (` est le caractère accent grave accessible avec [AltGr] + [7]):

$c="Retour à la ligne: `n Nouvelle ligne"
Write-Host $c

Le résultat sera:

Retour à la ligne:
Nouvelle ligne
Tabulation

On peut aussi noter le caractère `t pour désigner une tabulation dans une chaine de caractères.

Utiliser le Framework .NET

Powershell est basé sur .NET. Tout est un objet .NET. Ainsi, beaucoup d’objets sont disponibles en Powershell de la même façon qu’en .NET.

Par exemple si on affecte une chaine de caractères $a = "powershell":

  • $a permet d’obtenir la valeur de la variable
  • $a.Length permet d’obtenir la longueur de la chaine
  • $a.GetType() permet d’obtenir le type de la valeur de la variable.

Accès aux objets statiques

Powershell permet d’appeler des objets .NET statiques ce qui étend davantage ses fonctionnalités. Pour appeler une méthode du framework .NET on peut taper une instruction de type:

[<objet du framework .NET>]::<nom de la méthode>

Par exemple pour appeler la méthode statique suivant qui se trouve dans le namespace System.Reflection:

public static Assembly Load(string assemblyString)

On peut utiliser la syntaxe:

[System.Reflection.Assembly]::Load("System.Web")

Instanciation d’objets

L’instanciation de nouveaux objets .NET se fait en utilisant New-Object, par exemple:

$xmlDoc = New-Object System.Xml.XmlDocument

Utiliser des “pipelines”

Les pipelines permettent d’utiliser plusieurs commandes successivement suivant un pipeline de commandes.

Par exemple, pour avoir la liste des fichiers dont la taille est supérieure à 100kb:

Get-ChildItem | Where-Object { $_.Length -gt 100kb }

$_ permet de spécifier l’élément courant lors de l’exécution en boucle des éléments renvoyés par Get-ChildItem.

Pour indiquer la taille, on peut utiliser:

  • Kb pour kilo bytes
  • Mb pour mega bytes
  • Gb pour giga bytes

Pour trier par ordre alphabétique:

Get-ChildItem | Where-Object { $_.Length -gt 100kb } | Sort-Object Length 

Pour formatter la sortie de Get-ChildItem:

Get-ChildItem | `
  Where-Object { $_.Length -gt 100kb } | `
  Sort-Object Length | `
  Select-Object Name, Length

Autre exemple permettant de lister les ID des processus dont le nom contient le mot “powershell”:

Get-Process | `
  where{$_.Name -like "powershell"} | `
  Select Id

Powershell “providers” (utilisation des “snap-ins”)

Un provider est une bibliothèque .NET qui permet de mettre à disposition des commandes de façon à pouvoir naviguer dedans. On peut utiliser les mêmes commandes pour naviguer dans les différents types d’objets mis à disposition dans le provider.

Get-PSProvider permet d’avoir tous les providers disponibles par défaut.
Tous les providers sont utilisables sur des drives. C’est à travers ces drives qu’on peut naviguer et retrouver les données.

Get-Psdrive permet d’afficher tous les drives.

Par exemple, si on se place dans le drive consacré à l’environnement on peut explorer le contenu des variables d’environnement.
Pour se placer dans le drive de l’environnement, il faut exécuter:

Set-Location env:

On peut alors lister les variables d’environnement en écrivant:

Get-ChildItem 

Comme précédemment, on peut formater les données en faisant:

Get-ChildItem | Format-Table –Property Name, Value –Autosize 

Pour avoir la liste des alias, on peut écrire:

Set-Location alias: 
Get-ChildItem

Pour revenir au drive correspondant au système de fichiers, il suffit de se placer dans le drive d’un volume (par exemple le disque C):

Set-Location c: 

Ajouter un “provider”

Pour ajouter un provider, on effectue cette opération en utilisant des snap-ins:

Pour lister tous les snap-ins disponibles (c’est-à-dire enregistrables), on exécute:

Get-PSSnapin

Pour lister les snap-ins enregistrés:

Get-PSSnapin –Registered

Ces snap-ins sont enregistrés mais non exécutés.

Pour charger un snap-in qui est enregistré:

Add-PSSnapin <nom de l'addin>

On peut vérifier qu’ils sont bien chargés en exécutant:

Get-PSSnapin –Name <nom de la commande>

Quand on rajoute un snap-in, il ajoute un drive et on peut accéder à ce drive de la même façon que pour les autres exemples:

Set-Location <nom du drive>:
Get-ChildItem

Quelque soit le provider qu’on utilise, on y accéde de la même façon en utilisant les commandes Set-Location et Get-ChildItem.
D’autre part, la navigation dans les données mises à disposition pour le provider se fait de la même façon que la navigation dans un système de fichiers:

  • Il y a une notion de hiérarchie
  • On peut indiquer l’élément dans lequel on veut naviguer en exécutant Set-Location
  • On obtient la liste des éléments en exécutant Get-ChildItem.

Supprimer un “provider”

On exécute une commande permettant de supprimer un snap-in:

Remove-PSSnapin <nom de l'add-in>

Cet article a détaillé les éléments principaux permettent d’utiliser les cmdlets. Les articles suivants permettent de rentrer davantage dans les détails des instructions utilisables dans des scripts Powershell.

Leave a Reply