Gestion des Utilisateurs & Groupes
Ce script interactif propose un menu numéroté permettant de gérer les utilisateurs et groupes locaux (ou Active Directory). Chaque action inclut une gestion d'erreurs robuste.
PSScript PowerShell
New-LocalUser, Remove-LocalUser, New-LocalGroup, etc. disponibles sur Windows 10/Server 2016+. Exécuter en tant qu'administrateur.# ============================================================
# Script : Gestion des utilisateurs et groupes locaux
# Prérequis : Exécuter en tant qu'Administrateur
# ============================================================
function Show-Menu {
Clear-Host
Write-Host "===============================" -ForegroundColor Cyan
Write-Host " GESTION UTILISATEURS / GROUPES" -ForegroundColor Cyan
Write-Host "===============================" -ForegroundColor Cyan
Write-Host "1 - Créer un utilisateur"
Write-Host "2 - Supprimer un utilisateur"
Write-Host "3 - Créer un groupe"
Write-Host "4 - Supprimer un groupe"
Write-Host "5 - Ajouter un utilisateur à un groupe"
Write-Host "6 - Supprimer un utilisateur d'un groupe"
Write-Host "7 - Modifier le profil d'un utilisateur"
Write-Host "Q - Quitter"
Write-Host "===============================" -ForegroundColor Cyan
}
# ── Choix 1 : Créer un utilisateur ──────────────────────────
function Create-User {
$login = Read-Host "Login de l'utilisateur"
if (Get-LocalUser -Name $login -ErrorAction SilentlyContinue) {
Write-Host "[ERREUR] L'utilisateur '$login' existe déjà." -ForegroundColor Red
return
}
$pswd = Read-Host "Mot de passe" -AsSecureString
$change = Read-Host "Forcer le changement au prochain login ? (oui/non)"
try {
$params = @{
Name = $login
Password = $pswd
AccountNeverExpires = $true
PasswordNeverExpires = $false
UserMayNotChangePassword = $false
}
New-LocalUser @params | Out-Null
if ($change -eq "oui") {
# Forcer le changement de mot de passe
Set-LocalUser -Name $login -PasswordExpired $true
}
Write-Host "[OK] Utilisateur '$login' créé avec succès." -ForegroundColor Green
}
catch {
Write-Host "[ERREUR] $($_.Exception.Message)" -ForegroundColor Red
}
}
# ── Choix 2 : Supprimer un utilisateur ──────────────────────
function Delete-User {
$login = Read-Host "Login à supprimer"
if (-not (Get-LocalUser -Name $login -ErrorAction SilentlyContinue)) {
Write-Host "[ERREUR] Utilisateur introuvable." -ForegroundColor Red; return
}
try {
Remove-LocalUser -Name $login
Write-Host "[OK] Utilisateur '$login' supprimé." -ForegroundColor Green
}
catch { Write-Host "[ERREUR] $($_.Exception.Message)" -ForegroundColor Red }
}
# ── Choix 3 : Créer un groupe ────────────────────────────────
function Create-Group {
$grp = Read-Host "Nom du groupe"
$desc = Read-Host "Description (facultatif)"
if (Get-LocalGroup -Name $grp -ErrorAction SilentlyContinue) {
Write-Host "[ERREUR] Groupe '$grp' déjà existant." -ForegroundColor Red; return
}
try {
New-LocalGroup -Name $grp -Description $desc | Out-Null
Write-Host "[OK] Groupe '$grp' créé." -ForegroundColor Green
}
catch { Write-Host "[ERREUR] $($_.Exception.Message)" -ForegroundColor Red }
}
# ── Choix 4 : Supprimer un groupe ───────────────────────────
function Delete-Group {
$grp = Read-Host "Nom du groupe à supprimer"
if (-not (Get-LocalGroup -Name $grp -ErrorAction SilentlyContinue)) {
Write-Host "[ERREUR] Groupe introuvable." -ForegroundColor Red; return
}
try {
Remove-LocalGroup -Name $grp
Write-Host "[OK] Groupe '$grp' supprimé." -ForegroundColor Green
}
catch { Write-Host "[ERREUR] $($_.Exception.Message)" -ForegroundColor Red }
}
# ── Choix 5 : Ajouter un utilisateur à un groupe ────────────
function Add-UserToGroup {
$login = Read-Host "Login utilisateur"
$grp = Read-Host "Nom du groupe"
if (-not (Get-LocalUser -Name $login -EA SilentlyContinue)) {
Write-Host "[ERREUR] Utilisateur '$login' introuvable." -ForegroundColor Red; return
}
if (-not (Get-LocalGroup -Name $grp -EA SilentlyContinue)) {
Write-Host "[ERREUR] Groupe '$grp' introuvable." -ForegroundColor Red; return
}
try {
Add-LocalGroupMember -Group $grp -Member $login
Write-Host "[OK] '$login' ajouté au groupe '$grp'." -ForegroundColor Green
}
catch { Write-Host "[ERREUR] $($_.Exception.Message)" -ForegroundColor Red }
}
# ── Choix 6 : Retirer d'un groupe ───────────────────────────
function Remove-UserFromGroup {
$login = Read-Host "Login utilisateur"
$grp = Read-Host "Nom du groupe"
try {
Remove-LocalGroupMember -Group $grp -Member $login
Write-Host "[OK] '$login' retiré du groupe '$grp'." -ForegroundColor Green
}
catch { Write-Host "[ERREUR] $($_.Exception.Message)" -ForegroundColor Red }
}
# ── Choix 7 : Modifier le profil ────────────────────────────
function Edit-UserProfile {
$login = Read-Host "Login utilisateur"
if (-not (Get-LocalUser -Name $login -EA SilentlyContinue)) {
Write-Host "[ERREUR] Utilisateur introuvable." -ForegroundColor Red; return
}
$fullName = Read-Host "Nouveau nom complet (Entrée pour ignorer)"
$desc = Read-Host "Nouvelle description (Entrée pour ignorer)"
try {
$p = @{ Name = $login }
if ($fullName) { $p.FullName = $fullName }
if ($desc) { $p.Description = $desc }
Set-LocalUser @p
Write-Host "[OK] Profil mis à jour." -ForegroundColor Green
}
catch { Write-Host "[ERREUR] $($_.Exception.Message)" -ForegroundColor Red }
}
# ── Boucle principale ────────────────────────────────────────
do {
Show-Menu
$choice = Read-Host "Votre choix"
switch ($choice) {
"1" { Create-User }
"2" { Delete-User }
"3" { Create-Group }
"4" { Delete-Group }
"5" { Add-UserToGroup }
"6" { Remove-UserFromGroup }
"7" { Edit-UserProfile }
"Q" { Write-Host "Au revoir." }
default { Write-Host "[ERREUR] Choix invalide." -ForegroundColor Yellow }
}
if ($choice -ne "Q") { Read-Host "`nAppuyez sur Entrée pour continuer" }
} while ($choice -ne "Q")
⚠Points clés de la gestion d'erreurs
try/catch. Les vérifications d'existence (Get-LocalUser, Get-LocalGroup) se font avant toute action pour éviter les exceptions non contrôlées.| Scénario | Type d'erreur | Traitement |
|---|---|---|
| Utilisateur déjà existant | Logique | Vérification préalable + message rouge |
| Utilisateur introuvable | Logique | Vérification préalable + retour |
| Droits insuffisants | Système | Exception catch → message d'erreur |
| Mot de passe non conforme | Politique | Exception catch → détail retourné |
| Choix de menu invalide | Saisie | Bloc default → message jaune |
Gestion des Partages Réseau
Ce second script gère les partages SMB Windows : création, suppression, modification des droits et consultation des partages existants.
PSScript PowerShell
# ============================================================
# Script : Gestion des partages réseau (SMB)
# Prérequis : Module SmbShare + droits admin
# ============================================================
function Show-ShareMenu {
Clear-Host
Write-Host "===============================" -ForegroundColor Cyan
Write-Host " GESTION DES PARTAGES SMB " -ForegroundColor Cyan
Write-Host "===============================" -ForegroundColor Cyan
Write-Host "1 - Partager un dossier"
Write-Host "2 - Supprimer un partage"
Write-Host "3 - Modifier les droits d'un partage"
Write-Host "4 - Voir les partages existants"
Write-Host "Q - Quitter"
Write-Host "===============================" -ForegroundColor Cyan
}
# ── Choix 1 : Créer un partage ───────────────────────────────
function New-Share {
$shareName = Read-Host "Nom du partage"
$path = Read-Host "Chemin complet du dossier (ex: C:\Data\Commun)"
$group = Read-Host "Groupe autorisé (ex: Comptabilite)"
Write-Host "Droits : [1] Lecture [2] Modification [3] Contrôle total"
$right = Read-Host "Votre choix"
# Vérifier que le chemin existe
if (-not (Test-Path $path)) {
Write-Host "[ERREUR] Le chemin '$path' n'existe pas." -ForegroundColor Red
return
}
# Vérifier que le partage n'existe pas déjà
if (Get-SmbShare -Name $shareName -ErrorAction SilentlyContinue) {
Write-Host "[ERREUR] Un partage '$shareName' existe déjà." -ForegroundColor Red
return
}
$access = switch ($right) {
"1" { "Read" }
"2" { "Change" }
"3" { "Full" }
default { Write-Host "[ERREUR] Droit invalide." -ForegroundColor Yellow; return }
}
try {
New-SmbShare -Name $shareName -Path $path -FullAccess "Administrateurs" | Out-Null
Grant-SmbShareAccess -Name $shareName -AccountName $group -AccessRight $access -Force | Out-Null
Revoke-SmbShareAccess -Name $shareName -AccountName "Tout le monde" -Force -EA SilentlyContinue
Write-Host "[OK] Partage '$shareName' créé → $path ($access pour $group)" -ForegroundColor Green
}
catch { Write-Host "[ERREUR] $($_.Exception.Message)" -ForegroundColor Red }
}
# ── Choix 2 : Supprimer un partage ──────────────────────────
function Remove-Share {
$name = Read-Host "Nom du partage à supprimer"
if (-not (Get-SmbShare -Name $name -EA SilentlyContinue)) {
Write-Host "[ERREUR] Partage '$name' introuvable." -ForegroundColor Red; return
}
try {
Remove-SmbShare -Name $name -Force
Write-Host "[OK] Partage '$name' supprimé." -ForegroundColor Green
}
catch { Write-Host "[ERREUR] $($_.Exception.Message)" -ForegroundColor Red }
}
# ── Choix 3 : Modifier les droits ───────────────────────────
function Edit-ShareRights {
$name = Read-Host "Nom du partage"
$group = Read-Host "Groupe à modifier"
Write-Host "Nouveaux droits : [1] Lecture [2] Modification [3] Contrôle total"
$right = Read-Host "Votre choix"
$access = switch ($right) {
"1" { "Read" } "2" { "Change" } "3" { "Full" }
default { Write-Host "[ERREUR] Droit invalide." -ForegroundColor Yellow; return }
}
try {
Grant-SmbShareAccess -Name $name -AccountName $group -AccessRight $access -Force | Out-Null
Write-Host "[OK] Droits mis à jour : $access pour $group sur '$name'." -ForegroundColor Green
}
catch { Write-Host "[ERREUR] $($_.Exception.Message)" -ForegroundColor Red }
}
# ── Choix 4 : Lister les partages ───────────────────────────
function List-Shares {
$shares = Get-SmbShare | Where-Object { $_.Name -notlike "*$" }
if ($shares.Count -eq 0) {
Write-Host "Aucun partage non-administratif trouvé." -ForegroundColor Yellow
return
}
Write-Host "`n--- PARTAGES ACTIFS ---" -ForegroundColor Cyan
$shares | Format-Table Name, Path, Description -AutoSize
}
# ── Boucle principale ────────────────────────────────────────
do {
Show-ShareMenu
$choice = Read-Host "Votre choix"
switch ($choice) {
"1" { New-Share }
"2" { Remove-Share }
"3" { Edit-ShareRights}
"4" { List-Shares }
"Q" { Write-Host "Au revoir." }
default { Write-Host "[ERREUR] Choix invalide." -ForegroundColor Yellow }
}
if ($choice -ne "Q") { Read-Host "`nAppuyez sur Entrée pour continuer" }
} while ($choice -ne "Q")
Script de Sauvegarde Automatisée
Stratégie de sauvegarde en trois niveaux : Totale le 31 décembre, Différentielle en fin de mois, Incrémentielle chaque jour. Les données sources proviennent de C:\Users\<login>\Documents vers un disque externe D:\.
📋Types de sauvegardes
| Type | Fréquence | Contenu copié | Espace disque |
|---|---|---|---|
| Totale | 31 décembre | Tous les fichiers | Maximum |
| Différentielle | Fin de chaque mois | Modifiés depuis la dernière totale | Moyen |
| Incrémentielle | Chaque jour | Modifiés depuis la dernière incrémentielle | Minimum |
PSScript de sauvegarde
# ============================================================
# Script : Sauvegarde automatisée des Documents utilisateur
# Source : C:\Users\\Documents
# Dest. : D:\Sauvegardes\
# Stratégie : Totale (31/12) | Différentielle (fin mois) | Incrémentielle (quotidien)
# ============================================================
$User = $env:USERNAME
$Source = "C:\Users\$User\Documents"
$DestBase = "D:\Sauvegardes"
$LogFile = "D:\Sauvegardes\sauvegarde.log"
$Today = Get-Date
$DateStr = $Today.ToString("yyyy-MM-dd")
$Day = $Today.Day
$Month = $Today.Month
$DaysInMonth= [DateTime]::DaysInMonth($Today.Year, $Month)
# Créer les dossiers de destination si nécessaires
foreach ($dir in "Totale","Differentielle","Incrementielle") {
$p = Join-Path $DestBase $dir
if (-not (Test-Path $p)) { New-Item -ItemType Directory -Path $p | Out-Null }
}
function Write-Log($msg) {
$line = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $msg"
Add-Content -Path $LogFile -Value $line
Write-Host $line
}
# ── Sauvegarde TOTALE (31 décembre uniquement) ───────────────
if ($Day -eq 31 -and $Month -eq 12) {
$dest = Join-Path $DestBase "Totale\TOTALE_$DateStr"
Write-Log "=== SAUVEGARDE TOTALE → $dest"
try {
robocopy $Source $dest /E /COPYALL /R:3 /W:5 /LOG+:$LogFile /NP
# Enregistrer la date de la dernière totale
Set-Content "$DestBase\last_total.txt" $DateStr
Write-Log "Sauvegarde totale terminée."
}
catch { Write-Log "ERREUR totale : $($_.Exception.Message)" }
}
# ── Sauvegarde DIFFÉRENTIELLE (dernier jour du mois) ─────────
elseif ($Day -eq $DaysInMonth) {
$dest = Join-Path $DestBase "Differentielle\DIFF_$DateStr"
$lastTotal = Get-Content "$DestBase\last_total.txt" -EA SilentlyContinue
Write-Log "=== SAUVEGARDE DIFFÉRENTIELLE → $dest (depuis totale du $lastTotal)"
if (-not $lastTotal) {
Write-Log "[ERREUR] Aucune sauvegarde totale de référence."; exit
}
$refDate = [datetime]::ParseExact($lastTotal, "yyyy-MM-dd", $null)
try {
Get-ChildItem -Path $Source -Recurse |
Where-Object { -not $_.PSIsContainer -and $_.LastWriteTime -gt $refDate } |
ForEach-Object {
$rel = $_.FullName.Substring($Source.Length)
$target = Join-Path $dest $rel
$dir = Split-Path $target
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir | Out-Null }
Copy-Item $_.FullName -Destination $target -Force
}
Set-Content "$DestBase\last_diff.txt" $DateStr
Write-Log "Sauvegarde différentielle terminée."
}
catch { Write-Log "ERREUR diff : $($_.Exception.Message)" }
}
# ── Sauvegarde INCRÉMENTIELLE (tous les autres jours) ────────
else {
$dest = Join-Path $DestBase "Incrementielle\INCR_$DateStr"
$lastRef = if (Test-Path "$DestBase\last_incr.txt") {
Get-Content "$DestBase\last_incr.txt"
} else {
Get-Content "$DestBase\last_total.txt" -EA SilentlyContinue
}
Write-Log "=== SAUVEGARDE INCRÉMENTIELLE → $dest (depuis $lastRef)"
if (-not $lastRef) { Write-Log "[ERREUR] Pas de référence trouvée."; exit }
$refDate = [datetime]::ParseExact($lastRef, "yyyy-MM-dd", $null)
try {
Get-ChildItem -Path $Source -Recurse |
Where-Object { -not $_.PSIsContainer -and $_.LastWriteTime -gt $refDate } |
ForEach-Object {
$rel = $_.FullName.Substring($Source.Length)
$target = Join-Path $dest $rel
$dir = Split-Path $target
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir | Out-Null }
Copy-Item $_.FullName -Destination $target -Force
}
Set-Content "$DestBase\last_incr.txt" $DateStr
Write-Log "Sauvegarde incrémentielle terminée."
}
catch { Write-Log "ERREUR incr : $($_.Exception.Message)" }
}
⏰Planification via Task Scheduler
Rechercher « Planificateur de tâches » dans le menu Démarrer
Action → Créer une tâche de base → Nommer « Sauvegarde Auto »
Choisir « Quotidien » à 23h00
Démarrer un programme : powershell.exe — Arguments : -ExecutionPolicy Bypass -File "C:\Scripts\sauvegarde.ps1"
Cocher « Exécuter avec les autorisations maximales » et « Exécuter même si l'utilisateur n'est pas connecté »
Compte Utilisateur « secrétaire »
Configuration d'un compte restreint avec politique de sécurité renforcée, restrictions GPO et contrôle d'accès aux périphériques.
PSCréation du compte
# ============================================================
# Créer le compte "secretaire" avec politique de sécurité
# ============================================================
$username = "secretaire"
$password = ConvertTo-SecureString "Inraci#2021" -AsPlainText -Force
# Vérifier si l'utilisateur existe déjà
if (Get-LocalUser -Name $username -ErrorAction SilentlyContinue) {
Write-Host "[INFO] L'utilisateur '$username' existe déjà." -ForegroundColor Yellow
} else {
New-LocalUser `
-Name $username `
-Password $password `
-FullName "Secrétaire" `
-Description "Compte secrétariat restreint" `
-PasswordNeverExpires $false `
-AccountNeverExpires $true `
-UserMayNotChangePassword $true | Out-Null
Write-Host "[OK] Compte '$username' créé." -ForegroundColor Green
}
# Activer la complexité des mots de passe (politique locale)
# Note : géré via GPO pour le domaine, ou secedit localement
$cfgFile = "C:\Temp\secpol.cfg"
secedit /export /cfg $cfgFile /quiet
(Get-Content $cfgFile) -replace 'PasswordComplexity = 0', 'PasswordComplexity = 1' |
Set-Content $cfgFile
secedit /configure /db secedit.sdb /cfg $cfgFile /quiet
# Politique de verrouillage : 3 essais → verrouillage 60 min
# Remise à zéro après 15 min
net accounts /lockoutthreshold:3 /lockoutduration:60 /lockoutwindow:15
Write-Host "[OK] Politique de verrouillage configurée." -ForegroundColor Green
# Ajouter dans le groupe "Utilisateurs" uniquement (pas Administrateurs)
Add-LocalGroupMember -Group "Utilisateurs" -Member $username -ErrorAction SilentlyContinue
Write-Host "[OK] Configuration du compte terminée." -ForegroundColor Green
-UserMayNotChangePassword $true empêche l'utilisateur de modifier son mot de passe. La commande net accounts configure le verrouillage au niveau système.🔒Restrictions via GPO / Registre
Les restrictions suivantes s'appliquent au compte secrétaire via des stratégies de groupe (GPO) ou directement dans le registre.
# ============================================================
# Restrictions spécifiques pour le compte "secretaire"
# À exécuter dans le contexte de l'utilisateur OU via GPO
# ============================================================
# Chemin de base pour les restrictions utilisateur
$PolicyPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies"
$SysPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies"
# ── 1. Bloquer le Panneau de Configuration ─────────────────
$expPath = "$PolicyPath\Explorer"
if (-not (Test-Path $expPath)) { New-Item -Path $expPath -Force | Out-Null }
Set-ItemProperty -Path $expPath -Name "NoControlPanel" -Value 1 -Type DWord
Set-ItemProperty -Path $expPath -Name "NoSetFolders" -Value 1 -Type DWord
# ── 2. Bloquer l'Invite de commande (CMD) ──────────────────
$sysPath = "$PolicyPath\System"
if (-not (Test-Path $sysPath)) { New-Item -Path $sysPath -Force | Out-Null }
Set-ItemProperty -Path $sysPath -Name "DisableCMD" -Value 1 -Type DWord
# ── 3. Interdire l'arrêt / redémarrage de l'ordinateur ──────
Set-ItemProperty -Path $expPath -Name "NoClose" -Value 1 -Type DWord
# ── 4. Bloquer le verrouillage de la session ───────────────
Set-ItemProperty -Path $expPath -Name "DisableLockWorkstation" -Value 1 -Type DWord
# ── 5. Interdire l'installation de logiciels ───────────────
$instPath = "$SysPath\Installer"
if (-not (Test-Path $instPath)) { New-Item -Path $instPath -Force | Out-Null }
Set-ItemProperty -Path $instPath -Name "DisableMSI" -Value 2 -Type DWord
# ── 6. Bloquer Internet Explorer ───────────────────────────
$iePath = "$PolicyPath\Explorer\RestrictRun"
if (-not (Test-Path $iePath)) { New-Item -Path $iePath -Force | Out-Null }
Set-ItemProperty -Path ("$PolicyPath\Explorer") -Name "RestrictRun" -Value 1 -Type DWord
# ── 7. Interdire les médias amovibles (USB, DVD, etc.) ──────
$rmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\RemovableStorageDevices"
if (-not (Test-Path $rmPath)) { New-Item -Path $rmPath -Force | Out-Null }
# Bloquer toutes les classes de stockage amovible
foreach ($class in "RemovableDisk", "CDRom", "Tape", "FloppyDisk") {
$cp = Join-Path $rmPath $class
if (-not (Test-Path $cp)) { New-Item -Path $cp -Force | Out-Null }
Set-ItemProperty -Path $cp -Name "Deny_Read" -Value 1 -Type DWord
Set-ItemProperty -Path $cp -Name "Deny_Write" -Value 1 -Type DWord
Set-ItemProperty -Path $cp -Name "Deny_Execute" -Value 1 -Type DWord
}
Write-Host "[OK] Toutes les restrictions ont été appliquées." -ForegroundColor Green
Write-Host "[INFO] Appliquer via 'gpupdate /force' ou redémarrer la session." -ForegroundColor Cyan
📋Récapitulatif des restrictions
| Restriction | Méthode | Clé registre / GPO |
|---|---|---|
| Panneau de configuration | Registre | NoControlPanel = 1 |
| Invite de commande (CMD) | Registre | DisableCMD = 1 |
| Arrêt de l'ordinateur | Registre | NoClose = 1 |
| Verrouillage de session | Registre | DisableLockWorkstation = 1 |
| Installation de logiciels | Registre | DisableMSI = 2 |
| Internet Explorer | Registre | RestrictRun = 1 |
| Effacement historique navigateur | GPO | Config. utilisateur → Composants IE → Bloquer la suppression de l'historique |
| Interruption de script | GPO | Config. utilisateur → Système → Désactiver Ctrl+Alt+Suppr |
| Médias amovibles (USB, CD, DVD) | Registre | RemovableStorageDevices\*\Deny_Read/Write = 1 |
| Mot de passe non modifiable | Compte | UserMayNotChangePassword = $true |
| Verrouillage après 3 essais | Politique | net accounts /lockoutthreshold:3 /lockoutduration:60 |
| Réinitialisation compteur après 15 min | Politique | net accounts /lockoutwindow:15 |
gpmc.msc ou gpedit.msc.