[PowerShell] Gestion de la mise en veille des HUB USB (Suspension sélective)

Vous trouverez ici des scripts pour faciliter la gestion de votre ordinateur. Ils sont proposés tels quels par le rédacteur du message. La team ne vérifie pas la qualité de ces éléments et n'assure pas le support ni la maintenance. Vous les utilisez sous votre seule responsabilité.
Règles du forum
Pour les créateurs de scripts

Veuillez noter que les scripts que vous partagez ici sont proposés tels quels et la team ne vérifie pas leur qualité.
Nous vous rappelons que nous n'assurons ni le support ni la maintenance des scripts publiés.

Pour faciliter leur utilisation par les autres membres de la communauté, respectez ces consignes :
.
  • Utilisez les préfixes de langage pour taguer les messages.
  • Assurez-vous que vos scripts sont clairs et bien documentés
.
Merci de votre compréhension et de votre contribution.
Répondre
Avatar du membre
pboulanger
Administrateur du site
Administrateur du site
Messages : 1175
Enregistré le : mar. 17 mars 2020 11:49
A remercié : 155 fois
A été remercié : 196 fois
    Windows 10 Firefox

[PowerShell] Gestion de la mise en veille des HUB USB (Suspension sélective)

Message par pboulanger »

Gestion de la mise en veille des HUB USB (Suspension sélective)

Bonjour à toutes et à tous,

Je vous partage un script PowerShell permettant de désactiver ou réactiver la mise en veille (suspension sélective) des concentrateurs USB sous Windows 10 et 11.

Présentation de l'outil

Ce script est conçu pour résoudre un problème fréquent : les disques durs externes USB qui s’arrêtent ou se mettent en veille trop rapidement, même lorsque la machine est active.
Ce comportement est souvent dû aux paramètres de gestion d’alimentation appliqués aux HUB USB.

Ce que fait ce script

Ce script permet la :
  • Désactivation de la mise en veille (recommandé pour disques externes / matériel sensible)
  • Réactivation du comportement par défaut de Windows
via une interface de type menu simple (1 / 2 / 0)

et un suivi de l’exécution via
  • Un log en UTF-16 LE
  • Une vérification du mode Administrateur
  • Un nettoyage automatique du log à chaque lancement
 ! Message de : pboulanger
⚠ Le script doit être lancé en mode Administrateur.
En cas d’oubli, une alerte claire apparaît + consignée dans le log + pause avant sortie.
📌 Fonctionnement

Le script propose 3 options :

1 – Désactiver la mise en veille des HUB USB
2 – Activer la mise en veille (mode Windows par défaut)
0 – Quitter (consigné dans le log)

Seuls les Concentrateurs USB / USB Root Hub / USB SuperSpeed Hub sont traités.
Aucun périphérique USB (souris, clavier, audio…) n’est modifié.

📄 Journal (Log)

Un fichier USB_HUB_PowerSave_Log.txt est généré automatiquement dans le dossier du script.
L’encodage utilisé est UTF-16 LE
→ 100% compatible Bloc-notes / Notepad++ / VSCode / outils AAZ.

À chaque lancement, l’ancien log est automatiquement supprimé pour repartir proprement.

📦 Le code complet commenté
 ! Message de : pboulanger
⚠ Important : ce script doit être enregistré en UTF-16 LE (Little Endian) pour éviter les problèmes d’affichage des accents.

Code : Tout sélectionner

# =====================================================================
# USB-Hubs-PowerSave-Manager.ps1
# Version 1.0 du 15 novembre 2025
# © PiB pour Team-AAZ
# =====================================================================

# =====================================================================
# Gestion de la mise en veille (suspension sélective) des HUB USB.
# Menu :
#   1 - Désactiver la mise en veille (souvent utile pour éviter l'arrêt des disques externes)
#   2 - Activer la mise en veille (comportement normal Windows)
#   0 - Quitter
#
# Log UTF-16 LE dans le dossier du script.
# Vérification du mode Administrateur au lancement avec pause utilisateur.
# =====================================================================


# =====================================================================
# Vérification du mode Administrateur
# =====================================================================

# Pré-déclaration du chemin du futur log (nécessaire même si pas admin)
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
$logFile = Join-Path $scriptDir "USB_HUB_PowerSave_Log.txt"

# Fonction minimale d’écriture dans le log pour le cas "non admin"
function Write-LogEarly {
    param([string]$message)
    $timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
    $line = "$timestamp - $message"

    [System.IO.File]::AppendAllText(
        $logFile,
        $line + [Environment]::NewLine,
        [System.Text.Encoding]::Unicode
    )
}

# Test des droits Administrateur
$principal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {

    $msg = "ERREUR : Ce script doit être lancé en mode Administrateur."

    Write-Host $msg -ForegroundColor Red
    Write-Host "Veuillez relancer PowerShell en Administrateur pour continuer." -ForegroundColor Yellow

    # Log de l’erreur
    Write-LogEarly $msg
    Write-LogEarly "Arrêt du script : droits administrateur absents."

    # Pause utilisateur (sinon la fenêtre se ferme trop vite)
    Write-Host "`nAppuyez sur Entrée pour fermer..."
    Read-Host

    exit
}


# =====================================================================
# Initialisation du log principal
# =====================================================================

