Les bases des commandes PowerShell — Les opérations à connaître en premier et comment les utiliser en toute sécurité

· Mis à jour le: · · PowerShell, Windows, Ligne de commande, Automatisation, Réutilisation des actifs existants

1. Ce qu’il faut retenir en premier

PowerShell est un environnement de commandes que vous pouvez utiliser pour vérifier la configuration de Windows, organiser des fichiers, investiguer des journaux, traiter des CSV, gérer des services et automatiser des tâches routinières.

Cela dit, il n’est pas nécessaire d’écrire des scripts complexes dès le premier jour. Retenez d’abord simplement le déroulement suivant, et vous serez déjà bien plus efficace dans votre travail quotidien.

Chercher  Regarder  Filtrer  Trier  Afficher  Modifier si nécessaire

Les fondamentaux de PowerShell ne consistent pas à « mémoriser de longues commandes ». Ce qui compte, ce sont ces trois points :

  1. Savoir rechercher des commandes avec Get-Command et Get-Help
  2. Savoir transmettre un résultat à la commande suivante via le pipeline |
  3. Vérifier l’impact avec -WhatIf ou -Confirm avant toute suppression, arrêt ou modification

PowerShell permet d’exécuter « l’investigation » et « la modification » dans le même écran. C’est pratique, mais les suppressions et les arrêts s’exécutent tout aussi instantanément, d’où l’importance de prendre l’habitude de commencer par des vérifications en lecture seule.

Par ailleurs, le code qui apparaît dans cet article est publié sur GitHub sous la forme d’un ensemble complet d’exemples, comprenant une collection de scripts organisés par thème selon la structure des chapitres (conçue pour que vous puissiez vous entraîner en toute sécurité dans un espace de travail créé dans un dossier temporaire) ainsi que des tests Pester.

powershell-command-basics - komurasoft-blog-samples (GitHub)

2. La différence entre PowerShell et l’invite de commandes

PowerShell ressemble à l’invite de commandes traditionnelle (cmd.exe), mais la philosophie sous-jacente est différente.

Aspect Invite de commandes PowerShell
Sortie principale Chaînes de caractères Objets
Noms de commandes dir, copy, etc. Get-ChildItem, Copy-Item, etc.
Traitement des résultats Principalement de la manipulation de chaînes Filtrage et tri via les propriétés
Automatisation Fichiers batch Scripts .ps1
Points forts Compatibilité avec les anciennes commandes Administration Windows, CSV, JSON, API, tâches routinières

Par exemple, pour lister des fichiers, avec cmd.exe on se contente généralement de lire le résultat de dir comme un mur de texte. Sous PowerShell, les fichiers sont traités comme des objets possédant des propriétés telles que Name, Length et LastWriteTime.

Get-ChildItem

Une fois cette différence comprise, des opérations comme « n’afficher que les fichiers modifiés au cours des 7 derniers jours, du plus récent au plus ancien » s’écrivent naturellement.

Get-ChildItem -File |
  Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } |
  Sort-Object LastWriteTime -Descending |
  Select-Object Name, Length, LastWriteTime

3. Windows PowerShell 5.1 et PowerShell 7.x

Windows dispose depuis longtemps de Windows PowerShell 5.1, ainsi que de la nouvelle lignée PowerShell 7.x.

En pratique, ce cadre de lecture aide à y voir clair.

Type Exécutable Usage principal
Windows PowerShell 5.1 powershell.exe Modules spécifiques à Windows anciens, scripts existants, maintenance des actifs internes
PowerShell 7.x pwsh.exe Nouveaux scripts, multiplateforme, amélioration continue des fonctionnalités

Si vous apprenez PowerShell pour la première fois, prendre PowerShell 7.x comme référence ne pose pas de problème. Cependant, les anciens scripts d’administration internes et les modules spécifiques à Windows sont parfois conçus en partant du principe de Windows PowerShell 5.1.

C’est pourquoi, en pratique, la première chose à faire est de vérifier la version.

$PSVersionTable

Pour un script destiné à s’exécuter uniquement à partir d’une version donnée, indiquer une condition en tête de fichier permet de réduire les incidents.

#Requires -Version 7.0

4. Les applets de commande suivent la forme Verbe-Nom

Les commandes standard de PowerShell prennent fondamentalement la forme Verbe-Nom.

Get-Process
Get-Service
Get-ChildItem
Copy-Item
Remove-Item
Export-Csv

Une fois cette forme intégrée, même les commandes inconnues deviennent plus faciles à trouver.

Verbe Signification Exemple
Get Obtenir Get-Process
Set Configurer Set-Location
New Créer New-Item
Copy Copier Copy-Item
Move Déplacer Move-Item
Remove Supprimer Remove-Item
Start Démarrer Start-Service
Stop Arrêter Stop-Process
Import Importer Import-Csv
Export Exporter Export-Csv

