How to log "new pnp devices" events to console on Windows?

927 views Asked by At

I want to write something like nestat (that log new tcp connections to console) but for pnp devices with powershell.

Is there an API method "to subscribe to some kind of events bus" specific to PnP and get "connected" and "disconnected" events?

Or only one way to achive this is looping with Get-PnpDevice and "manually" seacrh for the differences?

1

There are 1 answers

2
boxdog On BEST ANSWER

You can use WMI events to do this. For example, here is one way to do it (seems over-complicated, so maybe someone can improve on it):

$addIdentifier = "WMI.PnpAddEvent"
$removeIdentifier = "WMI.PnpRemoveEvent"

$addAction = { $pnpEntity = $EventArgs.NewEvent.TargetInstance; Write-Host "`nPNPEvent: Plugged In`nCaption: $($pnpEntity.Caption)`nPNPDeviceID: $($pnpEntity.PNPDeviceID)`n" }
$addQuery = "SELECT * FROM __instancecreationevent WITHIN 5 WHERE targetinstance isa 'Win32_PnPEntity'"

$removeAction = { $pnpEntity = $EventArgs.NewEvent.TargetInstance; Write-Host "`nPNPEvent: Unplugged`nCaption: $($pnpEntity.Caption)`nPNPDeviceID: $($pnpEntity.PNPDeviceID)`n" }
$removeQuery = "SELECT * FROM __instancedeletionevent WITHIN 5 WHERE targetinstance isa 'Win32_PnPEntity'"

$addEventArgs = @{
    Query            = $addQuery
    SourceIdentifier = $addIdentifier
    SupportEvent     = $true
    Action           = $addAction
}

$removeEventArgs = @{
    Query            = $removeQuery
    SourceIdentifier = $removeIdentifier
    SupportEvent     = $true
    Action           = $removeAction
}

Register-WmiEvent @addEventArgs
Register-WmiEvent @removeEventArgs

Now, when you add/remove a device, you'll get output like this in the console:

PNPEvent: Unplugged
Caption: Apple iPhone
PNPDeviceID: USB\VID_05AC&PID_12A8&MI_00\E&2491F388&0&0000    

PNPEvent: Plugged In
Caption: Apple iPhone
PNPDeviceID: USB\VID_05AC&PID_12A8&MI_00\E&2491F388&0&0000

A couple of things to keep in mind:

  • The event registrations last for the current session only
  • You need to run this from an elevated prompt

As mentioned, the registrations should be cancelled when your session ends, but if you want to do it manually, you can do it like this:

$addIdentifier, $removeIdentifier | ForEach-Object { Unregister-Event -Force -SourceIdentifier $_ }