# Suppression d’un ancien log pour repartir proprement
if (Test-Path $logFile) {
    Remove-Item $logFile -Force
}

# Fonction d’écriture UTF-16 LE dans le log (compatible 100% Windows)
function Write-Log {
    param([string]$message)
    $timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
    $line = "$timestamp - $message"

    [System.IO.File]::AppendAllText(
        $logFile,
        $line + [Environment]::NewLine,
        [System.Text.Encoding]::Unicode
    )
}


# =====================================================================
# Fonction de détection des HUB USB uniquement
# =====================================================================
function Get-USBHubs {
    return Get-PnpDevice -Class "USB" | Where-Object {
        $_.FriendlyName -match "Concentrateur" -or
        $_.FriendlyName -match "Hub USB" -or
        $_.FriendlyName -match "Root Hub" -or
        $_.FriendlyName -match "USB Root"
    }
}


# =====================================================================
# Désactivation de la suspension sélective USB
# =====================================================================
function Disable-PowerSave {
    Write-Host "`nDésactivation de la mise en veille USB..." -ForegroundColor Cyan
    Write-Log "=== DÉBUT : Désactivation ==="

    $usbHubs = Get-USBHubs

    foreach ($hub in $usbHubs) {
        Write-Host "Traitement : $($hub.FriendlyName)" -ForegroundColor Yellow
        Write-Log "Traitement : $($hub.FriendlyName)"

        $instanceId = $hub.InstanceId
        $regPath = "HKLM:\SYSTEM\CurrentControlSet\Enum\$instanceId\Device Parameters"

        if (-not (Test-Path $regPath)) {
            New-Item -Path $regPath -Force | Out-Null
            Write-Log "  Clé créée : $regPath"
        }

        New-ItemProperty -Path $regPath -Name "DeviceSelectiveSuspended" -Value 0 -PropertyType DWord -Force | Out-Null
        Write-Log "  DeviceSelectiveSuspended = 0 (désactivé)"

        Write-Host " → Désactivé" -ForegroundColor Green
    }

    Write-Log "=== FIN : Désactivation ==="
    Write-Host "`nOpération terminée !`n" -ForegroundColor Cyan
}


# =====================================================================
# Réactivation de la suspension sélective USB
# =====================================================================
function Enable-PowerSave {
    Write-Host "`nRéactivation de la mise en veille USB..." -ForegroundColor Cyan
    Write-Log "=== DÉBUT : Réactivation ==="

    $usbHubs = Get-USBHubs

    foreach ($hub in $usbHubs) {
        Write-Host "Traitement : $($hub.FriendlyName)" -ForegroundColor Yellow
        Write-Log "Traitement : $($hub.FriendlyName)"

        $instanceId = $hub.InstanceId
        $regPath = "HKLM:\SYSTEM\CurrentControlSet\Enum\$instanceId\Device Parameters"

        if (-not (Test-Path $regPath)) {
            New-Item -Path $regPath -Force | Out-Null
            Write-Log "  Clé créée : $regPath"
        }

        New-ItemProperty -Path $regPath -Name "DeviceSelectiveSuspended" -Value 1 -PropertyType DWord -Force | Out-Null
        Write-Log "  DeviceSelectiveSuspended = 1 (activé)"

        Write-Host " → Activé" -ForegroundColor Green
    }

    Write-Log "=== FIN : Réactivation ==="
    Write-Host "`nOpération terminée !`n" -ForegroundColor Cyan
}


# =====================================================================
# MENU INTERACTIF
# =====================================================================
do {
    Write-Host "============================="
    Write-Host " Gestion de la mise en veille USB (HUBS uniquement)"
    Write-Host "============================="
    Write-Host "1 - Désactiver la mise en veille (recommandé pour disques externes)"
    Write-Host "2 - Activer la mise en veille (paramètre Windows par défaut)"
    Write-Host "0 - Quitter"
    Write-Host "-----------------------------"
    
    $choice = Read-Host "Votre choix"

    switch ($choice) {
        "1" { Disable-PowerSave }
        "2" { Enable-PowerSave }

        "0" { 
            Write-Log "L’utilisateur a quitté le script (option 0)"
            Write-Host "Fermeture du script..." -ForegroundColor Cyan 
        }

        default { 
            Write-Host "Choix invalide, merci de réessayer." -ForegroundColor Red 
        }
    }
}
while ($choice -ne "0")


# =====================================================================
# Fin de script
# =====================================================================
Write-Host "`nUn fichier log a été généré :" -ForegroundColor Cyan
Write-Host "$logFile"


💡 Remarques
  • Compatibilité Windows 10 / 11 => OK
  • Versions PowerShell ≥ 5.1 (jusqu’à 7.5.4) => OK
  • Ne modifie que les HUB USB, pas les périphériques
  • Peut être intégré facilement dans un outil plus large (diagnostic Windows, toolbox, etc.)
  • Convient à une utilisation portable (clé USB, network share)
📝 Conclusion

Ce script vise à simplifier la gestion d’un problème matériel très courant :
les coupures intempestives des disques externes USB dues à la suspension sélective.

N’hésitez pas à proposer des améliorations, une intégration dans un pack, ou une version automatisée.

Bon dépannage à tous ! 😉
Amicalement,

Pierre
Répondre