Des noms courts comme dir, ls, cat ou cd fonctionnent aussi, mais ce sont pour la plupart des alias.

Get-Command dir

Lorsque vous conservez du code sous forme de script, il est plus sûr d’utiliser les noms complets plutôt que des alias.

# Lisible, mais à éviter dans les scripts
ls *.log

# L'intention est claire
Get-ChildItem -Filter *.log

5. Les trois commandes d’investigation à apprendre en premier

PowerShell comporte un très grand nombre de commandes ; il est donc plus utile en pratique d’apprendre « comment les rechercher » plutôt que de les mémoriser.

1. Get-Command — rechercher les commandes disponibles

Get-Command est la commande permettant de rechercher les commandes, fonctions, alias et applications installés.

# Rechercher les commandes ayant le nom Process
Get-Command -Noun Process

# Rechercher les commandes liées aux services
Get-Command *Service*

# Rechercher les commandes liées aux CSV
Get-Command *Csv*

Lorsque vous ne vous souvenez que vaguement du nom d’une commande, utilisez des caractères génériques.

Get-Command *Item*
Get-Command *Content*
Get-Command *Json*

2. Get-Help — consulter le mode d’emploi

Get-Help est la commande permettant de consulter la description, les paramètres et les exemples d’une commande.

Get-Help Get-ChildItem
Get-Help Get-ChildItem -Examples
Get-Help Get-ChildItem -Full
Get-Help Get-ChildItem -Online

Au départ, -Examples est particulièrement utile.

Get-Help Where-Object -Examples

Si l’aide est obsolète ou incomplète, mettez-la à jour depuis une session PowerShell exécutée en tant qu’administrateur.

Update-Help

Selon l’environnement, cela nécessite une connexion internet et des droits suffisants. Sur les PC d’entreprise, cela peut échouer à cause d’un proxy ou de la politique de gestion.

3. Get-Member — regarder le contenu d’un objet

Dans la plupart des cas, la sortie de PowerShell n’est pas une « chaîne de caractères » mais un « objet ». Avec Get-Member, vous pouvez vérifier quelles propriétés et méthodes cet objet possède.

Get-Process | Get-Member
Get-Service | Get-Member
Get-ChildItem | Get-Member

Par exemple, un service possède des propriétés telles que Status et Name.

Get-Service | Select-Object Name, Status

Un fichier possède Name, Length, LastWriteTime, et ainsi de suite.

Get-ChildItem -File | Select-Object Name, Length, LastWriteTime

Quand vous « ne savez pas sur quoi filtrer », vérifiez d’abord les noms de propriétés avec Get-Member.

6. Les bases du pipeline

Le | de PowerShell transmet le résultat de la commande de gauche à la commande de droite.

Get-Process | Sort-Object CPU -Descending | Select-Object -First 10

Cet exemple effectue le traitement suivant, de gauche à droite.

Récupérer la liste des processus
   trier par ordre décroissant d'utilisation CPU
  → afficher seulement les 10 premiers

Voici les combinaisons fréquemment utilisées.

Commande Rôle Exemple
Where-Object Filtrer par condition Ne récupérer que les services arrêtés
Sort-Object Trier Trier du plus récemment modifié au plus ancien
Select-Object Choisir des colonnes ou un nombre d’éléments N’afficher que le nom et la taille
ForEach-Object Traiter chaque élément Traiter fichier par fichier
Export-Csv Exporter en CSV Enregistrer les résultats d’une investigation

Where-Object — filtrer par condition

# N'afficher que les services arrêtés
Get-Service | Where-Object { $_.Status -eq "Stopped" }

# N'afficher que les fichiers de plus de 100 Mo
Get-ChildItem -File |
  Where-Object { $_.Length -gt 100MB }

# N'afficher que les fichiers dont le nom contient backup
Get-ChildItem -File |
  Where-Object { $_.Name -like "*backup*" }

$_ représente l’objet en cours qui circule dans le pipeline.

Where-Object { $_.Length -gt 100MB }

Cela évalue « la propriété Length du fichier actuellement examiné est-elle supérieure à 100 Mo ? ».

Depuis PowerShell 3.0, une syntaxe simplifiée est également disponible.

Get-Service | Where-Object Status -EQ "Stopped"

Cependant, tant que vous êtes débutant, la syntaxe en bloc de script (scriptblock) est plus facile à suivre.

Get-Service | Where-Object { $_.Status -eq "Stopped" }

Sort-Object — trier

# Du plus gros consommateur de mémoire au plus petit
Get-Process |
  Sort-Object WorkingSet -Descending |
  Select-Object -First 10 Name, Id, WorkingSet

# Du plus récemment modifié au plus ancien
Get-ChildItem -File |
  Sort-Object LastWriteTime -Descending |
  Select-Object -First 20 Name, LastWriteTime

Select-Object — choisir uniquement les colonnes nécessaires

