Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect mounting of a virtual (TrueCrypt) volume in windows PowerShell script

I am using the following windows powershell script to detect when a particular volume is mounted so I can run a script that will move files from my machine to the device (I don't know much about powershell scripts, I found this online).

#Requires -version 2.0
Register-WmiEvent -Class win32_VolumeChangeEvent -SourceIdentifier volumeChange
write-host (get-date -format s) "     Beginning script..."
do{
  $newEvent = Wait-Event -SourceIdentifier volumeChange
  $eventType = $newEvent.SourceEventArgs.NewEvent.EventType
  $eventTypeName = switch($eventType)
    {
    1 {"Configuration changed"}
    2 {"Device arrival"}
    3 {"Device removal"}
    4 {"docking"}
    }
  write-host (get-date -format s) "     Event detected = " $eventTypeName
  if ($eventType -eq 2)
  {
    $driveLetter = $newEvent.SourceEventArgs.NewEvent.DriveName
    $driveLabel = ([wmi]"Win32_LogicalDisk='$driveLetter'").VolumeName
    write-host (get-date -format s) "     Drive name = " $driveLetter
    write-host (get-date -format s) "     Drive label = " $driveLabel
    # Execute process if drive matches specified condition(s)
    if ($driveLetter -eq 'G:' -and $driveLabel -eq 'My Book')
    {
        write-host (get-date -format s) "     Starting task in 5 seconds..."
     start-sleep -seconds 5
        start-process "F:\copy_backups.bat"
    }
  }
  Remove-Event -SourceIdentifier volumeChange
} while (1-eq1) #Loop until next event
Unregister-Event -SourceIdentifier volumeChange

G is a physical external hdd and F is a truecrypt container within G. When the script detects the correct device is mounted as G, it sleeps 5 seconds to give truecrypt time to mount F, and then runs the script found on F. It appears that volume change events are only generated when the physical drive is connected/disconnected (at least that's the only time the script receives an event), because leaving G connected and mounting/dismounting F does not trigger the script.

I would like to be able to detect when the truecrypt container is mounted without anything else changing. At some level this must be possible, because windows explorer updates its drives display when the container is mounted or dismounted. I read up on the win32_VolumeChangeEvent, but I was unable to find anything about it in connection to virtual drives. Thanks for the help.

like image 323
Matthew Patey Avatar asked May 05 '13 17:05

Matthew Patey


1 Answers

I was surprised this has been up for a year and does not have an answer! For anyone that visits:

The Register_WMIEvent did not work for me at all. Instead, I have taken a different approach to monitor the drive event. Unfortunately the script is not foolproof, as it executes an action when ANY new drive is added. Feel free to add more conditions to it. I would suspect that Register_WMIEvent for win32_VolumeChangeEvent monitors only when a physical drive is changed, as per volume manager entries.

Here is the script which should allow you to perform any action you want. (Hint: Possibly mount your TC containers at high letter and make a function restricted to these only, so that the script will not fire when some lower-letter drive is connected such as pendrive)

$DrivesCount = (gwmi -Query "Select * from Win32_LogicalDisk").Count
$Drives = (gwmi -Query "Select * from Win32_LogicalDisk")

while(1) {
Start-Sleep -Seconds 5
    $DrivesCountNew = (gwmi -Query "Select * from Win32_LogicalDisk").Count
        if ($DrivesCount -ne $DrivesCountNew) 
          {
          $DrivesNew = (gwmi -Query "Select * from Win32_LogicalDisk")
          $DriveLetter = Compare-Object -ReferenceObject $Drives -DifferenceObject $DrivesNew | Select -ExpandProperty InputObject | Select -ExpandProperty DeviceId
          if (!($DriveLetter -eq $null)) { 
          Write-host "New drive mounted $DriveLetter"

          ##Place for you to do something with your drive
          }
          $DrivesCount = (gwmi -Query "Select * from Win32_LogicalDisk").Count 
          }
         }

As for quick comments around the script:

$DrivesCount takes the initial value of your drive list and $Drives lists all of them to variable. Afterwards, infinite loop starts, where it counts every 5 seconds if a new drive is mounted ($DrivesCountNew). If no change has been registered, no action is taken (the values are the same). If, however, a new drive appears, $DriveLetter variable checks by comparing the difference and returns the sole letter of the drive (by using ExpandProperty couple of times.

Following that, a check against $DriveLetter is done since the script WILL fire if the drive is removed (and we don't want any action to happen in this place). Of course the script will execute any scriptblock afterwards, so it would be wise to limit the execution by adding some condition (like: if ($DriveLetter -eq "Z:") { }) Then, at the end of successful execution, it overwrites the $DrivesCount variable once again (to prevent the script from repeating the action as old variable would still hold place).

Well, sorry that you didn't have that response in timely manner - yet I hope someone will find the script useful. (And at least I learned a little more about WMI objects).

like image 99
AlexPawlak Avatar answered Nov 11 '22 20:11

AlexPawlak