PowerShell
Informations
Windows PowerShell (anciennement Microsoft Command Shell) est une suite logicielle développée par Microsoft qui intègre une interface en ligne de commande, un langage de script nommé PowerShell ainsi qu'un kit de développement.
Il est inclus dans Windows 7, Windows 8.1, Windows 10 et Windows 11 (y compris les versions grand public) et s'appuie sur le framework Microsoft .NET.
PowerShell se décline en deux programmes : PowerShell : permet d'exécuter des scripts ; PowerShell ISE : permet d'éditer des scripts et de les exécuter.
Commandlets
Les commandes PowerShell sont constituées d'un verbe ou d'un préfixe, suivis d'un nom, séparés par un tiret. Elles peuvent être accompagnées de paramètres.
Ces commandes sont communément appelées des commandlets, une contraction de command applets en anglais.
Dans l'interface en ligne de commande, les commandlets sont abrégées en cmdlets.
Créer un fichier par saisie
Si vous souhaitez créer un fichier par saisie de l'utilisateur, voici les cmdlets que vous devez utilisez :
Ici, nous allons dans un premier temps dire que notre variable $filename sera liée à la fonction Read-Host.
Read-Host permet d'inviter l'utilisateur à saisir une donnée. Aussi, entre les guillemets, nous avons ajouté un texte qui permet d'indiquer à l'utilisateur qu'il peut le faire.
Ensuite, le cmdlet New-Item permet de créer soit un fichier, dossier ou autres. -Name permet d'indiquer le nom de l'item, en l'occurrence ici, il est lié à notre variable. -ItemType permet d'indiquer le type d'item que nous souhaitons créer (fichier, dossier) et -Path indique son chemin de création.
$filename = Read-Host 'Saisissez le nom du fichier' New-Item -Name $filename -ItemType File -Path C:\Users\msa\Desktop\EPSIC\2022-23\122\wiki-opei
Créer des dossiers à partir d'une liste de mots
Si vous souhaitez créer des dossiers à partir d'un fichier TXT qui contient des mots, voici les cmdlets que vous allez devoir utiliser :
Dans un premier temps, nous allons nous rendre avec la commande cd dans le dossier où se trouve le fichier avec la liste de mots.
Ensuite, nous allons dire à notre variable $directoryfile de prendre le contenu du fichier texte avec Get-Content.
Pour terminer, nous allons faire un New-Item pour indiquer que nous allons créer un nouvel item (dossier, fichier,...) et utiliser un -ItemType pour préciser que c'est un dossier que nous souhaitons créer.
cd C:\Users\msa\Desktop\EPSIC\2022-23\122\wiki-opei $directoryfile = Get-Content -Path "C:\Users\msa\Desktop\EPSIC\2022-23\122\wiki-opei\wiki-opei.txt" New-Item $directoryfile -ItemType Directory
Créer un utilisateur local
Si vous souhaitez créer un utilisateur local, voici les deux méthodes possibles.
Ancienne méthode
$COMPUTER = [ADSI]"WinNT://$ENV:COMPUTERNAME,computer" [STRING]$NAME = Read-Host -Prompt "Saisissez un nom" [STRING]$FULLENAME = Read-Host "Saisissez le nom complet" [STRING]$DESCRIPTION = Read-Host "Saisissez une description" $NewUser = $COMPUTER.Create('User', $NAME) $NewUser.SetInfo() $NewUser.InvokeSet("FullName", $FULLENAME) $NewUser.description = $DESCRIPTION $NewUser.SetInfo() Write-Host "L'utilisateur a bien été créé !"
Nouvelle méthode
Dans un premier temps, nous allons définir trois variables, une pour dire quand il faut rentrer le nom de l'utilisateur, l'autre pour le nom complet ainsi que pour la description.
Ensuite, nous allons utiliser la commande New-LocalUser ou nous allons indiquer qu'il faut rentrer en premier lieu le nom, puis le -FullName donc le nom complet, la -Description pour la description et nous allons ajouter un -NoPassword car nous voulons pas de mot de passe pour cette utilisateur.
Pour terminer, nous allons utiliser un Write-Host pour indiquer la création est terminée.
$NomUtilisateur = Read-Host "Entrer le nom d'utilisateur" $NomComplet = Read-Host "Entrer le nom complet" $Description = Read-Host "Entrer la description du compte" New-LocalUser "$NomUtilisateur" -FullName "$NomComplet" -Description "$Description" -NoPassword Write-Host "L'utilisateur a bien été créé !"
Copier/coller, renommer et déplacer
Si vous souhaitez copier/coller, renommer et déplacer un fichier dans un dossier, voici les cmdlets que vous allez devoir utiliser :
En premier lieu, nous allons copier l'item, le fichier avec la commande Copy-Item, ensuite pour le coller nous allons simplement indiquer la -Destination avec le nouveau nom à la fin.
Ensuite, pour renommer l'item, nous allons utiliser le cmdlet Rename-Item en indiquant après le -NewName le nouveau nom du fichier.
Pour créer un dossier, nous allons de nouveau utiliser le cmdlet New-Item et nous allons indiquer le type avec le -ItemType dossier.
Pour terminer, pour le déplacer nous allons utiliser le cmdlet Move-Item en indiquant le -Name et la -Destination vers le dossier ou nous voulons le créer.
Après chaque commande, nous allons utiliser un Write-Host avec entre guillemets l'étape faite. Ceci permet d'indiquer à l'utilisateur ce qui a été fait après la commande.
Copy-Item 'C:\Users\msa\Desktop\EPSIC\2022-23\122\wiki-opei\wiki-opei.txt' -Destination 'C:\Users\msa\Desktop\EPSIC\2022-23\122\wiki-opei\wiki-opei-new.txt' Write-Host "Étape 1 : Copie faite Marijan" Rename-Item 'C:\Users\msa\Desktop\EPSIC\2022-23\122\wiki-opei\wiki-opei.txt' -NewName 'C:\Users\msa\Desktop\EPSIC\2022-23\122\wiki-opei\wiki-opei-old.txt' Write-Host "Étape 2 : Renommage fait Marijan" New-Item -Name OLD -ItemType Directory Write-Host "Étape 3 : Ancien dossier crée Marijan" Move-Item 'C:\Users\msa\Desktop\EPSIC\2022-23\122\wiki-opei\wiki-opei-old.txt' -Destination 'C:\Users\msa\Desktop\EPSIC\2022-23\122\wiki-opei\OLD' Write-Host "Étape 4 : Déplacement du fichier OK Marijan"
Obtenir les propriétés d'un fichier
Si vous souhaitez obtenir les propriétés d'un fichier, avec différentes étapes distincte, voici les cmdlets à utiliser :
Dans un premier temps, nous allons créer une variable $PATH afin d'indiquer quel fichier on souhaite cibler.
Ensuite, nous allons faire une variable $fileName où, dedans, nous allons indiquer que nous souhaiter obtenir des propriétés sur le fichier avec la fonction Get-ItemPropertyValue, en spécifiant que c'est pour le fichier derrière la variable $PATH, et que ici on cherche le -Name, donc le nom.
Pour la taille, nous allons faire une variable $size ou dans un premier temps, nous allons utiliser la variable $size.Length afin d'indiquer la taille et une deuxième ligne avec $size, avec un Get-Item $PATH pour indiquer que c'est pour le fichier qui se trouve derrière le $PATH.
Même principe pour $file, sauf qu'ici, on cherche l'extension avec la variable $file.Extension.
Nous allons finir pour les propriétés en créant la variable $lastwrite avec de nouveau Get-ItemPropertyValue du fichier derrière le $PATH avec le -Name LastWriteTime qui permet d'afficher la dernière modification.
Pour terminer, nous allons faire un Write-Output qui permet d'afficher le contenu des variables, ce qui n'est pas possible avec le Write-Host. Nous allons donc faire un Write-Ouput avec les différentes étapes ainsi que la $Variable à chaque étape que nous souhaitons afficher.
$PATH = 'C:\Users\msa\Desktop\EPSIC\2022-23\122\wiki-opei\wiki-opei.txt' $fileName = Get-ItemPropertyValue $PATH -Name Name $size = Get-Item $PATH $size = $size.Length $file = Get-Item $PATH $file = $file.Extension $lastWrite = Get-ItemPropertyValue $PATH -Name LastWriteTime Write-Output "Etape 1: $fileName" Write-Output "Etape 2: $size" Write-Output "Etape 3: $PATH" Write-Output "Etape 4: $file" Write-Output "Etape 5: $lastWrite"
Obtenir les informations sur la carte graphique
Si vous souhaitez obtenir les information de la carte graphique, avec différentes étapes distincte, voici les cmdlets à utiliser :
Dans un premier temps, nous allons définir une variable (ici $video) avec la fonction "Get-WmiObject Win32_videoController".
Puis, nous allons utiliser les différentes options de cette fonction pour obtenir les informations requises.
Ici, nous aurons besoin du nom ($video.Name), de la version du pilote graphique ($video.DriverVersion), de la résolution (Write-Host = "Étape 3 :"$video.CurrentHorizontalResolution x $video.CurrentVerticalResolution) et la description ($video.Caption).
$video = Get-WmiObject Win32_videoController Write-Host = "Étape 1 :" $video.Name Write-Host = "Étape 2 :" $video.DriverVersion Write-Host = "Étape 3 :" $video.CurrentHorizontalResolution x $video.CurrentVerticalResolution Write-Host = "Étape 4 :" $video.Caption
Obtenir les informations sur l'OS
Si vous souhaitez obtenir les information du système d'exploitation avec différentes étapes distincte, voici les cmdlets à utiliser :
Dans un premier temps, nous allons définir une variable (ici $OS) avec la fonction "Get-WMIObject win32_operatingsystem".
Puis, nous allons utiliser les différentes options de cette fonction pour obtenir les informations requises.
Ici, nous aurons besoin de la description ($OS.Caption), de l'architecture ($OS.OSArchitecture), de la langue ($OS.OSLanguage) et du fournisseur ($OS.Manufacturer).
$OS = Get-WMIObject win32_operatingsystem Write-Host = "Étape 1 :" $OS.Caption Write-Host = "Étape 2 :" $OS.OSArchitecture Write-Host = "Étape 3 :" $OS.OSLanguage Write-Host = "Étape 4 :" $OS.Manufacturer
Obtenir les informations sur le stockage
Si vous souhaitez obtenir les information du stockage avec différentes étapes distincte, voici les cmdlets à utiliser :
Dans un premier temps, nous allons définir une variable (ici $Disk) avec la fonction "get-wmiobject -class win32_logicaldisk".
Puis, nous allons utiliser les différentes options de cette fonction pour obtenir les informations requises.
Ici, nous aurons besoin du nom ($Disk.Name), de la 'taille ($Disk.Size), de l'espace libre ($Disk.Size) et du type de système de fichiers ($Disk.FileSystem).
$Disk = get-wmiobject -class win32_logicaldisk Write-Host = "Étape 1 :" $Disk.Name Write-Host = "Étape 2 :" $Disk.Size Write-Host = "Étape 3 :" $Disk.Freespace Write-Host = "Étape 4 :" $Disk.FileSystem
Programmation
Variables
Les variables sont utilisées pour stocker des valeurs de différents types, permettant ainsi de stocker les résultats des commandes, les éléments utilisés dans les commandes et les expressions, tels que les noms, les chemins, les paramètres et les valeurs.
Principalement, les deux types de variables utilisées sont celles créées par l'utilisateur et celles déjà existantes par défaut dans le langage de programmation.
Créer par l'utilisateur
- Exemple de variable créer par l'utilisateur :
$ExempleUtilisateur = "Marijan" Write-Host $ExempleUtilisateur Marijan
Par défaut
- Exemple de variable déjà existante dans le langage :
$Host Name : ConsoleHost Version : 5.1.19041.2673 UI : System.Management.Automation.Internal.Host.InternalHostUserInterface CurrentCulture : fr-CH CurrentUICulture : fr-FR PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy DebuggerEnabled : True IsRunspacePushed : False Runspace : System.Management.Automation.Runspaces.LocalRunspace
Opérateurs
Les opérateurs permettent d'effectuer des opérations sur les données comme par exemple des multiplications ou des comparaisons de données. Les deux principaux qui nous intéresses sont les athématiques et ceux de comparaison.
Athématiques
- Les athématiques sont ces opérateurs qui permettent de faire des calculs.
Signe | Signification |
---|---|
+ | Addition |
- | Soustraction |
* | Multiplication |
/ | Division |
% | Modulo |
Comparaison
- Les opérateurs de comparaison permettent de comparer des données :
Opérateur | Signification | Comparaison |
---|---|---|
-eq | Egal | A = B |
-ne | Non égal (différent) | A != B |
-gt | Strictement sup. | A > B |
-ge | Sup. ou égal | A >= B |
-lt | Strictement inf. | A < B |
-le | Inf. ou égal | A <= B |
Boucles
Les boucles permettent d'exécuter à plusieurs reprises les instructions qui ce trouvent à l'intérieur et tant que on lui indique pas de sortir, il va continuer.
While
Les instructions répétées seront exécutées tant que la condition spécifiée au début de la boucle reste vraie.
- Par exemple : Ici, tant que la variable $nombre est strictement inférieure à 10, alors on va répéter l'instruction.
$nombre = 0 while ($nombre -lt 10) { $nombre++ }
For
La boucle For est constituée de trois parties distinctes. La première partie représente la valeur initiale de la variable principale de la boucle. La deuxième partie correspond à la condition qui, lorsque remplie, permet à la troisième partie d'augmenter la valeur de cette variable.
- Par exemple : Ici, nous avons une valeur initial de 0, une condition qui dis que tant que nous sommes strictement inférieur à 10 il faudra donc faire l'incrémentation, donc faire +1.
For ($nombre = 0;$nombre -lt 10;$nombre++) { Write-Host = $nombre }
Foreach
La boucle foreach est utilisée pour parcourir des éléments d'une collection (comme un tableau, une liste ou un répertoire) et exécuter une action sur chaque élément.
- Par exemple : Nous allons créer une variable qui contient trois éléments et à l'aide d'un foreach, nous allons les lister.
$objets = ("laptop", "chargeur", "stylo") foreach ($objet in $objets) { Write-Host $objet } laptop chargeur stylo
Conditions
Les conditions permettent de diriger l'exécution de vos blocs d'instructions.
If, Else et Elseif
If, Else et Elseif ont le même fonctionnement, si la condition de If est respectée, son bloc d'instruction s'exécutera. Sinon, c'est celui des ElseIf (si leurs conditions sont respectées) ou du Else qui s'exécutera.
Le fonctionnement des If, Else et ElseIf, c'est que si par exemple les conditions du If ne sont pas remplies, celles des ElseIf seront testés de la même manière et si aucune n'est satisfaite, le Else s'exécutera.
- Par exemple : Ici, on demande à l'utilisateur de choisir un jour de la semaine. Un texte différent s'affichera pour chaque jour de la semaine grâce au If et au ElseIf, et un autre s'affichera pour les autres jours de la semaine ou les entrées différentes part le Else.
$x = Read-Host = "Entrer un jour de la semaine" If($x -eq "Lundi"){ Write-Host "Dur, le lundi !" } ElseIf($x -eq "Mardi"){ Write-Host"Le mardi aussi... " } ElseIf($x -eq "Mercredi"){ Write-Host "Mercredi... La moitié de faite !" } ElseIf($x -eq "Jeudi"){ Write-Host "Dernier jour de taff avant les cours !" } ElseIf($x -eq "Vendredi"){ Write-Host "Journée à l'EPSIC, quel bonheur !" } Else { Write-host "Enfin le week-end, bordel... Ou alors, vous n'avez pas entré un jour de la semaine." } Entrer un jour de la semaine : Lundi Dur, le lundi !
Switch
La condition switch permet d'afficher différentes sorties en fonction de la réponse fournie par l'utilisateur.
- Par exemple : supposons que nous demandions à l'utilisateur de fournir une réponse entre 1 et 4. En fonction de sa réponse, nous afficherons une sortie différente.
$reponse = Read-Host "Choisissez un nombre entre 1 et 4" switch ($reponse) { "1" { Write-Host "Vous avez choisi le nombre 1." } "2" { Write-Host "Vous avez choisi le nombre 2." } "3" { Write-Host "Vous avez choisi le nombre 3." } "4" { Write-Host "Vous avez choisi le nombre 4." } default { Write-Host "Réponse non valide." } } Choisissez un nombre entre 1 et 4 : 2 Vous avez choisi le nombre 2.
Fonctions
En utilisant des fonctions, on évite de répéter des morceaux de code. Cela permet principalement de rendre le code plus concis et plus facile à comprendre. Par exemple, si nous avons une fonctionnalité qui effectue la même tâche à plusieurs endroits du code, au lieu de devoir mettre à jour chaque occurrence séparément, nous n'avons qu'à mettre à jour la fonction correspondante.
- Par exemple : Si nous n'utilisons pas de fonction pour l'exemple ci-dessous, nous devrons mettre à jour le message d'erreur à chaque emplacement dans notre code :
Write-Host "Il y a une erreur ici !" Il y a une erreur ici !
- En revanche, si nous mettons en place une fonction, il suffira simplement de la mettre à jour pour que les modifications s'appliquent automatiquement à tous les endroits où un message d'erreur doit apparaître :
function AfficherErreur { Write-Host "Il y a une erreur ici !" } AfficherErreur Il y a une erreur ici !
Export/Import CSV
L'extension CSV (Comma-Separated Values) a pour but de présenter des données séparées par des virgules, des points-virgules ou par un autre séparateur.
Une de ses fonctionnalités principales est d'importer et d'exporter des données afin de les transmettre entre différents programmes.
- Par exemple : Voici comment importer un fichier CSV.
$CSV_Path = "C:\Users\msa\Desktop\EPSIC\2022-23\122\CSV\User.csv" Import-Csv -Path $CSV_Path -Delimiter ";" -Encoding Default
Dans la première variable, on déclare le chemin du fichier en question.
Ensuite, nous utilisons Import-Csv donc pour l'import, puis on ajoute le paramètre -Path pour déclarer le chemin, -Delimiter ";" car notre fichier CSV est en point-virgule puis on défini l'encodage avec le -Encoding Default.
- Par exemple : Voici comment exporter un fichier CSV.
$CSV_Path = "C:\Users\msa\Desktop\EPSIC\2022-23\122\CSV\User.csv" Export-Csv -Path $CSV_Path -NoTypeInformation -Delimiter ";"
Dans la première variable, on déclare également le chemin du fichier en question.
Ensuite, nous utilisons Export-Csv donc pour l'import, puis on ajoute le paramètre -Path pour déclarer le chemin, -Delimiter ";" car notre fichier CSV est en point-virgule puis on ajoute le paramètre -NoTypeInformation pour éviter d'avoir les informations de base ajouter par PowerShell par défaut.
Try / Catch / Finally
Projets
Voici ci-dessous mes projets PowerShell.
Administration d'un Active Directory à partir de script
Ci-dessous, vous trouverez une vidéo qui présente le fonctionnement de mes scripts pour l'administration d'un Active Directory. Voici les différents scripts inclus :
- Génération aléatoire d'un mot de passe fort et attribution aux utilisateurs répertoriés dans un fichier CSV ;
- Création d'unités d'organisation à partir de la colonne appropriée dans le fichier CSV ou manuellement en utilisant les champs proposés ;
- Création d'utilisateurs en utilisant les colonnes appropriées dans le fichier CSV ou manuellement en utilisant les champs proposés ;
- Attribution d'une date d'expiration et création d'une unité d'organisation pour les utilisateurs dont la date a expiré, puis déplacement de ces utilisateurs dans cette unité ;
- Exportation des utilisateurs de l'Active Directory vers un fichier CSV.
Déploiement de VMs sur un ESXi depuis PowerCLI
J'ai créé un script utilisant le module PowerCLI pour déployer des machines virtuelles sur l'ESXi à partir d'un serveur distant.
Vérification et sauvegarde sur Veeam
J'ai créé un script en utilisant le module par défaut de Veeam pour vérifier l'existence des machines virtuelles et effectuer une sauvegarde une fois que tout a été vérifié.
Modification d'un fichier .docx à partir de script
Ci-dessous, un code pour modifier un fichier .docx en PowerShell. Pour ce faire, il est obligatoire de convertir le fichier en .zip puis en dossier afin d'accéder au fichier intitulé document.xml pour la modification du contenu. Une fois fais, on reconverti en .zip puis on remet en .docx.
Afin d'éviter de corrompre le fichier lors de la conversion en .zip, il faut utiliser Pre PowerShell v5, .NET style. Avec les dernières versions, la conversion .docx > .zip > dossier > .zip > .docx corrompe le fichier.
# Defaults variables $FirstName = "Marijan" $Lastname = "Stajic" $Initials = "MSA" $Password = "MonM0tD4P@sse" # .docx file path $template = "C:\path\to\file.docx" # Folder path $templateFolder = "C:\path\to\temp_folder" # Unzip/Zip with Pre PowerShell v5, .NET style Add-Type -AssemblyName System.IO.Compression.FileSystem # Unzip .docx file [System.IO.Compression.ZipFile]::ExtractToDirectory($template, $templateFolder) # Replace content $bodyFile = $templateFolder + "\word\document.xml" $body = Get-Content $bodyFile $body = $body.Replace("[NAME1]", $FirstName) $body = $body.Replace("[NAME2]", $Initials) $body = $body.Replace("[NAME3]", $Password) $body | Out-File $bodyFile -Force -Encoding Default # Zip .docx file [System.IO.Compression.ZipFile]::CreateFromDirectory($templateFolder, "C:\path\to\final_file.docx") # Remove folder Remove-Item $templateFolder -Recurse -Confirm:$false | Out-Null