Get-Process |
  Select-Object Name, Id, CPU, WorkingSet

Il sert aussi à limiter le nombre d’éléments.

Get-Process | Select-Object -First 5
Get-Process | Select-Object -Last 5

Avant d’exporter en CSV, réduire le résultat aux seules colonnes nécessaires avec Select-Object le rend plus facile à exploiter.

Get-Service |
  Select-Object Name, DisplayName, Status, StartType |
  Export-Csv .\services.csv -NoTypeInformation -Encoding UTF8

7. Utilisez les commandes Format en dernier

PowerShell propose des commandes pour mettre en forme l’affichage.

Format-Table
Format-List
Format-Wide

Ces commandes sont destinées à « l’affichage à l’écran ». Si vous les utilisez avant d’exporter en CSV ou avant de transmettre les données à un traitement ultérieur, vous obtenez des objets d’affichage à la place des propriétés d’origine.

# À éviter : des informations d'affichage se mélangent au CSV
Get-Process |
  Format-Table Name, CPU |
  Export-Csv .\process.csv -NoTypeInformation

# Correct : sélectionner d'abord les propriétés, puis exporter en CSV
Get-Process |
  Select-Object Name, CPU |
  Export-Csv .\process.csv -NoTypeInformation -Encoding UTF8

Retenez que les commandes Format-* sont « faites pour l’affichage final à l’écran », et les incidents diminueront.

8. Les bases des opérations sur les fichiers et les dossiers

Ce que vous utiliserez le plus souvent avec PowerShell, ce sont les opérations sur les fichiers et les dossiers.

Ce que vous voulez faire Commande
Voir l’emplacement actuel Get-Location
Se déplacer Set-Location
Voir une liste Get-ChildItem
Créer un fichier ou un dossier New-Item
Copier Copy-Item
Déplacer Move-Item
Renommer Rename-Item
Supprimer Remove-Item
Vérifier l’existence Test-Path

Vérifier l’emplacement actuel

Get-Location

Se déplacer.

Set-Location C:\Work

Si le chemin contient des espaces, entourez-le de guillemets.

Set-Location "C:\Work Files\Reports"

Voir la liste des fichiers

Get-ChildItem
Get-ChildItem -File
Get-ChildItem -Directory
Get-ChildItem -Recurse

Pour filtrer par extension, -Filter est pratique.

Get-ChildItem -Filter *.log

Pour rechercher aussi dans les sous-dossiers, utilisez -Recurse.

Get-ChildItem C:\Logs -Filter *.log -Recurse

Dans un emplacement contenant un très grand nombre de fichiers, n’utilisez pas -Recurse d’emblée : limitez d’abord le dossier ciblé, puis exécutez la commande.

Créer

# Créer un dossier
New-Item -ItemType Directory -Path .\archive

# Créer un fichier vide
New-Item -ItemType File -Path .\memo.txt

Si l’élément existe peut-être déjà, vérifiez d’abord.

if (-not (Test-Path .\archive)) {
  New-Item -ItemType Directory -Path .\archive
}

Copier

Copy-Item .\report.xlsx .\backup\report.xlsx

Pour copier un dossier entier, utilisez -Recurse.

Copy-Item .\data .\backup\data -Recurse

Lorsqu’un écrasement est possible, vérifiez l’impact au préalable.

Copy-Item .\data .\backup\data -Recurse -WhatIf

Déplacer

Move-Item .\old.log .\archive\old.log

Pour déplacer plusieurs fichiers selon une condition, ajoutez d’abord -WhatIf.

Get-ChildItem .\logs -Filter *.log |
  Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
  Move-Item -Destination .\archive -WhatIf

Si tout semble correct, retirez -WhatIf.

Get-ChildItem .\logs -Filter *.log |
  Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
  Move-Item -Destination .\archive

Supprimer

Traitez la suppression avec une prudence particulière.

Remove-Item .\old.log -WhatIf

N’exécutez qu’après avoir vérifié que la cible est correcte.

Remove-Item .\old.log

La combinaison des caractères génériques et de -Recurse est puissante. N’exécutez pas d’emblée sur un dossier de production : vérifiez d’abord via un affichage de liste.

# D'abord, confirmer les cibles
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
  Select-Object FullName, Length, LastWriteTime

# Ensuite, confirmer ce qui serait supprimé
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
  Remove-Item -WhatIf

# Enfin, exécuter
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
  Remove-Item

9. Lire, rechercher et écrire dans des fichiers texte

Dans l’investigation de journaux, les opérations sur les fichiers texte reviennent constamment.

Lire un fichier

Get-Content .\app.log

Pour ne voir que la fin, utilisez -Tail.

Get-Content .\app.log -Tail 50

Pour suivre un journal qui continue d’être complété, utilisez -Wait.

Get-Content .\app.log -Tail 20 -Wait

Rechercher une chaîne de caractères

