Question [WMI]Comment détecter l'insertion d'un disque USB?
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 68
il y a 16 ans 9 mois - il y a 2 ans 9 mois #4844
par Laurent Dardenne
Tutoriels PowerShell
Voici un code qui attend l'insertion d'un disque USB ou autre.
On crée une requête WQL d'événement, la classe Win32_PnPEntity concerne tous les éléments Plug and Play.
On indique un ensemble d'événement à l'aide de la classe d'événement "__InstanceOperationEvent" qui concerne la création,la modification et la suppression.Identique à :
SELECT * FROM __InstanceOperationEvent WITHIN 1
WHERE Targetinstance ISA 'Win32_PnPEntity
On crée un abonnement à des notifications d'événement temporaires :Puisque l'on attend un ensemble d'événement (création, modification et suppression), on détermine le type de l'événement reçu à l'aide de sa propriété __CLASS :Une fois cette mécanique mis en place on peut affiner la recherche, on peut vouloir filtrer plus précisément les événements :Puis préciser le type d'élément PnPSelon le contexte on peut vouloir disposer pour un même opération d'informations différentes, dans ce cas on change la classe ciblée.
Par exemple surveiller les disques, plutôt qu'un élément PnP :Ou seulement les disques USB :Si on recheche les lecteurs, on accéde directement au nom d'unité.
Les lecteurs réseaux créés par la commande Net Use sont aussi concernés :Si on scrute les événements concernant la classe Win32_DiskDrive, on doit parcourir les associations pour récupérer la lettre de lecteur qui lui a été attribué, ou s'il contient plusieurs partitions les noms de lecteur ajoutés au système.
Une classe dassociation définit les relations entre deux classes.
Un disque posséde une ou plusieurs partitions et à chaque partition est attribué un nom de lecteur, on doit donc interroger les objet suivants :
Win32_DiskDrive->Win32_DiskPartition->Win32_LogicalDisk
Le principe de recherche dans les associations reste identique pour d'autres classes; Pour la classe Win32_PnPEntity je n'ai pas réussi à remonter jusqu'au disque...
Enfin la propriété Win32_PnPEntity.DeviceId peut servir à déterminer le type de device .<br><br>Message édité par: Laurent Dardenne, à: 18/06/09 11:58
On crée une requête WQL d'événement, la classe Win32_PnPEntity concerne tous les éléments Plug and Play.
On indique un ensemble d'événement à l'aide de la classe d'événement "__InstanceOperationEvent" qui concerne la création,la modification et la suppression.
$query =New-object System.Management.WqlEventQuery(
"__InstanceOperationEvent",
[TimeSpan]"0:0:1",
'TargetInstance isa "Win32_PnPEntity"')SELECT * FROM __InstanceOperationEvent WITHIN 1
WHERE Targetinstance ISA 'Win32_PnPEntity
On crée un abonnement à des notifications d'événement temporaires :
$watcher =new-object System.Management.ManagementEventWatcher
$watcher.Query = $query
#Gestion d'événement synchrone
$evenement = $watcher.WaitForNextEvent()#Détermine le type d'événement
switch ($evenement.__Class)
{
#Une nouvelle instance de la classe recherchée a été créée
"__InstanceCreationEvent"
{Write-Warning ("Nouvel élément Plug and Play détecté."ÂÂ)
#On créé une instance de la classe
#référencée par la propriété TargetInstance
#Nécessaire si on souhaite retrouver ses associations
$I=[wmi]"$($evenement.TargetInstance.__relpath)"
}
#Une instance de la classe recherchée vient d'être supprimée
"__InstanceDeletionEvent" {
Write-Warning ("Un élément Plug and Play a été retiré."ÂÂ)
#L'instance référencée n'existe plus dans le référentiel, mais
#seulement comme copie dans la propriété TargetInstance.
#Difficile de retrouver les associations d'un objet inexistant...
$evenement.TargetInstance
}
default {Write-Warning "La classe d'événement __InstanceModificationEvent n'est pas gérée."}
} #Switch
#Libére les ressources
$Watcher.Dispose()
# Traitement nécessitant le device PnP
...$query =New-object System.Management.WqlEventQuery(
"__InstanceOperationEvent",
[TimeSpan]"0:0:1",
'(__CLASS="__InstanceCreationEvent" or
__CLASS="__InstanceDeletionEvent"ÂÂ) and
TargetInstance isa "Win32_PnPEntity"')#Win32_PnPEntity = tous les éléments PNP
#Service="USBSTOR"= de type USB Storage.
#Par exemple une clé USB
$query =New-object System.Management.WqlEventQuery(
"__InstanceOperationEvent",
[TimeSpan]"0:0:1",
'(__CLASS="__InstanceCreationEvent" or
__CLASS="__InstanceDeletionEvent"ÂÂ) and
TargetInstance isa "Win32_PnPEntity" and TargetInstance.Service="USBSTOR"')Par exemple surveiller les disques, plutôt qu'un élément PnP :
#disque
$query =New-object System.Management.WqlEventQuery(
"__InstanceOperationEvent",
[TimeSpan]"0:0:1",
'TargetInstance isa "Win32_DiskDrive"')$query =New-object System.Management.WqlEventQuery(
#On recherche les créations, modifications et suppressions d'instance
"__InstanceOperationEvent",
[TimeSpan]"0:0:1",
#On précise la classe recherchée, ici les disques USB
'TargetInstance isa "Win32_DiskDrive" and TargetInstance.InterfaceType="USB"')Les lecteurs réseaux créés par la commande Net Use sont aussi concernés :
# net use * \\HOSTNAME\C$
$query =New-object System.Management.WqlEventQuery(
"__InstanceOperationEvent",
[TimeSpan]"0:0:1",
'TargetInstance isa "Win32_LogicalDisk"')Une classe dassociation définit les relations entre deux classes.
Un disque posséde une ou plusieurs partitions et à chaque partition est attribué un nom de lecteur, on doit donc interroger les objet suivants :
Win32_DiskDrive->Win32_DiskPartition->Win32_LogicalDisk
#Une nouvelle instance de la classe Win32_DiskDrive a été créée
"__InstanceCreationEvent" {
Write-Warning ("Nouveau lecteur détecté"ÂÂ)
$I=[wmi]"$($evenement.TargetInstance.__relpath)"
#Recherche les associations de la classe
#Win32_DiskDrive à partir du disque détecté
#$Drives récupère les résultats d'un pipeline
$Drives=$I.psbase.GetRelationships()|
#on parcourt celles concernant les partitions du disque courant
where {$_.__class -eq "Win32_DiskDriveToDiskPartition"}|
#Pour chaque instance de type Win32_DiskDriveToDiskPartition
foreach {
#On créé une instance de Win32_DiskPartition,
#référencée par la propriété Dependent
#Sans cela on ne peut accéder à psbase.GetRelationships()
[wmi]"$($_.Dependent)"|
foreach {
#Recherche les associations de la
#classe Win32_DiskPartition à partir
#de la partition courante
$_.psbase.GetRelationships()|
#on parcourt celles concernant le
#disque logique de la partition courante
where {$_.__class -eq "Win32_LogicalDiskToPartition"}|
#Pour chaque instance de type Win32_LogicalDiskToPartition
foreach {
#On créé une instance de Win32_LogicalDisk,
#référencée par la propriété Dependent.
#On renvoie le nom d'unité qui lui a été attribuée
([wmi]"$($_.Dependent)"ÂÂ).DeviceID
}
}#Logical
}#Partition
Write-Warning ("`t unité : $drives"ÂÂ)
}#Event CreationEnfin la propriété Win32_PnPEntity.DeviceId peut servir à déterminer le type de device .<br><br>Message édité par: Laurent Dardenne, à: 18/06/09 11:58
Tutoriels PowerShell
Dernière édition: il y a 2 ans 9 mois par Laurent Dardenne. Raison: Correction balises
Connexion ou Créer un compte pour participer à la conversation.
Temps de génération de la page : 0.059 secondes
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Contributions à la communauté
- [WMI]Comment détecter l'insertion d'un disque USB?