PowerShell sous Linux

Préparation

Pour les manipulations de ce cours, vous aurez besoin d'un terminal Linux avec PowerShell installé.

Bien que PowerShell soit disponible sur presque toutes les distributions Linux, nous utiliserons pour ce cours des distributions basées sur Debian (Ubuntu, Debian, etc.) afin de simplifier les instructions d'installation (apt).

Installer PowerShell sur Linux

PowerShell s'installe avec le gestionnaire de paquets de votre distribution. Voici comment l'installer sur une distribution basée sur Debian (Ubuntu, Debian, etc.):

  1. Ouvrez un terminal.
  2. Mettez à jour la liste des paquets:
sudo apt update
  1. Installez les dépendances nécessaires:
sudo apt install -y wget apt-transport-https software-properties-common
  1. Importez la clé GPG de Microsoft:
source /etc/os-release
wget -q https://packages.microsoft.com/config/debian/$VERSION_ID/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
  1. Mettez à jour la liste des paquets à nouveau:
sudo apt update
  1. Installez PowerShell:
sudo apt install -y powershell
  1. Vérifiez l'installation en affichant la version de PowerShell:
pwsh --version

Vous devriez voir la version de PowerShell installée. Remarquez que la version de PowerShell sur Linux sera la version 7.x (PowerShell Core), car les versions 5.x et antérieures sont spécifiques à Windows.

Lancer PowerShell

Ouvrez un terminal et lancez PowerShell en tapant :

pwsh

Vous devriez voir le prompt de PowerShell (PS).

Vous pouvez tester une première commande PowerShell, par exemple, afficher la version:

$PSVersionTable

Pour quitter PowerShell et retourner au bash Linux, tapez exit.

Manipulations

Les manipulations suivantes vous permettront de vous familiariser avec PowerShell sous Linux et de comparer son fonctionnement avec celui sous Windows.

Manipulation 1 – Naviguer dans le système de fichiers

  1. Lancez PowerShell (pwsh).
  2. Affichez le répertoire courant avec Get-Location (ou pwd).