Select-String -Path .\app.log -Pattern "ERROR"

Plusieurs fichiers peuvent être ciblés.

Select-String -Path .\logs\*.log -Pattern "ERROR", "WARN"

Vous pouvez aussi extraire le nom de fichier, le numéro de ligne et le contenu des résultats de recherche pour les mettre dans un CSV.

Select-String -Path .\logs\*.log -Pattern "ERROR" |
  Select-Object Path, LineNumber, Line |
  Export-Csv .\error-lines.csv -NoTypeInformation -Encoding UTF8

Écrire dans un fichier

"hello" | Set-Content .\memo.txt -Encoding UTF8
"next line" | Add-Content .\memo.txt -Encoding UTF8

Pour enregistrer le résultat d’une commande, Export-Csv ou ConvertTo-Json est souvent plus facile à exploiter par la suite que Out-File.

Get-Process |
  Select-Object Name, Id, CPU |
  Export-Csv .\process.csv -NoTypeInformation -Encoding UTF8

10. Les bases des CSV

Les fichiers CSV reviennent constamment dans l’automatisation des tâches métier. Avec PowerShell, un CSV n’est pas traité comme une chaîne de caractères mais comme des « objets ayant des colonnes ».

Lire un CSV

Supposons par exemple que vous disposiez du fichier users.csv suivant.

Name,Department,Enabled
Suzuki,Sales,true
Tanaka,Accounting,false
Sato,Sales,true

Chargez-le.

$users = Import-Csv .\users.csv
$users

Les noms de colonnes deviennent des propriétés.

$users | Select-Object Name, Department

Filtrer par condition

$users |
  Where-Object { $_.Department -eq "Sales" }

Les valeurs d’un CSV entrent souvent sous forme de chaînes de caractères ; soyez donc attentif lorsque vous traitez true / false ou des nombres.

$users |
  Where-Object { $_.Enabled -eq "true" }

Écrire dans un CSV

$users |
  Where-Object { $_.Department -eq "Sales" } |
  Export-Csv .\sales-users.csv -NoTypeInformation -Encoding UTF8

La règle absolue est de ne jamais placer Format-Table avant Export-Csv.

# À éviter
$users | Format-Table | Export-Csv .\out.csv -NoTypeInformation

# Correct
$users | Select-Object Name, Department, Enabled | Export-Csv .\out.csv -NoTypeInformation -Encoding UTF8

11. Les bases du JSON

Le JSON est également très courant dans les fichiers de configuration et les API Web.

$data = Get-Content .\settings.json -Raw | ConvertFrom-Json
$data

Convertir un objet en JSON.

[pscustomobject]@{
  Name = "BatchJob"
  Enabled = $true
  Retry = 3
} | ConvertTo-Json

Lorsque la structure comporte des niveaux profonds, indiquez -Depth.

$config | ConvertTo-Json -Depth 10 | Set-Content .\settings.json -Encoding UTF8

12. Les bases des processus et des services

Voir les processus

Get-Process

Vérifiez les processus dont la consommation de mémoire est la plus élevée.

Get-Process |
  Sort-Object WorkingSet -Descending |
  Select-Object -First 10 Name, Id, WorkingSet

Filtrer par nom.

Get-Process -Name notepad

Procédez à l’arrêt avec prudence.

Stop-Process -Name notepad -WhatIf

Si tout semble correct, exécutez.

Stop-Process -Name notepad

Voir les services

Get-Service

Pour ne voir que les services arrêtés :

Get-Service |
  Where-Object { $_.Status -eq "Stopped" }

Filtrer par nom.

Get-Service -Name "Spooler"

Pour un redémarrage également, confirmez d’abord la cible.

Get-Service -Name "Spooler"
Restart-Service -Name "Spooler" -WhatIf

Les opérations sur les services ont facilement un impact sur l’activité métier ; en environnement de production, vérifiez d’abord la procédure, la fenêtre de maintenance et le moyen de récupération.

13. Les bases des journaux d’événements

Les journaux d’événements sont indispensables pour l’investigation sous Windows.

Vérifier les erreurs récentes.

Get-WinEvent -LogName System -MaxEvents 100 |
  Where-Object { $_.LevelDisplayName -eq "Error" } |
  Select-Object TimeCreated, ProviderName, Id, Message

Voir les 50 dernières entrées du journal Application.

Get-WinEvent -LogName Application -MaxEvents 50 |
  Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message

Pour filtrer par période :

$start = (Get-Date).AddHours(-24)

Get-WinEvent -FilterHashtable @{
  LogName = "System"
  StartTime = $start
} |
  Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message

Conserver les résultats d’investigation dans un CSV facilite leur partage ultérieur.

Get-WinEvent -LogName System -MaxEvents 500 |
  Where-Object { $_.LevelDisplayName -in @("Error", "Warning") } |
  Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message |
  Export-Csv .\system-events.csv -NoTypeInformation -Encoding UTF8

