Rakha
Rakha

Reputation: 2064

Powershell WMI trigger - action when specific device is plugged in

I want to trigger a script when a specific USB Device is plugged in, I've researched Register-WmiEvent but I'm really confused at how to approach it correctly.

So far I have successfully isolated the device as such :

Get-WmiObject win32_PNPEntity | where {$_.Caption -eq "Lexar USB Flash Drive USB Device"}

This is the WMI object returned :

_GENUS                     : 2
__CLASS                     : Win32_PnPEntity
__SUPERCLASS                : CIM_LogicalDevice
__DYNASTY                   : CIM_ManagedSystemElement
__RELPATH                   : Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_LEXAR&PROD_USB_FLASH_DRIVE&REV_1100\\AAEDZZ5RVJ47QS4K&0"
__PROPERTY_COUNT            : 26
__DERIVATION                : {CIM_LogicalDevice, CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER                    : P7409
__NAMESPACE                 : root\cimv2
__PATH                      : \\P7409\root\cimv2:Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_LEXAR&PROD_USB_FLASH_DRIVE&REV_1100\\AAEDZZ5RVJ47QS4K&0"
Availability                : 
Caption                     : Lexar USB Flash Drive USB Device
ClassGuid                   : {4d36e967-e325-11ce-bfc1-08002be10318}
CompatibleID                : {USBSTOR\Disk, USBSTOR\RAW, GenDisk}
ConfigManagerErrorCode      : 0
ConfigManagerUserConfig     : False
CreationClassName           : Win32_PnPEntity
Description                 : Lecteur de disque
DeviceID                    : USBSTOR\DISK&VEN_LEXAR&PROD_USB_FLASH_DRIVE&REV_1100\AAEDZZ5RVJ47QS4K&0
ErrorCleared                : 
ErrorDescription            : 
HardwareID                  : {USBSTOR\DiskLexar___USB_Flash_Drive_1100, USBSTOR\DiskLexar___USB_Flash_Drive_, USBSTOR\DiskLexar___, USBSTOR\Lexar___USB_Flash_Drive_1...}
InstallDate                 : 
LastErrorCode               : 
Manufacturer                : (Lecteurs de disque standard)
Name                        : Lexar USB Flash Drive USB Device
PNPClass                    : DiskDrive
PNPDeviceID                 : USBSTOR\DISK&VEN_LEXAR&PROD_USB_FLASH_DRIVE&REV_1100\AAEDZZ5RVJ47QS4K&0
PowerManagementCapabilities : 
PowerManagementSupported    : 
Present                     : True
Service                     : disk
Status                      : OK
StatusInfo                  : 
SystemCreationClassName     : Win32_ComputerSystem
SystemName                  : P7409
PSComputerName              : P7409

How should I approach the event part?

Is there a way to write it so it works like "When the instance containing that Caption exists...do this" ?

I'm trying :

$query = "Select * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'win32_PNPEntity'  and TargetInstance.Caption = 'Lexar USB Flash Drive USB Device'"

Register-WMIEvent -Query $query -Action { Write-Host "LEXAR FLASH DRIVE CONNECTED"} -SourceIdentifier TEST

But nothing happens when I plug/unplug it.

I experimented with:

$query = "SELECT * FROM win32_DeviceChangeEvent"
Register-WMIEvent -Query $query  -Action {Write-Host "ALERT"}

This work but it triggers when ANY device is connected/disconnected. I want to be able to isolate just that device with the Lexar caption.

Much appreciated.

Upvotes: 1

Views: 2165

Answers (1)

Rakha
Rakha

Reputation: 2064

There is a lot of documentation online about WMI events but nothing really clear for something like this so here is how I got it working, I'm sure it'll be useful for many others.

What you want to do is register an event when the instance of your device is CREATED and when it's DELETED. (in our case this is synonymous to PLUGGED IN and UNPLUGGED)

So you have to first find the ID of the instance that gets created when you plug in the device. Mine is:

Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_LEXAR&PROD_USB_FLASH_DRIVE&REV_1100\\AAEDZZ5RVJ47QS4K&0"

*That device ID was causing me trouble (I think because of all the sepcial characters in it) so I did a match with parts of the string instead of the whole thing, it works just as well.

Here is how to create the two events:

#Event when plugged in (InstanceCreationEvent)
$query = "Select * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'win32_PNPEntity' and TargetInstance.DeviceID like 'USBSTOR%LEXAR%AAEDZZ5RVJ47QS4K%'"
Register-WMIEvent -Query $query -Action { msg * lexar connected} -SourceIdentifier LexarConnect

#Event when disconnected (InstanceDeletionEvent)
$query = "Select * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA 'win32_PNPEntity' and TargetInstance.DeviceID like 'USBSTOR%LEXAR%AAEDZZ5RVJ47QS4K%'"
Register-WMIEvent -Query $query -Action { msg * lexar disconnected} -SourceIdentifier LexarDisconnect

Like I said above, the DeviceID was creating errors so I used parts of the string with the WQL wildcard character "%" (using : like USBSTOR%LEXAR%AAEDZZ5RVJ47QS4K% matches the good DeviceID without having to use the whole string)

WMI Events are powerful stuff! Enjoy!

Upvotes: 3

Related Questions