Introduction
Cet article ne pas faire de vous un professionnel de la programmation en powershell mais il va introduire les bases, le fonctionnement de la syntaxe et quelques commandes utiles dans la vie courante d'un type qui bosse avec Windows.
Fonctionnement
PowerShell est le langage de programmation développé par Microsoft pour communiquer avec leurs systèmes d'exploitation. On peut littéralement TOUT FAIRE avec powershell sur un système Windows. Ces particularités sont :
- Langage orienté objet
- Langage Shell (comme Bash, Zsh, CMD, etc...)
- Compréhension de la Pipeline nécessaire ( | )
- Depuis la v6 il fonctionne avec Linux & MacOS
- Conçu spécialement pour l'interopérabilité avec Active Directory & Windows
- Sécurité des signatures de scripts (Get-ExecutionPolicy)
On va expliquer tout ça.
Orienté Objet
Powershell manipule des objets avec des méthodes et des caractéristiques particulières. Par exemple :
Get-ChildItem (Meme fonction que 'ls' sur Linux)
- Vous cherchez tous les objets qui ont la propriété "enfant" du repertoire courant ou spécifié dans la commande.
- Mais comme chaque "Item" enfant a des propriétés vous les verrez apparaître comme, la CreationDate, BaseName, Extension, Length, etc... qu'on va apprendre à filtrer plus tard dans cet article.
Tandis que ls (avec Bash) va aussi lister les enfants du repertoire courant mais que sous forme de chaînes de cractères. Ce qui veut dire que chaque élément listé aura des propriétés mais pas dans la sortie de commande, on devra les récupérer avec d'autres outils comme awk, jq par exemple.
Langage Shell
Un langage shell (Bash, Zsh, PowerShell, etc..) se distingue des autres parcequ'il est conçu spécialement pour l'interaction avec un système en particulier. C'est un langage dit interprété c'est à dire que contrairement a un langage compilé il n'y a pas besoin de transformation préalable du code en un fichier exécutable. Une fois le script écrit par exemple script.ps1 vous aurez juste à l'exécuter avec l'interpréteur adéquat et il fonctionnera partout (Ici c'est powershell l'interpréteur). Le code sera exécuté ligne par ligne.
Pipeline Robuste
La Pipeline c'est l'utilisation des | dans l'écriture d'une commande (ou d'un script) pour transférer la sortie d'une commande vers une autre pour par exemple appliquer du filtrage. En PowerShell la pipeline fonctionne différemment de Bash/Zsh, je m'explique :
- En Bash/Zsh les | ne sont utilisées que pour transférer du texte brut :
ifconfig | grep "eth0"
Ici la commande ifconfig qui renvoie du texte concernant vos interfaces réseaux est filtrée avec la commande grep pour ne sortir que l'interface qui est eth0.
- En PowerShell, les | transmettent des objets, pas du texte :
Get-ChildItem -Filter "groscaca*" | Select-Object Name,CreationTime,Lentgh,Extension
Ici la commande va sortir tous les objets qui commencent par groscaca avec l'étoile à la fin du mot qui permet de spécifier que n'importequoi peut venir après on souhaite l'afficher quand même, et filtrer la sortie avec Select-Object pour n'afficher que les propriétées (Nom, Date de création, Taille, Extension) de l'objet groscaca.
Interopérabilité AD & Windows
PowerShell, étant conçu par Microsoft, va naturellement être adapté pour les produits de Microsoft tels que :
- Active Directory
- WMI Objects
- Meilleur que Windows Cmd
- Etc...
Par exemple pour créer un nouveau domaine Active Directory, et le gérer, on peut apprendre comment ça fonctionne avec PowerShell pour s'alléger drastiquement la vie et aller beaucoup plus vite sans avoir à retenir ou se trouve chaque bouton à la con sur le Gestionnaire de Server.
Voici le processus de création d'un domaine (Sample) à faire sur un Windows Server
- Installer la fonctionnalité AD
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
- Promouvoir le Serveur en Contrôleur de Domaines: (Retenez pas la manière dont le mot de passe est mis en place c'est pas bien dutout)
Install-ADDSForest -DomainName "nomdusuperdomaine.local" -SafeModeAdministratorPassword (ConvertTo-SecureString "AdminP@ssw0rd" -AsPlainText -Force) -Force
- Créer des groupes
New-ADGroup -Name "Comptable" -GroupScope Global -Path "CN=Users,DC=monentreprise,DC=local"
New-ADGroup -Name "Direction" -GroupScope Global -Path "CN=Users,DC=monentreprise,DC=local"
New-ADGroup -Name "Stagiaires" -GroupScope Global -Path "CN=Users,DC=monentreprise,DC=local"
- Créer des utilisateurs
# Comptabilité
New-ADUser -Name "Alice Dupont" -GivenName "Alice" -Surname "Dupont" -SamAccountName "alice.dupont" -UserPrincipalName "alice.dupont@monentreprise.local" -Path "CN=Users,DC=monentreprise,DC=local" -AccountPassword (ConvertTo-SecureString "Passw0rd!" -AsPlainText -Force) -Enabled $true
New-ADUser -Name "Bernard Martin" -GivenName "Bernard" -Surname "Martin" -SamAccountName "bernard.martin" -UserPrincipalName "bernard.martin@monentreprise.local" -Path "CN=Users,DC=monentreprise,DC=local" -AccountPassword (ConvertTo-SecureString "Passw0rd!" -AsPlainText -Force) -Enabled $true
New-ADUser -Name "Catherine Leroy" -GivenName "Catherine" -Surname "Leroy" -SamAccountName "catherine.leroy" -UserPrincipalName "catherine.leroy@monentreprise.local" -Path "CN=Users,DC=monentreprise,DC=local" -AccountPassword (ConvertTo-SecureString "Passw0rd!" -AsPlainText -Force) -Enabled $true
# Direction
New-ADUser -Name "David Morel" -GivenName "David" -Surname "Morel" -SamAccountName "david.morel" -UserPrincipalName "david.morel@monentreprise.local" -Path "CN=Users,DC=monentreprise,DC=local" -AccountPassword (ConvertTo-SecureString "Passw0rd!" -AsPlainText -Force) -Enabled $true
New-ADUser -Name "Emma Rousseau" -GivenName "Emma" -Surname "Rousseau" -SamAccountName "emma.rousseau" -UserPrincipalName "emma.rousseau@monentreprise.local" -Path "CN=Users,DC=monentreprise,DC=local" -AccountPassword (ConvertTo-SecureString "Passw0rd!" -AsPlainText -Force) -Enabled $true
New-ADUser -Name "François Lambert" -GivenName "François" -Surname "Lambert" -SamAccountName "francois.lambert" -UserPrincipalName "francois.lambert@monentreprise.local" -Path "CN=Users,DC=monentreprise,DC=local" -AccountPassword (ConvertTo-SecureString "Passw0rd!" -AsPlainText -Force) -Enabled $true
# Stagiaires
New-ADUser -Name "Gabriel Fontaine" -GivenName "Gabriel" -Surname "Fontaine" -SamAccountName "gabriel.fontaine" -UserPrincipalName "gabriel.fontaine@monentreprise.local" -Path "CN=Users,DC=monentreprise,DC=local" -AccountPassword (ConvertTo-SecureString "Passw0rd!" -AsPlainText -Force) -Enabled $true
New-ADUser -Name "Hugo Bernard" -GivenName "Hugo" -Surname "Bernard" -SamAccountName "hugo.bernard" -UserPrincipalName "hugo.bernard@monentreprise.local" -Path "CN=Users,DC=monentreprise,DC=local" -AccountPassword (ConvertTo-SecureString "Passw0rd!" -AsPlainText -Force) -Enabled $true
New-ADUser -Name "Isabelle Girard" -GivenName "Isabelle" -Surname "Girard" -SamAccountName "isabelle.girard" -UserPrincipalName "isabelle.girard@monentreprise.local" -Path "CN=Users,DC=monentreprise,DC=local" -AccountPassword (ConvertTo-SecureString "Passw0rd!" -AsPlainText -Force) -Enabled $true
- Les ajouter à des groupes
# Ajouter les utilisateurs au groupe Comptable
Add-ADGroupMember -Identity "Comptable" -Members "alice.dupont", "bernard.martin", "catherine.leroy"
# Ajouter les utilisateurs au groupe Direction
Add-ADGroupMember -Identity "Direction" -Members "david.morel", "emma.rousseau", "francois.lambert"
# Ajouter les utilisateurs au groupe Stagiaires
Add-ADGroupMember -Identity "Stagiaires" -Members "gabriel.fontaine", "hugo.bernard", "isabelle.girard"
Vous avez fait en 5 minutes ce qui prend 45 minutes à des SysAdmin qui connaissent pas bien le langage PowerShell.
Sécurité de signatures
PowerShell prend en charge un mécanisme de signature numérique pour garantir l'intégrité et l'authenticité des scripts exécutés. Cela permet d'empêcher l'exécution de scripts malveillants ou modifiés sans autorisation.
Vous avez 4 modes d'ExecutionPolicy que vous pouvez choisir dans Powershell : Restricted (Aucun Script autorisé), Unrestricted (Tout est autorisé), AllSigned (Tout les script doivent être signés), RemoteSigned (Les scripts distants doivent être signés).
Vous pouvez voir quel mode est défini sur votre système avec Get-ExecutionPolicy. Vous pouvez aussi la changer avec Set-ExecutionPolicy :
Set-ExecutionPolicy AllSigned (Tout doit être signé) -Scope CurrentUser (Utilisateur connecté (vous))
Vous pouvez ducoup logiquement signer vos scripts, soit les auto-signer (à éviter puisque c'est suspect pour un antivirus (mais pratique pour les tests locaux)) soit obtenir un certificat designature par une autorité.
New-SelfSignedCertificate -Type CodeSigningCert -Subject "CN=PowerShell Code Signing" -CertStoreLocation "Cert:\CurrentUser\My" -> Crée le certificat auto-signé dans le chemin spécifié.
Une fois le certificat créé vous pouvez signer un script.ps1 par exemple avec :
$cert = Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object { $_.Subject -like "*PowerShell Code Signing*" } -> Récupérer le Certificat précédemment créé
Set-AuthenticodeSignature -FilePath "C:\Path\To\script.ps1" -Certificate $cert
Puis vérifier la signature
Get-AuthenticodeSignature -FilePath "C:\Scripts\MonScript.ps1"
Vous pouvez aussi voir tous les certificats disponibles dans *Cert:* :
Get-ChildItem -Path Cert:\CurrentUser\My -CodeSigningCert -> Vous liste les certificats auto-signés dans \CurrentUser\My
Il y a parfois des problèmes dans des environnements ou l'ExecutionPolicy est restreinte, car Windows ne reconnaît pas toujours le certificat comme étant "de confiance" alors on peut l'ajouter au Magasin des Certificats
Import-Certificate -FilePath "C:\Path\To\Cert.cer" -CertStoreLocation "Cert:\CurrentUser\Root" -> (Nécessite des droits Admin naturellement)
Syntaxe
Cmdlets
Les commandes PowerShell (appelées cmdlet) utilisent une syntaxe de type Verbe-Nom :
Get-Alias -> Verbe : Get, Nom : Alias (Permet de lister les Alias du système)
Set-Alias -> Verbe : Set (Permet de Créer un nouvel Alias)
Chaque commande accèpte des paramètres positionnels ou nommés :
- Paramètre Positionnel :
Get-ChildItem "C:\"-> Va lister tous les éléments de la position (ou emplacement) C:\ . - Paramètre Nommé:
Get-ChildItem -Filter "*.ps1"-> Va lister tous fichiers ayant l'extension.ps1dans le répertoire courant. - Combinaison des deux :
Get-ChildItem "C:\" -Filter "*.ps1"-> Liste tous les fichiers.ps1dans le répertoire C:\ .
Variables
Les variables sont définies de cette manière $nom_de_la_variable elles sont utiles pour ré-utiliser une chose dont on aura besoin a plusieurs endroits.
# Créer une variable
$nom = "Alice"
# L'utiliser dans une commande
Write-Host "Bonjour, $nom"
Bonjour Alice
Write-Host "Aurevoir, $nom"
Aurevoir Alice
# Redéfinir une variable existante
$nom = $nom+" Au Pays Des Merveilles"
Write-Host "Re, $nom"
Re Alice Au Pays Des Merveilles
Ici on a utilisé du texte brut, mais comme mentionné précédemment, Powershell utilise des objets :
$superprocess = Get-Process -Name "notepad" -> Récupère le processus du programe Notepad++
$superprocess -> Vous renvoie l'output de la commande définie dans la variable
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
270 14 2936 1484 0,44 10812 1 notepad
Opérateurs
PowerShell inclut des opérateurs comme dans tout langages, par exemple en Python on a : == > < ! (et d'autres) bah dans PowerShell on a :
Opérateurs de comparaison :
-eq, -ne, -gt, -lt, -ge, -le, -like, -notlike, -match, -notmatch, -contains, -notcontains, -in, -notin, -is, -isnot
Opérateurs logiques :
-and, -or, -xor, -not
Opérateurs arithmétiques :
+, -, *, /, %, ++, --, -bnot, -band, -bor, -bxor
Opérateurs d'affectation :
=, +=, -=, *=, /=, %=
Opérateurs de type :
-as, -is, -isnot
Opérateurs de redirection :
, >>, <, 2>, 2>&1
Opérateurs de chaîne :
+, -join, -split, -replace, -match, -notmatch
Opérateurs de collection :
-contains, -in, -notin, -isnull, -isnotnull
Condition, Boucles
Comme dans tout langage de programmation, powershell inclut la possibilité d'écrire des boucles ou des conditions pour faire tout un tas de choses avec if, for, while, foreach, etc..., voici quelques exemples :
Condition
On veut faire un script qui dit si le monsieur est majeur ou nom selon son age
$age = Read-Host "Entrez votre age " -> Prompt pour entrer son age au lancement du programme
if ($age -gt 18) { -> Si l'âge entré est supérieur a 18 exécuter le code entre { } (opérateur -gt (greather than (plus grand que)))
Write-Host "Vous êtes majeur."
} else { -> Sinon exécuter le code ci-dessous.
Write-Host "Vous êtes mineur."
}
Boucle Foreach
$names = @("Alice", "Bob", "Charlie")
foreach ($name in $names) {
Write-Host "Bonjour, $name"
}
La boucle foreach (pour chaque) passe en revue chaque élément du tableau $names et exécute le code entre {} ici, la fonction écrit Bonjour, Nom pour chaque Nom contenu dans le tableau
Boucle While
$i = 0
while ($i -lt 5) {
Write-Host "i = $i"
$i++
}
La boucle conditionnelle while (tant que) vérifie une condition ($i est inférieur à 5) et exécute le code tant que cette condition n'est pas remplie. On incrémente la valeur de i a chaque exécution de la boucle au bout de 5 fois i arrivera a 5 et la boucle nesera plus exécutée
Fonctions
function Salut {
param ($nom)
Write-Host "Bonjour, $nom"
}
Salut "Alice"
On suit la même logique que pour tout le reste en définissant les paramètres au début de la fonction
Typer la Valeur de Retour
Pour faire des fonctions plus sécurisées et facile à lire lors de relecture de code on peut ajouter un type de retour string, int, etc... :
function Get-Name {
[string]$name = "Alice" -> Spécifie que la valeur de retour sera forcément une chaine de caractère
return $name
}
# Appel de la fonction
$result = Get-Name
Write-Host $result # "Alice"
Liste des Valeurs de Retours Possibles
[string], [int], [float], [double], [bool], [char], [decimal], [datetime], [array], [hashtable], [object], [pscustomobject], [void], [xml], [securestring], [system.net.ipaddress], [system.collections.generic.list[object]] (et autres types génériques), [enum]
ValidateSet
On peut aussi restreindre les possibilités de valeur d'un choix dans une fonction, pour être plus explicite par exemple quand vous allez faire ls | Where-Object -eq "azeaz" ça va vous générer une erreur vous disant que le paramètre n'est pas valide car la fonction Where-Object attend en paramètre une -Property et une -Value pour comparer avec le -eq. Voici un exemple simpliste:
function Set-Color {
param (
[ValidateSet("Red", "Green", "Blue")]
[string]$Color
)
Write-Host "You chose the color $Color"
}
Set-Color -Color "Red" # Fonctionne
Set-Color -Color "Yellow" # Erreur, car "Yellow" n'est pas dans le ValidateSet
Commentaires
# Commentaire sur une ligne
<#
c
o
m
m
e
n
t
a
i
r
e
#>
Conditions en Ligne de Commandes ( -eq Lambda )
PS C:\Users\Administrateur> if ("Hello" -eq "Hello") { Write-Host "Les chaînes sont égales" }
Les chaînes sont égales
PS C:\Users\Administrateur> if ("Heello" -eq "Zgeg") { Write-Host "Les chaînes sont égales" } else { echo "Inégales" }
Inégales
Utils (Pour Ceux du Métier)
Active Directory
Liens
- HelloMyDir est un programme écrit en powershell pour automatiser la création d'un Domaine AD avec "les bonnes pratiques".
- PowerShell AD Automation pour automatiser les tâches courantes dans Active Directory
- Autopopulation Active Directory pour créer des utilisateurs beaucoup plus rapidement
- Automatisation Administration AD avec une attention particulière à la gestion des erreurs, la validation des entrées et la journalisation pour assurer la fiabilité et la sécurité dans des environnements réels
- Awesome AD Scripts
- Hybrid AD Automation Account automatisation création utilisateurs avec personnalisation
Commandes
### Gestion Utilisateurs
Set-ADAccountPassword -Identity "alice.martin" -NewPassword (ConvertTo-SecureString "NewP@ssword456" -AsPlainText -Force) -Reset # Réinitialiser MDP Utilisateur
# Activer / Désactiver Compte Utilisateur
Disable-ADAccount -Identity "alice.martin"
Enable-ADAccount -Identity "alice.martin"
# Supprimer Compte Utilisateur
Remove-ADUser -Identity "alice.martin" -Confirm:$false
### Gestion Groupes
# Ajouter / Retire utilisateur d'un groupe
Add-ADGroupMember -Identity "Comptable" -Members "alice.martin"
Remove-ADGroupMember -Identity "Comptable" -Members "alice.martin" -Confirm:$false
# Lister les membres
Get-ADGroupMember -Identity "Comptable" | Select Name, SamAccountName
### Gestion des OU
# Ajouter / Supprimer une OU
New-ADOrganizationalUnit -Name "Stagiaires" -Path "DC=domaine,DC=com"
Remove-ADOrganizationalUnit -Identity "OU=Stagiaires,DC=domaine,DC=com" -Confirm:$false -Recursive
### Gestion des oridnateurs
Get-ADComputer -Filter * | Select Name,OperatingSystem # Lister
Add-ADGroupMember -Identity "GroupeDesPCs" -Members "PC-01" # ajouter a un groupe
Test-Connection -ComputerName "PC-01" # Vérifier l'activité sur le réseau d'un ordi
### Notions de base des """bonnes pratiques""" (ptn quelle phrase de connard)
Get-ADUser -Filter {Enabled -eq $false} | Select Name, SamAccountName # Vérifier régulièrement les comptes désactivés et inactifs :
Get-ADUser -Filter {LastLogonDate -lt (Get-Date).AddDays(-90)} | Select Name, LastLogonDate # Vérifier l'inactivité depuis 90 Jours
Créer un Profil PowerShell
Créer un profil PowerShell permet de sauvegarder vos configurations à la base éphemères de manière permanente c'est comme créer un profil mozilla firefox par exemple ou le .zshrc / .bashrc pour les Linuxiens.
# Vérifier si un profil existe déjà
Test-Path $PROFILE
# Créer un profil si False est retourné
New-Item -ItemType File -Path $PROFILE -Force
# Ouvrir le fichier de configuration du profil
notepad $PROFILE
code $PROFILE -> Si VSCode installé
# Ou n'importe quel autre éditeur
# Puis ajouter vos configurations
# une fois fait vous pouvez tapper
. $PROFILE
# pour charger le profil
Alias Linux -> Windows
Set-Alias ls Get-ChildItem
Set-Alias cat Get-Content
Set-Alias cp Copy-Item
Set-Alias mv Move-Item
Set-Alias rm Remove-Item
Set-Alias touch New-Item
Set-Alias pwd Get-Location
Set-Alias cd Set-Location
Set-Alias echo Write-Output
Set-Alias clear Clear-Host
Set-Alias ps Get-Process
Set-Alias kill Stop-Process
Set-Alias man Get-Help
Set-Alias grep Select-String
Set-Alias find Get-ChildItem
Set-Alias df Get-PSDrive
Set-Alias du Measure-Object
Set-Alias which Get-Command
Set-Alias hostname Hostname
Set-Alias whoami $env:USERNAME
Set-Alias env Get-ChildItem Env:
Set-Alias export Set-Item Env:
Set-Alias uname systeminfo
Set-Alias top Get-Process | Sort-Object -Property CPU -Descending
Set-Alias ifconfig Get-NetIPAddress
Set-Alias ip ipconfig
Set-Alias chmod Set-Acl
Set-Alias chown icacls
Set-Alias sudo Start-Process -Verb RunAs
Si vous ajoutez ces alias a votre profile ca vous génèrera surement une erreur AllScope blablabla donc y'a une solution alternative :
function ls { Get-ChildItem @args }
function cat { Get-Content @args }
function cp { Copy-Item @args }
function mv { Move-Item @args }
function rm { Remove-Item @args }
function pwd { Get-Location }
function cd { Set-Location @args }
function echo { Write-Output @args }
function clear { Clear-Host }
function ps { Get-Process @args }
function kill { Stop-Process @args }
function man { Get-Help @args }
function grep { Select-String @args }
function find { Get-ChildItem @args }
function df { Get-PSDrive @args }
function du { Measure-Object @args }
function which { Get-Command @args }
function hostname { [System.Net.Dns]::GetHostName() }
function whoami { $env:USERNAME }
function env { Get-ChildItem Env: }
function export { Set-Item Env:@args }
function uname { systeminfo }
function top { Get-Process | Sort-Object -Property CPU -Descending | Select-Object -First 10 }
function ifconfig { Get-NetIPAddress }
function ip { ipconfig }
function chmod { param($p) Set-Acl @args }
function chown { param($p) icacls @args }
function sudo { Start-Process -Verb RunAs @args }
Surveillance Dossier
Ce code met en place un FileSystemWatcher, qui permet de surveiller un dossier en temps réel pour détecter les changements (ajout, suppression, modification de fichiers).
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\Users\Public"
$watcher.EnableRaisingEvents = $true
On peut ensuite déclencher une action lorsqu’un fichier change, par exemple envoyer un email ou enregistrer une alerte.
# Détecter un fichier créé
$watcher.Created.Add({ Write-Host "Nouveau fichier détecté : $($_.FullPath)" })
# Détecter un fichier supprimé
$watcher.Deleted.Add({ Write-Host "Fichier supprimé : $($_.FullPath)" })
# Détecter un fichier modifié
$watcher.Changed.Add({ Write-Host "Fichier modifié : $($_.FullPath)" })
Mini Gestion Réseau
Lister les adresses IP
Get-NetIPAddress
# Tester une connexion réseau (alternative à ping)
Test-NetConnection google.com
# Lister les ports ouverts
Get-NetTCPConnection | Where-Object { $_.State -eq "Listen" }
# Vérifier les utilisateurs connectés
quser
# Lister les partages réseau actifs
Get-SmbShare
Logging et Audit
# Écrire un message dans un fichier log
"[INFO] Début du script à $(Get-Date)" | Out-File -FilePath C:\Logs\Script.log -Append
# Lister les événements du journal système Windows (erreurs uniquement)
Get-EventLog -LogName System -EntryType Error -Newest 10
# Surveiller en temps réel les logs d'un service spécifique
Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" -MaxEvents 10
Décompression et Compression de fichiers
# Compresser un dossier en .zip
Compress-Archive -Path C:\DossierSource -DestinationPath C:\Backup\Dossier.zip
# Décompresser un fichier ZIP
Expand-Archive -Path C:\Backup\Dossier.zip -DestinationPath C:\DossierDestination
Gestion des tâches planifiées
# Créer une tâche planifiée pour exécuter un script PowerShell chaque jour à 3h
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Scripts\Sauvegarde.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At 3am
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "Sauvegarde_Nuit"
# Configurer la tâche pour s'exécuter même si l'utilisateur n'est pas connecté
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount
Register-ScheduledTask -Action $action -Trigger $trigger -Settings $settings -Principal $principal -TaskName "Sauvegarde_Nuit"
# Ajouter plusieurs déclencheurs à une tâche
$trigger1 = New-ScheduledTaskTrigger -Daily -At 3am
$trigger2 = New-ScheduledTaskTrigger -AtStartup
Register-ScheduledTask -Action $action -Trigger $trigger1, $trigger2 -Settings $settings -TaskName "Sauvegarde_Nuit"
# Configurer une condition pour ne s'exécuter que si l'ordinateur est inactif
$conditions = New-ScheduledTaskSettingsSet -IdleDuration (New-TimeSpan -Minutes 15) -WaitForIdle (New-TimeSpan -Minutes 10)
Register-ScheduledTask -Action $action -Trigger $trigger -Settings $conditions -TaskName "Sauvegarde_Nuit"
# Lister toutes les tâches planifiées
Get-ScheduledTask | Select-Object TaskName, State
# Désactiver une tâche planifiée
Disable-ScheduledTask -TaskName "Sauvegarde_Nuit"
# Supprimer une tâche planifiée
Unregister-ScheduledTask -TaskName "Sauvegarde_Nuit" -Confirm:$false