14. Variables, tableaux et tables de hachage

Vous pouvez travailler avec de courtes commandes seules, mais dès que les choses s’allongent un peu, les variables deviennent utiles.

Variables

$path = "C:\Logs"
Get-ChildItem $path

Les variables de PowerShell commencent par $.

$today = Get-Date
$limit = (Get-Date).AddDays(-30)

Tableaux

$extensions = @("*.log", "*.txt", "*.csv")
foreach ($ext in $extensions) {
  Get-ChildItem C:\Work -Filter $ext
}

Tables de hachage

Une table de hachage est un ensemble de paires clé-valeur.

$params = @{
  Path = "C:\Logs"
  Filter = "*.log"
  Recurse = $true
}

Get-ChildItem @params

Cette écriture avec @params s’appelle le « splatting ». Elle rend le code plus lisible lorsque le nombre de paramètres augmente.

15. Mettre en forme les résultats avec PSCustomObject

Lorsque vous voulez rassembler des résultats d’investigation sous forme de tableau, [pscustomobject] est pratique.

[pscustomobject]@{
  ComputerName = $env:COMPUTERNAME
  UserName     = $env:USERNAME
  CheckedAt    = Get-Date
}

Vous pouvez construire plusieurs résultats et les transformer en CSV.

Get-ChildItem C:\Logs -Filter *.log |
  ForEach-Object {
    [pscustomobject]@{
      Name          = $_.Name
      FullName      = $_.FullName
      SizeMB        = [math]::Round($_.Length / 1MB, 2)
      LastWriteTime = $_.LastWriteTime
    }
  } |
  Export-Csv .\log-files.csv -NoTypeInformation -Encoding UTF8

16. Les bases des fichiers de script .ps1

Transformez les traitements fréquemment utilisés en fichiers .ps1.

Par exemple, créons un script qui liste les anciens journaux.

# Find-OldLogs.ps1
param(
  [string]$Path = "C:\Logs",
  [int]$Days = 30,
  [string]$OutputPath = ".\old-logs.csv"
)

$limit = (Get-Date).AddDays(-$Days)

Get-ChildItem -Path $Path -Filter *.log -File -Recurse |
  Where-Object { $_.LastWriteTime -lt $limit } |
  Select-Object FullName, Length, LastWriteTime |
  Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8

Write-Host "Exported: $OutputPath"

Exemple d’exécution.

.\Find-OldLogs.ps1 -Path C:\Logs -Days 60 -OutputPath .\old-logs.csv

Recevoir les arguments via param() permet de modifier les conditions plus facilement par la suite.

17. Les bases de la stratégie d’exécution

Lorsque vous essayez d’exécuter un .ps1, il arrive de voir une erreur telle que celle-ci.

... ne peut pas être chargé, car l'exécution de scripts est désactivée sur ce système...

Dans ce cas, vérifiez la stratégie d’exécution actuelle.

Get-ExecutionPolicy
Get-ExecutionPolicy -List

Sur un poste de développement personnel, si vous souhaitez simplement exécuter des scripts créés localement, il est fréquent de passer à RemoteSigned dans la portée de l’utilisateur actuel.

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Cependant, sur les PC d’entreprise, cela peut être contrôlé par une stratégie de groupe. Ne forcez pas de contournement : vérifiez auprès de vos administrateurs et des règles internes.

La stratégie d’exécution est une fonctionnalité de sécurité qui contrôle les conditions d’exécution des scripts PowerShell. Elle ne constitue toutefois pas une frontière de sécurité complète. Dans une organisation, elle doit être envisagée conjointement avec la signature, AppLocker, Microsoft Defender, la gestion des privilèges et l’audit des journaux.

18. Les bases de la gestion des erreurs

PowerShell continue parfois son traitement même lorsqu’une erreur se produit.

Pour les traitements importants, utilisez -ErrorAction Stop et try/catch.

try {
  Copy-Item .\source.txt .\backup\source.txt -ErrorAction Stop
  Write-Host "Copy succeeded"
}
catch {
  Write-Error "Copy failed: $($_.Exception.Message)"
}

Lorsque vous traitez plusieurs fichiers, enregistrer les échecs permet de les retracer par la suite.

$results = foreach ($file in Get-ChildItem .\input -File) {
  try {
    Copy-Item $file.FullName .\backup -ErrorAction Stop

    [pscustomobject]@{
      FileName = $file.Name
      Status   = "OK"
      Message  = ""
    }
  }
  catch {
    [pscustomobject]@{
      FileName = $file.Name
      Status   = "NG"
      Message  = $_.Exception.Message
    }
  }
}

$results | Export-Csv .\copy-result.csv -NoTypeInformation -Encoding UTF8

19. L’ordre sûr pour exécuter les commandes de modification

Dans PowerShell, la procédure permettant de traiter en toute sécurité les commandes de modification — supprimer, déplacer, arrêter — est essentielle.

