10 commandes pour administrer Windows avec PowerShell
Sommaire
- I. Présentation
- II. Récupérer des informations sur l'ordinateur
- III. Redémarrer l'ordinateur local ou distant
- IV. Renommer l'ordinateur
- V. Intégrer l'ordinateur à l'Active Directory
- VI. Installer un rôle ou une fonctionnalité
- VII. Gérer les processus Windows
- VIII. Arrêter un processus Windows
- IX. L'historique des mises à jour installées
- X. Rechercher les fichiers volumineux
- XI. Consulter les journaux d'événements de Windows
- XII. Conclusion
I. Présentation
Dans ce chapitre, nous allons explorer des commandes PowerShell qui sont utiles pour l'administration de postes de travail Windows et de serveur Windows Server, en prenant 10 cas pratiques comme exemple ! Cette liste n'est pas exhaustive et nous continuerons à manipuler d'autres cmdlets dans les prochains chapitres.
II. Récupérer des informations sur l'ordinateur
Le cmdlet "Get-ComputerInfo" peut être utilisé pour récupérer des informations générales sur l'ordinateur local. Il va retourner des informations diverses et variées sur le système d'exploitation, le matériel, les paramètres régionaux, les paramètres système ou encore sur le BIOS. Il peut rendre bien des services.
Get-ComputerInfo
Voici un exemple de résultat :
Par exemple, la propriété "OsName" retournera le nom complet du système d'exploitation ("Microsoft Windows 11 Professionnel") alors que la propriété "OsBuildNumber" retournera le numéro de build ("22631").
En fait, c'est un cmdlet qui consolide des informations que nous pouvons obtenir par l'intermédiaire des classes WMI, sauf qu'ici, nous n'avons pas besoin de connaître les requêtes WMI correspondantes. Ceci évite d'utiliser les cmdlets "Get-WmiObject" et "Get-CimInstance".
III. Redémarrer l'ordinateur local ou distant
Si vous souhaitez redémarrer un ordinateur à l'aide de PowerShell à partir de la ligne de commande, vous pouvez utiliser la commande "shutdown" avec les bonnes options, mais également le cmdlet PowerShell "Restart-Computer. Il est compatible uniquement avec Windows et nous pouvons l'utiliser pour redémarrer la machine locale ou des machines distantes.
Le fait de l'exécuter sur une machine locale, sans préciser de paramètre, va déclencher un redémarrage immédiat de la machine.
Restart-Computer
Il est très utile pour redémarrer à distance plusieurs machines, ce qui évitera de se connecter et d'ouvrir une session sur les machines en question afin de lancer un redémarrage. Ceci implique que la gestion à distance soit activée sur la machine distante et que vous disposiez de permissions suffisantes (sinon, vous devez utiliser le paramètre "-Credential").
L'exemple ci-dessous permet de redémarrer l'hôte "SRV-ADDS-01.it-connect.local".
Restart-Computer -ComputerName SRV-ADDS-01.it-connect.local
Nous pouvons aussi exploiter le cmdlet "Restart-Computer" dans un script et indiquer à PowerShell qu'il doit attendre que la machine soit redémarrée avant de poursuivre l'exécution du script. Pour cela, nous devons utiliser des paramètres supplémentaires.
L'exemple ci-dessous permet de redémarrer l'hôte "SRV-ADDS-01.it-connect.local", puis nous allons attendre le redémarrage pendant 3 minutes (timeout de 180 secondes), tout en vérifiant toutes les 3 secondes si la machine est de nouveau en ligne. Le paramètre "-Force" est utile pour forcer le redémarrage, même s'il y a un utilisateur connecté sur la machine.
Restart-Computer -ComputerName SRV-ADDS-01.it-connect.local -Wait -Timeout 180 -Delay 3 -Force
IV. Renommer l'ordinateur
Suite à l'installation d'une nouvelle machine Windows, vous pouvez renommer le système à l'aide du cmdlet "Rename-Computer". Le paramètre "-NewName" permet de préciser le nouveau nom d'hôte, tandis que le paramètre "-Restart" va permettre de redémarrer la machine immédiatement pour finaliser l'opération.
Voici un exemple pour attribuer le nom "PC-W11" à la machine locale.
Rename-Computer -NewName "PC-W11" -Restart
Nous pouvons également agir sur une machine distante à l'aide du paramètre "-ComputerName".
V. Intégrer l'ordinateur à l'Active Directory
Pour intégrer une machine Windows à un annuaire Active Directory, nous pouvons naviguer dans l'interface graphique de Windows, ou faire appelle au cmdlet PowerShell nommé "Add-Computer. L'avantage, c'est qu'il s'utilise de la même façon sur Windows 10, Windows 11, Windows Server, etc... Donc, nous ne perdrons pas de temps à naviguer dans les menus de Windows qui varient d'une version à une autre.
L'exemple ci-dessous permet d'intégrer le domaine "it-connect.local" et nous serons invités à préciser des identifiants pour nous authentifier auprès des services d'annuaire Active Directory. Le cmdlet "Get-Credential" sert à demander à l'utilisateur de saisir des identifiants (un nom d'utilisateur et un mot de passe), et les informations saisies seront utilisées comme valeur pour le paramètre "-DomainCredential".
Add-Computer -DomainName "it-connect.local" -DomainCredential (Get-Credential)
VI. Installer un rôle ou une fonctionnalité
Sur un poste de travail Windows, nous pouvons installer des fonctionnalités supplémentaires en piochant dans une liste de fonctionnalités facultatives. Sur un serveur Windows Server, nous pouvons également installer des rôles et des fonctionnalités : serveur DHCP, serveur DNS, WSUS, les services de domaine Active Directory, etc.
De ce fait, en fonction du type de système d'exploitation, nous ne devons pas utiliser le même cmdlet pour effectuer l'installation ou la désinstallation de fonctionnalités ou rôles :
- Install-WindowsFeature sur Windows Server
- Enable-WindowsOptionalFeature sur Windows
Ces cmdlets doivent être utilisés à partir d'une console PowerShell ouverte en tant qu'administrateur.
A. Serveurs sous Windows Server
Avant même de chercher à installer une fonctionnalité ou un rôle Windows Server, nous allons générer une liste pour indiquer le statut de chaque élément.
Get-WindowsFeature
Voici un exemple de sortie où nous pouvons voir que les rôles "Serveur DHCP" et "Serveur DNS" sont installés.
Si nous cherchons à obtenir une liste précise de tous les rôles et fonctionnalités installées sur un serveur, nous pouvons filtrer de cette façon :
Get-WindowsFeature | Where-Object { $_.InstallState -eq "Installed" }
Ensuite, pour procéder à l'installation, nous devons utiliser le cmdlet "Install-WindowsFeature". Ce cmdlet peut installer une ou plusieurs fonctionnalités à la fois, et il peut également agir sur une machine distante.
L'exemple suivant permet d'installer le rôle "Hyper-V" sur le serveur, en intégrant les outils d'administration ("-IncludeManagementTools"), c'est-à-dire le "Gestionnaire Hyper-V" dans le cadre de l'installation de ce rôle. Le serveur va également redémarrer automatiquement ("-Restart").
Install-WindowsFeature -Name Hyper-V -IncludeManagementTools -Restart
L'opération inverse, à savoir la désinstallation d'une fonctionnalité ou d'un rôle, est possible à l'aide du cmdlet "Uninstall-WindowsFeature".
B. Postes de travail sous Windows
Désormais, nous allons évoquer la gestion des fonctionnalités facultatives sur les postes de travail Windows.
Nous pouvons lister l'ensemble des fonctionnalités facultatives disponibles à l'aide du cmdlet "Get-WindowsOptionalFeature". Le fait de préciser le paramètre "-Online" signifie que nous ciblons l'image Windows en ligne, c'est-à-dire celle exécutée sur la machine en cours d'exécution.
Get-WindowsOptionalFeature -Online | Format-Table FeatureName, State
Ceci permettra d'avoir un tableau avec le nom de l'ensemble des fonctionnalités et leur statut. Si la propriété "State" contient "Enabled", cela signifie que la fonctionnalité est activée, et donc installée, sur la machine locale.
Ensuite, nous pouvons installer une fonctionnalité à l'aide du cmdlet "Enable-WindowsOptionalFeature". Par exemple, pour installer le rôle Hyper-V sur Windows 10 ou Windows 11, nous devons utiliser la commande suivante :
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
Ceci va installer le rôle Hyper-V sur Windows, ainsi que toutes ses dépendances éventuelles.
VII. Gérer les processus Windows
Le cmdlet "Get-Process" de PowerShell permet de lister les processus actifs sur une machine. Il va permettre d'obtenir de nombreuses informations à leur sujet, notamment leur nom, leur PID, la mémoire consommée, le CPU consommé, la date et l'heure à laquelle le processus a été créé, etc.
Get-Process
Sans utiliser PowerShell, nous pouvons utiliser "Gestionnaire des tâches" de Windows pour avoir un aperçu en temps réel des processus en cours d'exécution sur la machine locale.
Le cmdlet "Get-Process" va permettre de faire la même chose, à l'aide de PowerShell. Son exécution sans paramètre va lister les processus actifs à l'instant t :
Dans la sortie ci-dessus, il est intéressant de noter que les noms des propriétés (des colonnes) sont en fait des alias de propriétés vers d'autres noms de propriétés. La commande "Get-Member" que nous avons étudiée dans un précédent chapitre nous permet de le vérifier :
Get-Process | Get-Member Name MemberType Definition ---- ---------- ---------- Handles AliasProperty Handles = Handlecount Name AliasProperty Name = ProcessName NPM AliasProperty NPM = NonpagedSystemMemorySize64 PM AliasProperty PM = PagedMemorySize64 SI AliasProperty SI = SessionId VM AliasProperty VM = VirtualMemorySize64 WS AliasProperty WS = WorkingSet64
Pour avoir une sortie qui se rapproche réellement de l'affichage du "Gestionnaire des tâches", et notamment avoir le nom de l'utilisateur qui est à l'origine de l'exécution du processus, on va ajouter le paramètre "-IncludeUserName".
Get-Process -IncludeUserName
La propriété nommée "WS" correspond à "WorkingSet", ce qui indique en fait la consommation en RAM de ce processus, ici en "Mégaoctets". Tandis que la colonne "CPU" indique le temps d'utilisation du processeur.
Avec la commande initiale (sans "-IncludeUserName"), la valeur est en octet. Ainsi, pour obtenir la liste de tous les processus qui consomment au minimum 100 Mo de RAM, nous utiliserons la valeur "100000000".
Get-Process | Where-Object { $_.WorkingSet -ge 100000000 }
Si nous recherchons un processus spécifique en cours d'exécution, en lien avec un logiciel, par exemple, le navigateur Chrome et son processus "chrome", nous pouvons affiner la commande :
Get-Process -Name "chrome" -IncludeUserName
Ou, tout simplement :
Get-Process -Name "chrome"
La liste des propriétés disponibles avec la commande "Get-Process" est très longue. Nous pouvons, par exemple, obtenir la date de création de chaque processus grâce à la propriété "StartTime".
Get-Process | Format-Table Name, StartTime
VIII. Arrêter un processus Windows
En complément du cmdlet "Get-Process", celui nommé "Stop-Process" joue un rôle clé dans la gestion des processus, car il va nous permettre d'arrêter un processus. Ceci peut s'avérer très utile pour tenter de forcer l'arrêt d'un programme et que vous ne parvenez pas à l'arrêter proprement.
Nous allons chercher à arrêter tous les processus associés au navigateur "Microsoft Edge". Nous pouvons lister ces processus avec le cmdlet "Get-Process" :
Get-Process "msedge"
Puis, nous pouvons envoyer la liste de processus à "Stop-Process" via le pipeline. Ceci va tuer immédiatement tous les processus, donc cette commande est puissante, mais peut aussi être dangereuse.
Get-Process "msedge" | Stop-Process
Nous pouvons voir que tous les processus "msedge" ont été arrêtés :
Si vous souhaitez arrêter uniquement un processus avec un ID spécifique, c'est possible. Dans ce cas, nous devons utiliser le paramètre "-Id" suivi de l'ID du processus à arrêter. Par exemple :
Stop-Process -Id 652
Pour identifier votre cible, travaillez déjà avec "Get-Process" puis, initiez "Stop-Process". Vous pouvez même stocker le résultat dans une variable et l'appeler ensuite avec "Stop-Process".
IX. L'historique des mises à jour installées
Le suivi des mises à jour Windows est très important. Sur ce système d'exploitation, le composant "Windows Update" est en charge de la recherche et de l'installation des mises à jour.
PowerShell propose un cmdlet nommé "Get-HotFix" qui permet d'obtenir la liste des correctifs installés sur la machine locale, en s'appuyant sur la classe WMI "Win32_QuickFixEngineering". Nous pouvons l'utiliser de cette façon afin d'obtenir une liste des correctifs, classés par date d'installation (du plus récent au plus ancien) :
Get-HotFix | Sort-Object -Property InstalledOn -Descending
Voici un exemple :
Le problème, c'est que cette historique ne contient pas la liste de toutes les mises à jour installées, donc ceci ne permet pas d'avoir un aperçu complet de l'historique des mises à jour.
Pour avoir des résultats plus précis, nous allons installer le module "PSWindowsUpdate" sur notre machine. Ce module communautaire est disponible sur le site PowerShell Gallery.
Install-Module -Name PSWindowsUpdate -Force
Ce module fonctionne avec Windows PowerShell et PowerShell, y compris PowerShell 7. Une fois l’installation terminée, nous pouvons lister les commandes disponibles dans ce module :
Get-Command -Module PSWindowsUpdate
Ce module permet de gérer Windows Update dans son ensemble. Il est très complet et ne se limite pas à l'obtention de la liste des mises à jour installées.
L'exemple ci-dessous permettra d'obtenir la liste de toutes les mises à jour installées, de la plus récente à la plus ancienne. Il intègre aussi les mises à jour de définition pour Microsoft Defender, celles pour PowerShell (pour PowerShell 7, si les mises à jour par Windows Update sont activées), etc.
Get-WUHistory | Sort-Object -Property Date -Descending
Voici un exemple :
Nous pouvons améliorer cet affichage en sélectionnant trois propriétés : "KB" pour avoir le numéro de KB de la mise à jour, "Date" pour avoir la date et l'heure d'installation, ainsi que "Title" pour avoir le titre complet de la mise à jour. Nous pouvons aussi utiliser un affichage en mode graphique via "Out-GridView", même si c'est facultatif. Nous affichons uniquement les mises à jour où la colonne "KB" n'est pas vide.
Get-WUHistory | Select-Object KB, Date, Title | Where-Object { $_.KB -ne "" }
Get-WUHistory | Select-Object KB, Date, Title | Where-Object { $_.KB -ne "" } | Out-GridView
Le résultat obtenu est beaucoup plus intéressant qu'avec le cmdlet "Get-HotFix".
Nous pouvons aussi afficher toutes les mises à jour installées à partir d'une certaine date, grâce au paramètre "-MaxDate". Pour obtenir les mises à jour installées sur les 31 derniers jours, cela donne :
Get-WUHistory -MaxDate $((Get-Date).AddDays(-31))
Tandis que pour les mises à jour installées depuis le 01 mars 2024, cela donne :
Get-WUHistory -MaxDate "01/03/2024"
Enfin, vous pouvez rechercher une mise à jour spécifique à partir de son nom de KB. Voici un exemple pour rechercher la mise à jour "KB5035853".
Get-WUHistory | Where-Object { $_.KB -eq "KB5035853" }
X. Rechercher les fichiers volumineux
Le cmdlet "Get-ChildItem" sert à lister le contenu d'un répertoire ou d'une arborescence complète puisqu'il va retourner l'ensemble des fichiers et dossiers présents sous la racine spécifiée. Il a accès aux propriétés des dossiers et fichiers, ce qui ouvre de nombreuses possibilités : effectuer une recherche sur des types de fichiers spécifiques (en fonction de l'extension), effectuer une recherche basée sur la taille des fichiers, etc.
La commande ci-dessous permet de lister le contenu de premier niveau présent dans "C:\Windows".
Get-ChildItem -Path "C:\Windows"
Si nous souhaitons lister tous les fichiers et dossiers, de façon récursive, nous devons ajouter ce paramètre :
Get-ChildItem -Path "C:\Windows" -Recurse
Nous pouvons affiner notre recherche en fonction d'un filtre via le paramètre "-Filter". Par exemple, pour afficher uniquement les fichiers exécutables avec l'extension ".exe" :
Get-ChildItem -Path "C:\Windows" -Recurse -Filter *.exe
Désormais, nous allons chercher à obtenir la liste des 10 fichiers les plus volumineux présents sur le volume "P:" d'une machine, qui pourrait être un poste de travail ou un serveur. Nous obtenons un classement des fichiers, du plus volumineux au moins volumineux. Nous pourrions avoir une liste plus conséquente en ajustant la valeur du paramètre "-First" du cmdlet "Select-Object".
Get-ChildItem P:\ -Recurse | Sort-Object -Descending -Property Length | Select-Object -First 10 Name, Length
Pour que la taille soit plus facilement lisible, nous pouvons créer une propriété calculée basée sur l'utilisation de la méthode "[math]::round()" pour afficher la taille en Go :
Get-ChildItem P:\ -Recurse | Sort-Object -Descending -Property Length | Select-Object -First 10 Name, @{Name="GB";Expression={[math]::round($_.Length/1Gb, 3)}}
Voici le résultat obtenu :
Enfin, pour que ce soit plus précis, nous pouvons ajouter la propriété "DirectoryName" car elle va permettre d'ajouter le chemin correspondant à l'emplacement du fichier.
Get-ChildItem P:\ -Recurse | Sort-Object -Descending -Property length | Select-Object -First 10 name, @{Name="MB";Expression={[math]::round($_.Length/1mb, 2)}},DirectoryName
Enfin, sachez que nous pourrions aussi cibler la recherche sur un type de fichiers spécifique. Par exemple, pour obtenir le "Top 10" des archives ZIP présentes sur le volume "P:" de la machine, nous pourrons ajuster la commande précédente comme ceci :
Get-ChildItem P:\ -Recurse -Include "*.zip" | Sort-Object -Descending -Property length | Select-Object -First 10 name, @{Name="MB";Expression={[math]::round($_.Length/1mb, 2)}},DirectoryName
XI. Consulter les journaux d'événements de Windows
Sur une machine Windows, les journaux sont accessibles par l'intermédiaire de l'"Observateur d'événements" qui contient un ensemble de journaux, notamment les journaux "Applications", "Système" et "Sécurité" qui sont les plus connus.
Certaines actions effectuées sur le système sont susceptibles de créer un événement. Les erreurs sont également visibles dans les journaux. Ceci en fait une source d'information très intéressante pour investiguer sur un dépannage ou un problème de sécurité, même si parfois, les journaux manquent de détails (ce qui pourra nous inciter à utiliser un outil tel que "Sysmon").
PowerShell est capable d'interagir avec les journaux de Windows, que ce soit pour créer un journal, créer un événement ou consulter les événements existants. Nous allons nous intéresser à ce dernier point.
Il existe deux cmdlets pour consulter les journaux Windows : "Get-EventLog" et "Get-WinEvent". Le second est le successeur du premier, mais les deux fonctionnent toujours, et dans certains cas, "Get-EventLog" peut s'avérer plus avantageux.
Tout d'abord, nous pouvons lister l'intégralité des journaux présents sur la machine locale :
Get-WinEvent -ListLog *
Nous obtenons une liste avec plusieurs informations, dont le nom de chaque journal, ainsi que le nombre d'événements qu'il contient actuellement, et sa taille maximale en octets.
Ce cmdlet est capable d'accéder aux événements présents dans les journaux sous "Journaux Windows" et "Journaux des applications et des services".
Ensuite, nous pourrons exploiter ce cmdlet pour effectuer quelques recherches dans ces journaux. Voici quelques exemples.
- Lister tous les événements du journal "Système"
Get-EventLog -LogName "System"
Get-WinEvent -LogName "System"
- Lister les 10 événements les plus récents du journal "Système"
Get-EventLog -LogName "System" -Newest 10
Le cmdlet "Get-WinEvent" n'a pas de paramètre "-Newest" donc si nous voulons obtenir les 10 événements les plus récents, nous devons utiliser le paramètre "-MaxEvents" ou l'associer à "Select-Object" même si la première option est plus pertinente :
Get-WinEvent -LogName "System" -MaxEvents 10
Get-WinEvent -LogName "System" | Select-Object -First 10
- Lister les dernières erreurs dans le journal "Système"
Get-EventLog -LogName "System" -EntryType Error
Il est important de préciser que le cmdlet "Get-EventLog" n'a pas accès aux journaux sous "Journaux des applications et des services", ce qui nous empêchera de lire certains journaux. Dans ce cas, nous pouvons utiliser "Get-WinEvent" avec un filtre sur la propriété "LevelDisplayName". Mais, attention, car la valeur tient compte du langage du système d'exploitation.
Voici comment filtrer pour afficher uniquement les erreurs :
Get-WinEvent -LogName "System" | Where-Object { $_.LevelDisplayName -eq "Erreur" }
- Lister les événements correspondants à un ID spécifique
Si vous recherchez tous les événements associés à un ID spécifique, voici la syntaxe à adopter :
Get-EventLog -LogName "System" -InstanceId 107
L'exemple ci-dessous permet de rechercher les événements avec l'ID "107" dans le journal "Système".
- Effectuer une recherche par mot clé dans un journal
Le paramètre "-Message" du cmdlet "Get-EventLog" permet d'effectuer une recherche basée sur le contenu du message, c'est-à-dire la description de l'événement. Ceci est pratique pour effectuer une recherche sur un mot clé.
Voici la syntaxe :
Get-EventLog -LogName "System" -Message "*<mot clé>*"
C'est important de préciser l'astérisque avant et après votre mot clé (constituée d'un ou plusieurs mots) afin d'effectuer une recherche par correspondance.
XII. Conclusion
Il existe bien d'autres cmdlets très intéressants et répondant à d'autres cas d'usage et scénarios, car PowerShell est un langage très riche : nous continuerons à en manipuler d'autres dans les prochains chapitres.