À remarquer: la commande pwd est une commande bash qui fonctionne également dans PowerShell car PowerShell intègre des alias pour certaines commandes courantes de bash. Il ne faut pas confondre avec la vraie commande bash pwd qui affiche le répertoire courant dans un shell bash. Cependant, comme nous le verrons plus tard, PowerShell permet d'appeler des commandes bash directement. Comment savoir alors si nous utilisons une commande PowerShell ou une commande bash? L'ordre de priorité est le suivant:

  • Si une cmdlet PowerShell existe avec ce nom, c'est cette cmdlet qui sera exécutée.
  • Sinon, si une fonction PowerShell existe avec ce nom, c'est cette fonction qui sera exécutée.
  • Sinon, si un alias PowerShell existe avec ce nom, c'est cet alias qui sera exécuté.
  • Sinon, si un exécutable (commande externe) existe avec ce nom (trouvable dans le $PATH), c'est cet exécutable qui sera exécuté, comme c'est le cas des commandes bash.
  1. Changez de répertoire avec Set-Location /home/votre_utilisateur/Downloads (remplacez votre_utilisateur par votre nom d'utilisateur Linux).

À remarquer: sous Linux, les chemins utilisent des / au lieu des \ sous Windows.

  1. Listez les fichiers avec Get-ChildItem.

  2. Créez un nouveau répertoire avec New-Item -ItemType Directory -Name "TestPS".

  3. Allez dans ce répertoire avec Set-Location TestPS.

  4. Créez un nouveau fichier texte avec New-Item -ItemType File -Name "monfichier.txt".

  5. Vérifiez que le fichier a été créé avec Get-ChildItem.

  6. Ouvrez le fichier avec nano monfichier.txt, ajoutez du texte, puis sauvegardez et quittez.

À remarquer: nano est une commande Linux pour éditer des fichiers texte. Si vous l'exécutez dans PowerShell, vous utilisez une commande Linux depuis PowerShell. PowerShell permet d'appeler des commandes Linux directement.

  1. Affichez le contenu du fichier avec Get-Content monfichier.txt.
  2. Quittez PowerShell avec exit.
  3. Retournez dans le répertoire parent avec cd .. (commande bash), explorez le répertoire TestPS avec ls (commande bash).
  4. Supprimez le répertoire TestPS et son contenu avec rm -r TestPS (commande bash).

Manipulation 2 – Utiliser des cmdlets PowerShell

Pour cette manipulation, ouvrez une machine Linux et une machine Windows avec PowerShell.

  1. Lancez PowerShell sur vos deux machines (pwsh sur Linux, powershell ou pwsh sur Windows).

  2. Sur les deux machines, exécutez la commande Get-Process pour lister les processus en cours.

À remarquer: L'affichage des processus sera relativement similaire, mais les processus eux-mêmes seront différents car ils dépendent du système d'exploitation.

  1. Explorez le type d'objet retourné par Get-Process avec Get-Member sur vos deux machines.

À remarquer: Dans les deux cas, vous verrez que Get-Process retourne des objets de type System.Diagnostics.Process, mais les propriétés disponibles peuvent varier légèrement entre Windows et Linux.

  1. Ouvrez Notepad sous Windows et nano sous Linux (dans un nouveau terminal) pour démarrer des processus.
  2. Sur les deux machines, exécutez la commande suivante pour filtrer les processus Notepad/nano et afficher uniquement le nom et l'ID du processus : Sur Linux:
Get-Process | Where-Object { $_.Name -eq "nano" } | Select-Object Name, Id

Sur Windows:

Get-Process | Where-Object { $_.Name -eq "notepad" } | Select-Object Name, Id

À remarquer: la syntaxe PowerShell est la même sur les deux systèmes.

  1. Arrêtez les processus Notepad/nano avec Stop-Process -Id <ID> (remplacez <ID> par l'ID du processus obtenu précédemment).

À remarquer: la commande Stop-Process fonctionne de la même manière sur les deux systèmes, bien que la gestion des processus sous-jacente soit différente entre Windows et Linux.

  1. Quittez PowerShell sur les deux machines avec exit.

Manipulation 3 – Appeler des commandes Linux depuis PowerShell

  1. Lancez PowerShell sur votre machine Linux (pwsh).
  2. Exécutez la commande Linux df -h pour afficher l'espace disque disponible.
df -h

À remarquer: df est une commande Linux appelée depuis PowerShell.

  1. Explorez le type de l'objet retourné par df -h avec Get-Member.
df -h | Get-Member

À remarquer: les résultats de df -h sont des chaînes de caractères, pas des objets PowerShell.

  1. Exécutez la commande Linux systemctl status ssh pour vérifier le statut du service SSH.
systemctl status ssh

Note: Si le service SSH n'est pas installé ou en cours d'exécution, vous pouvez essayer avec un autre service comme cron ou networking.

À remarquer: systemctl est une commande Linux appelée depuis PowerShell.

  1. Explorez le type de l'objet retourné par systemctl status ssh avec Get-Member.
systemctl status ssh | Get-Member

À remarquer: les résultats de systemctl status ssh sont également des chaînes de caractères, pas des objets PowerShell.

  1. Essayez d'exécuter une commande Linux qui n'existe pas, par exemple foo.
foo

À remarquer: PowerShell affichera une erreur indiquant que la commande n'a pas été trouvée. Cela montre que PowerShell peut appeler des commandes Linux, mais uniquement celles qui sont installées et accessibles dans le PATH de l'utilisateur.

  1. Exécutez la commande suivante, qui combine la sortie de df -h avec ForEach-Object pour formater la sortie:
df -h | ForEach-Object { ($_ -split "\s+")[0..2] -join " | " }

À remarquer: cette commande utilise ForEach-Object pour traiter chaque ligne de la sortie de df -h, en divisant chaque ligne en colonnes et en joignant les trois premières colonnes avec des |. Cela montre comment vous pouvez manipuler la sortie des commandes Linux dans PowerShell.

  1. Essayons maintenant de convertir la sortie de df -h en objets PowerShell. Exécutez la commande suivante:
$dfOutput = df -h
$dfObjects = $dfOutput | ForEach-Object {
    $columns = $_ -split "\s+"
    [PSCustomObject]@{
        Filesystem = $columns[0]
        Size       = $columns[1]
        Used       = $columns[2]
        Avail      = $columns[3]
        UsePercent = $columns[4]
        MountedOn  = $columns[5]
    }
}
$dfObjects | Format-Table -AutoSize

À remarquer: cette commande crée des objets personnalisés PowerShell à partir de la sortie de df -h, ce qui permet de manipuler les données plus facilement dans PowerShell. En effet, cela nous permettra de travailler avec des objets (et donc des propriétés) plutôt qu'avec des chaînes de caractères brutes.

  1. Filtrez les systèmes de fichiers dont l'utilisation est supérieure à 50%:
$dfObjects | Where-Object { [int]($_.UsePercent -replace '%','') -gt 50 } 

À remarquer: cette commande utilise Where-Object pour filtrer les objets en fonction de la propriété UsePercent. Cela est beaucoup plus simple que de manipuler des chaînes de caractères.

Note: Vous obtiendrez un message d'erreur indiquant qu'il est impossible de convertir la valeur "Use" en type "System.Int32". Cela est dû au fait que la première ligne de la sortie de df -h est l'en-tête, qui ne peut pas être converti en entier. Pour éviter cette erreur, vous pouvez filtrer l'en-tête avant de faire la conversion:

$dfObjects | Where-Object { $_.Filesystem -ne "Filesystem" -and [int]($_.UsePercent -replace '%','') -gt 50 }
  1. Quittez PowerShell avec exit.

Manipulation 4 - Les commandes propres à Windows

  1. Lancez PowerShell sur votre machine Windows (powershell ou pwsh).
  2. Essayez d'exécuter les commandes suivantes :
    • Get-EventLog -LogName System
    • Get-ADUser -Filter *
    • Get-WmiObject -Class Win32_OperatingSystem
  3. Observez que ces commandes fonctionnent sous Windows car elles sont spécifiques à Windows.

À remarquer: Certaines cmdlets PowerShell sont spécifiques à Windows et ne fonctionneront pas sous Linux. Cela inclut des cmdlets liées à Active Directory, WMI, et les journaux d'événements Windows. Il est important de vérifier la compatibilité des cmdlets lorsque vous écrivez des scripts destinés à être exécutés sur plusieurs plateformes.

  1. Quittez PowerShell avec exit.

Manipulation 5 – Créer un script PowerShell portable

  1. Créez un nouveau fichier script PowerShell nommé rapport.ps1 avec nano rapport.ps1.
  2. Ajoutez le contenu suivant au script :
# Rapport système
"Rapport généré le : $(Get-Date)"
"Top 5 des processus par utilisation CPU :"
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 | Format-Table -AutoSize
"Espace disque disponible :"
df -h
"Ping google.com :"
ping -c 4 google.com

À remarquer: les commandes df et ping sont des commandes Linux appelées depuis PowerShell, tandis que les autres sont des cmdlets PowerShell. Dans un script PowerShell, vous pouvez mélanger des cmdlets PowerShell et des commandes Linux.

  1. Sauvegardez et quittez nano.
  2. Rendez le script exécutable avec chmod +x rapport.ps1.
  3. Exécutez le script avec ./rapport.ps1.
  4. Observez les résultats affichés par le script.
  5. Copiez le script rapport.ps1 sur une machine Windows.
  6. Sur la machine Windows, ouvrez PowerShell (powershell ou pwsh).
  7. Exécutez le script avec .\rapport.ps1. Observez que les parties utilisant des cmdlets PowerShell fonctionnent, mais les commandes Linux (df, ping) ne fonctionneront pas à moins que vous n'ayez un environnement Linux (comme WSL) configuré.
  8. Modifiez le script pour qu'il soit compatible avec les deux systèmes en utilisant des conditions pour vérifier le système d'exploitation :

Sur PowerShell 7.4 et ultérieur, vous pouvez utiliser les variables automatiques $IsLinux et $IsWindows pour détecter le système d'exploitation. Voici un exemple modifié du script rapport.ps1 :

# Rapport système
"Rapport généré le : $(Get-Date)"
"Top 5 des processus par utilisation CPU :"
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 | Format-Table -AutoSize
"Espace disque disponible :"
if ($IsLinux) {
    df -h
} elseif ($IsWindows) {
    Get-PSDrive -PSProvider FileSystem
}
"Ping google.com :"
if ($IsLinux) {
    ping -c 4 google.com
} elseif ($IsWindows) {
    Test-Connection -ComputerName google.com -Count 4
}

Sur les versions antérieures de PowerShell, vous pouvez utiliser la variable $env:OS pour détecter le système d'exploitation. Voici un exemple modifié du script rapport.ps1 :

# Rapport système
"Rapport généré le : $(Get-Date)"
"Top 5 des processus par utilisation CPU :"
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 | Format-Table -AutoSize
"Espace disque disponible :"
if ($env:OS -eq "Windows_NT") {
    Get-PSDrive -PSProvider FileSystem
} else {
    df -h
}
"Ping google.com :"
if ($env:OS -eq "Windows_NT") {
    Test-Connection -ComputerName google.com -Count 4
} else {
    ping -c 4 google.com
}
  1. Sauvegardez et exécutez à nouveau le script sur les deux systèmes pour vérifier qu'il fonctionne correctement.
  2. Quittez PowerShell avec exit.

Manipulation 6 – Utiliser des scripts Bash depuis PowerShell et vice versa

Partie A : Créer et exécuter un script bash depuis PowerShell

  1. Depuis votre terminal bash Linux, créez un script bash nommé info-systeme.sh :
nano info-systeme.sh
  1. Ajoutez le contenu suivant :
#!/bin/bash
echo "=== Informations Système ==="
echo "Nom d'hôte: $(hostname)"
echo "Utilisateur: $(whoami)"
echo "Système: $(uname -s)"
echo "Noyau: $(uname -r)"
echo "Architecture: $(uname -m)"
  1. Sauvegardez et quittez nano.
  2. Rendez le script exécutable :
chmod +x info-systeme.sh
  1. Lancez PowerShell (pwsh).
  2. Exécutez le script bash depuis PowerShell :
./info-systeme.sh

À remarquer: PowerShell peut exécuter directement des scripts bash en les appelant comme des commandes externes.

  1. Capturez la sortie du script bash dans une variable PowerShell :
$resultat = ./info-systeme.sh
$resultat

À remarquer: la sortie du script bash est capturée comme un tableau de chaînes de caractères dans PowerShell.

  1. Passez un paramètre au script bash. Modifiez d'abord le script :
nano info-systeme.sh

Modifiez-le pour accepter un paramètre :

#!/bin/bash
NOM=${1:-"Utilisateur"}
echo "=== Informations Système pour $NOM ==="
echo "Nom d'hôte: $(hostname)"
echo "Utilisateur: $(whoami)"
echo "Système: $(uname -s)"
echo "Noyau: $(uname -r)"
echo "Architecture: $(uname -m)"
  1. Depuis PowerShell, exécutez le script avec un paramètre :
./info-systeme.sh "MonServeur"

À remarquer: les paramètres sont passés au script bash de la même manière qu'on le ferait depuis bash.

Partie B : Créer et exécuter un script PowerShell depuis bash

  1. Quittez PowerShell (exit) pour retourner à bash.
  2. Créez un script PowerShell nommé analyse-processus.ps1 :
nano analyse-processus.ps1
  1. Ajoutez le contenu suivant :
#!/usr/bin/env pwsh
param(
    [int]$TopN = 5
)

Write-Host "=== Top $TopN processus par CPU ===" -ForegroundColor Cyan
Get-Process | Sort-Object CPU -Descending | Select-Object -First $TopN | Format-Table Name, CPU, WorkingSet -AutoSize

Write-Host "`n=== Top $TopN processus par mémoire ===" -ForegroundColor Cyan
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First $TopN | Format-Table Name, CPU, WorkingSet -AutoSize

À remarquer: la ligne #!/usr/bin/env pwsh (shebang) indique à Linux d'utiliser PowerShell pour exécuter ce script.

  1. Sauvegardez et quittez nano.
  2. Rendez le script exécutable :
chmod +x analyse-processus.ps1
  1. Exécutez le script PowerShell depuis bash en utilisant le shebang :
./analyse-processus.ps1

À remarquer: grâce au shebang, le script PowerShell s'exécute directement depuis bash.

  1. Exécutez le script avec un paramètre :
./analyse-processus.ps1 -TopN 10
  1. Alternativement, vous pouvez aussi appeler explicitement PowerShell :
pwsh -File analyse-processus.ps1 -TopN 3

Partie C : Intégration bash et PowerShell

  1. Créez un script bash qui appelle un script PowerShell :
nano orchestration.sh
  1. Ajoutez le contenu suivant :
#!/bin/bash
echo "=== Début de l'analyse système ==="
echo ""
echo "Étape 1 : Informations système (bash)"
./info-systeme.sh "Analyse Automatique"
echo ""
echo "Étape 2 : Analyse des processus (PowerShell)"
pwsh -File analyse-processus.ps1 -TopN 3
echo ""
echo "=== Fin de l'analyse ==="
  1. Sauvegardez, rendez exécutable et exécutez :
chmod +x orchestration.sh
./orchestration.sh

À remarquer: ce script démontre comment bash et PowerShell peuvent travailler ensemble dans un workflow d'automatisation. Vous pouvez utiliser bash pour orchestrer des tâches et appeler PowerShell pour des opérations plus complexes, ou vice-versa.

  1. Vérifiez les codes de retour. Lancez PowerShell :
pwsh
  1. Dans PowerShell, exécutez un script bash et vérifiez son code de retour :
./info-systeme.sh
$LASTEXITCODE

À remarquer: $LASTEXITCODE contient le code de retour de la dernière commande externe. Un code de 0 indique généralement un succès.

  1. Quittez PowerShell avec exit.