L’ordre de base est le suivant.

1. Regarder les cibles avec les commandes Get-*
2. Filtrer avec Where-Object
3. Vérifier la liste des cibles avec Select-Object
4. Enregistrer avec Export-Csv
5. Confirmer les modifications prévues avec -WhatIf
6. Exécuter pour de bon

Prenons l’exemple de la suppression de fichiers .tmp datant de plus de 30 jours.

Étape 1 : Regarder les cibles

Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse

Étape 2 : Filtrer par condition

$limit = (Get-Date).AddDays(-30)

Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse |
  Where-Object { $_.LastWriteTime -lt $limit }

Étape 3 : N’afficher que les colonnes nécessaires

$targets = Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse |
  Where-Object { $_.LastWriteTime -lt $limit }

$targets |
  Select-Object FullName, Length, LastWriteTime

Étape 4 : Conserver une preuve

$targets |
  Select-Object FullName, Length, LastWriteTime |
  Export-Csv .\delete-targets.csv -NoTypeInformation -Encoding UTF8

Étape 5 : Confirmer avec WhatIf

$targets | Remove-Item -WhatIf

Étape 6 : Exécuter

$targets | Remove-Item

Suivre cet ordre réduit les incidents du type « on ne sait plus ce qu’on a supprimé ».

20. Liste des commandes de base fréquemment utilisées

Emplacement et fichiers

Objectif Exemple de commande
Afficher le dossier actuel Get-Location
Changer de dossier Set-Location C:\Work
Afficher une liste Get-ChildItem
N’afficher que les fichiers Get-ChildItem -File
N’afficher que les dossiers Get-ChildItem -Directory
Rechercher aussi dans les sous-dossiers Get-ChildItem -Recurse
Vérifier l’existence Test-Path .\file.txt
Créer un dossier New-Item -ItemType Directory .\backup
Copier Copy-Item .\a.txt .\backup\a.txt
Déplacer Move-Item .\a.txt .\archive\a.txt
Vérifier avant suppression Remove-Item .\a.txt -WhatIf

Manipulation d’objets

Objectif Exemple de commande
Filtrer par condition Where-Object { $_.Status -eq "Running" }
Trier Sort-Object LastWriteTime -Descending
Choisir des colonnes Select-Object Name, LastWriteTime
N’afficher que les premiers Select-Object -First 10
Traiter chaque élément ForEach-Object { $_.Name }
Examiner le contenu Get-Member

Entrée/sortie

Objectif Exemple de commande
Lire du texte Get-Content .\app.log
Voir la fin Get-Content .\app.log -Tail 50
Rechercher une chaîne Select-String -Path .\app.log -Pattern "ERROR"
Lire un CSV Import-Csv .\users.csv
Écrire un CSV Export-Csv .\out.csv -NoTypeInformation -Encoding UTF8
Lire du JSON Get-Content .\a.json -Raw \| ConvertFrom-Json
Écrire du JSON $obj \| ConvertTo-Json -Depth 10

Investigation Windows

Objectif Exemple de commande
Liste des processus Get-Process
Liste des services Get-Service
Journaux d’événements Get-WinEvent -LogName System -MaxEvents 100
Variables d’environnement Get-ChildItem Env:
Version de PowerShell $PSVersionTable
Stratégie d’exécution Get-ExecutionPolicy -List

21. Exemple pratique : investiguer des journaux et générer un rapport

Considérons une exigence de ce type :

À partir des fichiers .log sous C:\App\Logs, trouver les lignes contenant ERROR dans les fichiers modifiés au cours des 7 derniers jours, et les rassembler dans un CSV.

Plutôt que d’écrire directement la version finale, construisons-la par étapes.

Étape 1 : Trouver les fichiers journaux

Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse

Étape 2 : Filtrer sur les 7 derniers jours

$since = (Get-Date).AddDays(-7)

Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
  Where-Object { $_.LastWriteTime -ge $since }

Étape 3 : Rechercher ERROR

$since = (Get-Date).AddDays(-7)

Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
  Where-Object { $_.LastWriteTime -ge $since } |
  Select-String -Pattern "ERROR"

Étape 4 : Exporter en CSV

$since = (Get-Date).AddDays(-7)

Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
  Where-Object { $_.LastWriteTime -ge $since } |
  Select-String -Pattern "ERROR" |
  Select-Object Path, LineNumber, Line |
  Export-Csv .\error-report.csv -NoTypeInformation -Encoding UTF8

Étape 5 : En faire un script

# Export-ErrorReport.ps1
param(
  [string]$LogPath = "C:\App\Logs",
  [int]$Days = 7,
  [string]$Pattern = "ERROR",
  [string]$OutputPath = ".\error-report.csv"
)

$since = (Get-Date).AddDays(-$Days)

Get-ChildItem $LogPath -Filter *.log -File -Recurse |
  Where-Object { $_.LastWriteTime -ge $since } |
  Select-String -Pattern $Pattern |
  Select-Object Path, LineNumber, Line |
  Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8

Write-Host "Exported: $OutputPath"

Exemple d’exécution.

.\Export-ErrorReport.ps1 -LogPath C:\App\Logs -Days 14 -Pattern "ERROR|FATAL" -OutputPath .\errors.csv

22. Exemple pratique : archiver d’anciens fichiers

Voici maintenant un exemple qui déplace plutôt qu’il ne supprime.

Déplacer vers C:\Work\Archive les fichiers .xlsx de C:\Work\Reports qui n'ont pas été modifiés depuis 90 jours ou plus.

Vérification des cibles

$source = "C:\Work\Reports"
$dest = "C:\Work\Archive"
$limit = (Get-Date).AddDays(-90)

$targets = Get-ChildItem $source -Filter *.xlsx -File |
  Where-Object { $_.LastWriteTime -lt $limit }

$targets | Select-Object FullName, Length, LastWriteTime

Création de la destination d’archivage

if (-not (Test-Path $dest)) {
  New-Item -ItemType Directory -Path $dest
}

Sortie de la preuve

$targets |
  Select-Object FullName, Length, LastWriteTime |
  Export-Csv .\archive-targets.csv -NoTypeInformation -Encoding UTF8

Confirmation avec WhatIf

$targets | Move-Item -Destination $dest -WhatIf

Exécution

$targets | Move-Item -Destination $dest

Si des collisions de noms de fichiers sont possibles, cela échouera tel quel. En pratique, décidez des règles à l’avance : séparer par dossiers année-mois, ajouter un horodatage au nom du fichier de destination, ou ignorer le fichier si un fichier existant est déjà présent.

23. Difficultés fréquentes

Symptôme Cause Solution
Les commandes sont trop longues pour être mémorisées On essaie de mémoriser Les rechercher avec Get-Command et Get-Help -Examples
$_ reste incompréhensible Compréhension insuffisante de la valeur courante du pipeline L’apprendre via la forme Where-Object { $_.Name -like "*log*" }
Le CSV a un contenu étrange Export-Csv exécuté après Format-Table Exécuter Export-Csv après Select-Object
Un chemin avec des espaces échoue Absence de guillemets L’entourer comme "C:\Work Files\a.txt"
Le script ne peut pas s’exécuter Stratégie d’exécution Vérifier avec Get-ExecutionPolicy -List
Trop de cibles de suppression Conditions trop larges Confirmer d’abord avec Select-Object FullName et -WhatIf
Impossible de connaître le nom des propriétés La structure de l’objet n’a pas été examinée Utiliser Get-Member
Des caractères sont mal affichés Hypothèses d’encodage différentes Vérifier le -Encoding en entrée/sortie et l’application utilisée

24. L’ordre pour apprendre les commandes

Il n’est pas nécessaire d’apprendre toutes les commandes dès le départ.

Voici l’ordre que nous recommandons.

Étape 1 : Regarder, chercher

Get-Command
Get-Help
Get-Member
Get-Location
Set-Location
Get-ChildItem
Get-Content
Select-String

Étape 2 : Filtrer, mettre en forme

Where-Object
Sort-Object
Select-Object
ForEach-Object
Format-Table
Format-List

Étape 3 : Entrée/sortie

Import-Csv
Export-Csv
ConvertFrom-Json
ConvertTo-Json
Set-Content
Add-Content
Out-File

Étape 4 : Modifier

New-Item
Copy-Item
Move-Item
Rename-Item
Remove-Item
Start-Service
Stop-Service
Restart-Service
Stop-Process

Apprenez toujours les commandes de modification en les associant systématiquement aux commandes de vérification correspondantes.

# Regarder
Get-ChildItem .\logs -Filter *.tmp

# Voir ce qui serait supprimé
Get-ChildItem .\logs -Filter *.tmp | Remove-Item -WhatIf

# Exécuter
Get-ChildItem .\logs -Filter *.tmp | Remove-Item

25. Liste de vérification opérationnelle sur le terrain

Lorsque vous utilisez PowerShell dans un contexte professionnel, vérifier les points suivants permet de rester en sécurité.

  • Vérifié si le PowerShell exécuté est powershell.exe ou pwsh.exe
  • Vérifié la version avec $PSVersionTable
  • Affiché les cibles avec les commandes Get-* avant toute modification
  • Vérifié à l’écran les conditions de Where-Object
  • Utilisé -WhatIf avant toute suppression, déplacement ou arrêt
  • Enregistré en CSV la liste des cibles avant exécution
  • Vérifié la sauvegarde ou la procédure de récupération en environnement de production
  • Vérifié la stratégie d’exécution des scripts et les règles internes
  • Prévu une sortie de journal en cas d’erreur
  • Utilisé les noms de commandes complets plutôt que des alias dans les scripts partagés

26. Conclusion

Les fondamentaux de PowerShell ne consistent pas à mémoriser une montagne de commandes. Ce qui porte ses fruits dans le travail réel, c’est d’intérioriser ce schéma :

Chercher avec Get-Command
Consulter l'usage avec Get-Help
Vérifier les propriétés avec Get-Member
Regarder les cibles avec Get-*
Filtrer avec Where-Object
Mettre en forme les colonnes avec Select-Object
Conserver une preuve avec Export-Csv
Confirmer les modifications prévues avec -WhatIf
Exécuter en dernier

Par-dessus tout, PowerShell est un environnement puissant qui peut supprimer des fichiers, arrêter des services, mettre fin à des processus et même manipuler le Registre. C’est précisément pour cette raison que ce qu’il faut apprendre en premier n’est pas « les commandes dangereuses », mais « la procédure permettant de vérifier ses cibles en toute sécurité ».

Regarder  Filtrer  Enregistrer  Répéter  Exécuter

Respectez cet ordre, et PowerShell cesse d’être un simple écran noir pour devenir un outil pratique au service de l’organisation, de l’investigation et de l’automatisation du travail sous Windows.

Liens de référence

Articles connexes

Services liés à ce thème

Développement d’applications Windows

Nous accompagnons le développement de logiciels Windows tels que les applications métier, l’intégration avec des équipements et les outils de communication.

Voir le service / Nous contacter

Réutilisation des actifs existants et accompagnement à la migration

Nous accompagnons l’inventaire, la remise à niveau et la migration des actifs existants, notamment les anciens fichiers batch, VBScript, VBA, PowerShell et COM / ActiveX.

Nous contacter

Articles récents partageant les mêmes étiquettes, pour approfondir des sujets proches.

Ces pages replacent le sujet dans un contexte plus large de services et de décisions.

Cet article est directement lié aux services suivants.

Questions fréquentes

Questions souvent posées lors d’une consultation sur le sujet de cet article.

Par quoi commencer pour apprendre PowerShell ?
Il ne s'agit pas de mémoriser des commandes, mais d'apprendre comment les rechercher. Trois points sont essentiels : pouvoir rechercher des commandes avec Get-Command et Get-Help, pouvoir transmettre un résultat à la commande suivante via le pipeline (|), et vérifier l'impact avec -WhatIf ou -Confirm avant toute suppression, arrêt ou modification. Lorsque vous ne connaissez pas le nom des propriétés d'un objet, utilisez Get-Member pour en examiner le contenu. Le déroulement de base est : « chercher → regarder → filtrer → trier → afficher → modifier si nécessaire ».
Quelle est la différence entre PowerShell et l'invite de commandes ?
La plus grande différence est que la sortie de l'invite de commandes est essentiellement composée de chaînes de caractères, alors que la sortie de PowerShell est constituée d'objets. Par exemple, un fichier est traité comme un objet possédant des propriétés telles que Name, Length et LastWriteTime, ce qui permet d'écrire naturellement un filtrage avec Where-Object ou un tri avec Sort-Object. Les noms de commandes sont également unifiés sous la forme Verbe-Nom, comme Get-ChildItem ou Copy-Item, ce qui facilite la recherche même de commandes inconnues.
Faut-il utiliser Windows PowerShell 5.1 ou PowerShell 7.x ?
Si vous apprenez PowerShell pour la première fois, il n'y a pas de problème à prendre PowerShell 7.x (pwsh.exe) comme référence. Cependant, les anciens scripts d'administration internes et certains modules spécifiques à Windows sont parfois conçus en partant du principe de Windows PowerShell 5.1 (powershell.exe). En pratique, commencez par vérifier la version avec $PSVersionTable, et pour un script destiné à s'exécuter à partir d'une version donnée, indiquer une condition telle que #Requires -Version 7.0 en tête de fichier permet de réduire les incidents.
Comment exécuter en toute sécurité des suppressions ou des modifications avec PowerShell ?
Il faut respecter l'ordre « regarder → filtrer → enregistrer → répéter → exécuter ». Concrètement, affichez d'abord les cibles avec les commandes de la famille Get, filtrez-les avec Where-Object, vérifiez la liste des cibles avec Select-Object, conservez une preuve au format CSV avec Export-Csv, confirmez les modifications prévues avec -WhatIf, puis exécutez pour de bon. Comme PowerShell permet d'exécuter l'investigation et la modification dans le même écran, l'habitude de commencer par des vérifications en lecture seule est essentielle.

Profil de l’auteur

Page de présentation de l’auteur de l’article.

Go Komura

Représentant de KomuraSoft LLC

Spécialisé dans le développement de logiciels Windows, le conseil technique et l’analyse de pannes, notamment pour les systèmes existants et les incidents difficiles à reproduire.

Retour au blog